SOS! HELP! Есть программа работающая с raw сокетом.
В CBuilder(5-я версия) в ней была такая ошибка: при юзании флага IP_HDRINCL в setsockopt функция sendto давала ошибку 10022(не помню что это, да и неважно). Без этого флага всё работало, но блин заголовок-то уже не тот
В лепешку разбился, как исправить - непонятно...Ну ладно, нашел в инете другую программу, слегка поправил - в том же Билдере не работает!!! Ошибка WSAEADDRNOTAVAIL, хотя это бред полный - адреса в норме, заголовки пакетов тоже. Что самое интересное, ТОТ ЖЕ КОД откомпиленный в Visual C++ 6 РАБОТАЕТ ПРЕКРАСНО! ПОМОГИТЕ! Не знаю уже что делать...на Visual C++ перенести свою исходную программу не могу - придется всю визуальную часть переписывать, а время поджимает.
Система Win2000 Server Service pack 3, winsock version 2.2, код программы см. далее(IP-адрес в bind'е исправьте ессно на свой локальный, иначе не заработает...):
main.cpp
#include "head.h"
#include "check.cpp"
#include <conio.h>
#define PORT 80
int main(void)
{
WSADATA wsd;
char *datagram="";
int bOpt = 1;
char info[30] ="das ist ein test";
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("WSAStartup() failed: %d\n", GetLastError());
return -1;
}
// Create a raw socket
SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (s == INVALID_SOCKET)
{
printf("WSASocket() failed: %d\n", WSAGetLastError());
return -1;
}
struct ipheader *iph = (struct ipheader *) malloc(sizeof(struct
ipheader));
struct tcpheader *tcph = (struct tcpheader *) malloc( sizeof
(struct tcpheader));
struct body *bo = (struct body *) malloc( sizeof (struct body));
struct ps_hdr *ps = (struct ps_hdr *) malloc( sizeof (struct
ps_hdr));
datagram = (char *) malloc(sizeof(struct ipheader) + sizeof(struct
tcpheader)+sizeof (struct body));
struct sockaddr_in sin;
iph= (struct ipheader *) datagram;
tcph=(struct tcpheader *) (datagram+ sizeof(struct ipheader));
bo= (struct body *) (datagram+sizeof(struct ipheader)+ sizeof(struct
tcpheader));
memset(bo->data,'\0',sizeof(body));
sin.sin_family = AF_INET;
sin.sin_port = htons (PORT);
sin.sin_addr.s_addr = inet_addr ("213.180.216.200");
//printf("%i\n",sizeof(datagram));
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = sizeof (struct ipheader) + sizeof (struct
tcpheader)+sizeof(struct body);
iph->ip_id = 1;
iph->ip_off = 0;
iph->ip_ttl = 255;
iph->ip_p = 6;
iph->ip_sum = 0;
iph->ip_src = inet_addr ("213.180.216.200");
iph->ip_dst = sin.sin_addr.s_addr;
tcph->th_sport = htons (PORT);
tcph->th_dport = htons (PORT);
tcph->th_seq = rand();
tcph->th_ack = htons (6234);
tcph->th_x2 = 0;
tcph->th_off = 5;
tcph->th_flags = 16; // SYN
tcph->th_win = htons(65535);
tcph->th_sum = 0;
tcph->th_urp = 0;
// Build the Psuedo Header
ps->source_address = inet_addr ("213.180.216.200");
ps->dest_address = sin.sin_addr.s_addr;
ps->placeholder = 0;
ps->protocol = IPPROTO_TCP;
ps->tcp_length = htons(sizeof(struct tcpheader)+sizeof(struct
body));
ps->tcp = *tcph;
ps->data=*bo;
strcpy((char *)bo->data,info);
// Calculate Checksum
tcph->th_sum = checksum((unsigned short *)ps, sizeof(struct
ps_hdr));
iph->ip_sum = checksum((unsigned short *)iph, sizeof(struct
ipheader));
// ENABLE IPHDRINCL
sockaddr_in sii;
int sin_len=sizeof(sii);
memset(&sii, 0, sin_len);
sii.sin_family = AF_INET;
sii.sin_port = htons(1080);
sii.sin_addr.s_addr = inet_addr ("62.33.238.3");
if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt,
sizeof(bOpt)) == SOCKET_ERROR)
{
printf("setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
return -1;
}
if (bind(s, (const sockaddr *)&sii, sin_len) == SOCKET_ERROR)
{
printf("bind failed: %d\n", WSAGetLastError());
return -1;
}
// Send The Packet
char *target=inet_ntoa(sin.sin_addr);
char buf[16];
memcpy(buf, target, 16);
if (sendto(s, datagram, iph->ip_len, 0, (SOCKADDR *)&sin,
sizeof(sin)) == SOCKET_ERROR)
{
printf("sendto() failed: %d\n", WSAGetLastError());
return -1;
}
getch();
return 0;
}
check.cpp
unsigned short checksum(unsigned short *addr, int len)
{
register int sum = 0;
u_short answer = 0;
register u_short *w = addr;
register int nleft = len;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we
add
* sequential 16 bit words to it, and at the end, fold back all
the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff);/* add hi 16 to low 16 */
sum += (sum >> 16);/* add carry */
answer = ~sum;/* truncate to 16 bits */
return (answer);
}
head.h
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
unsigned short checksum(unsigned short *addr, int len);
struct tcpheader {
unsigned short int th_sport;
unsigned short int th_dport;
unsigned int th_seq;
unsigned int th_ack;
unsigned char th_x2:4, th_off:4;
unsigned char th_flags;
unsigned short int th_win;
unsigned short int th_sum;
unsigned short int th_urp;
}; /* total tcp header length: 20 bytes (=160 bits) */
struct ipheader {
unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4
bits */
unsigned char ip_tos;
unsigned short int ip_len;
unsigned short int ip_id;
unsigned short int ip_off;
unsigned char ip_ttl;
unsigned char ip_p;
unsigned short int ip_sum;
unsigned int ip_src;
unsigned int ip_dst;
}; /* total ip header length: 20 bytes (=160 bits) */
// Psuedo Header
struct body
{
unsigned char data [40];
};
struct ps_hdr
{
unsigned int source_address; // Source Address => 4 Bytes
unsigned int dest_address; // Destination Address => 4 Bytes
unsigned char placeholder; // Place Holder => 1 Bytes
unsigned char protocol; // Protocol => 1 Bytes
unsigned short tcp_length; // TCP Length => + 2 Bytes
struct tcpheader tcp;
struct body data;
};