Raw Sockets Fehlermeldung
-
hi,
ich habe ein Programm in Visual C++ 2008 geschrieben das UDP über RawSockets versendet.
Das Programm soll UDP Pakete direkt senden ohne vorher einen ARP Request zu machen wie es sonst bei der "normalen" Socketprogrammierung üblich ist.
Um die einzelnen Pakete zu sniffen verwende ich Wireshark.
Ich bekomme immer die WSAGetLastFehlermeldung: 10038
Ich vermute das der Socket nicht richtig initialisiert wurde. Es kann aber auch sein das es auf meinem Windows XP SP3 einfach nicht läuft (Hab gehört das es da Einschränkungen gibt).
Ich weiß nicht genau was ich bei der setsockopt angeben soll. IP_HDRINCL findet er nicht!
Über jede hilfreiche Antwort freue ich mich

Gruß profcoder
Hier der Code:
#include "stdafx.h" #include <windows.h> //#include <winsock2.h> #include <stdlib.h> #include <iostream> //Wird benötigt! #pragma comment( lib, "ws2_32.lib" ) /* Der IP Header: -------------- | Byte 0 | Byte 1 | Byte 2 | Byte 3 | 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct IP_HEADER { unsigned int h_len:4; // Länge des Headers unsigned int version:4; // IP Version unsigned char tos; // Type of service unsigned short total_len; // Gesamt länge des Pakets unsigned short ident; // unique identifier unsigned short frag_and_flags; // flags unsigned char ttl; // TTL unsigned char proto; // Protokoll (TCP, UDP etc) unsigned short checksum; // IP Checksumme unsigned int sourceIP; // Source IP unsigned int destIP; // Ziel IP }; // The UDP header structure // typedef struct _udphdr { unsigned short sport; // Source Port unsigned short dport; // Destination Port unsigned short Length; // Length unsigned short Checksum; // Checksum }UdpHeader, * LPUdpHeader; struct UDP_HEADER { unsigned short sport; // Source Port unsigned short dport; // Destination Port unsigned short Length; // Length unsigned short Checksum; // Checksum }; typedef struct _PSHeader { unsigned long srcaddr; unsigned long destaddr; unsigned char zero; unsigned char protocol; unsigned short len; }PSHeader; long WinsockStartup(); int main(int argc, char** argv) { IP_HEADER *iphdr; UDP_HEADER *udphdr, udpHdr; PSHeader pseudo_header; SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP); SOCKADDR_IN sock_addr; int iUdpSize, error; long rc; unsigned char sendBuf[2048]; memset(sendBuf,0,2048); char RecvTimeout=1000; unsigned char data[32]; memset(data,0,20); // unsigned char rspace[32]; WSADATA wsa_data; //Winsock initialisieren rc = WinsockStartup(); if (rc == SOCKET_ERROR) { std::cout << "Error: WinsockStartup failed: " << WSAGetLastError(); return SOCKET_ERROR; } //------- Hier weiß ich nicht wie ich die setsockopt einstellen soll! IP_HDRINCL findet er nicht! ------------- // rc = setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&RecvTimeout, sizeof(RecvTimeout)); //char on = 1; //setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)); //--------------------------------------------------------------------------------------------------------------- //iphdr auf den Puffer zeigen lassen iphdr = (IP_HEADER *) sendBuf; // the ip header now points to the top of the sendBuf udphdr= (UDP_HEADER *) (sendBuf + sizeof(IP_HEADER)); // the udp header points to the part next to the ip header sock_addr.sin_family = AF_INET; sock_addr.sin_port = htons (1526); sock_addr.sin_addr.s_addr = inet_addr("192.168.0.22"); //IP Header initialisieren iphdr->version = 4; iphdr->h_len = 5; iphdr->tos = 0; iphdr->total_len = sizeof (IP_HEADER) + sizeof (UDP_HEADER) + sizeof (data); iphdr->ident = 1; iphdr->frag_and_flags = 0; iphdr->ttl = 255; iphdr->proto = IPPROTO_UDP; //UDP iphdr->checksum = 0; iphdr->sourceIP = inet_addr ("192.168.0.1"); // your source ip iphdr->destIP = sock_addr.sin_addr.s_addr; // Initalize the UDP header // iUdpSize = sizeof(udpHdr) + strlen((char*)data); udphdr->sport = htons(13371) ; udphdr->dport = htons(13371) ; udphdr->Length = htons(iUdpSize) ; udphdr->Checksum = 0 ; //calculate UDP CheckSum pseudo_header.destaddr = inet_addr("192.168.0.22"); pseudo_header.srcaddr = inet_addr("192.168.0.1"); pseudo_header.zero = 0; pseudo_header.protocol = 17; pseudo_header.len = sizeof(data) + sizeof(udphdr); //Gebe den Inhalt des Sendepuffers aus for(int i=0;i<40;i++) printf("%x",sendBuf[i]); //Sende den Inhalt des Puffers (Das Paket) error = sendto(sock,(char*)sendBuf,40,0,(LPSOCKADDR)&sock_addr,sizeof(SOCKADDR_IN)); //Bei Fehler gebe Fehlermeldung aus if(error == SOCKET_ERROR) { std::cout << "\nError: "; std::cout << WSAGetLastError(); } else std::cout << "sent"; //Warte 3Sekunden, dann fahre fort Sleep(3000); //Programmende return 0; } long WinsockStartup() { long rc; WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 1); rc = WSAStartup( wVersionRequested, &wsaData ); return rc; }
-
Ich würde erstmal WinsockStartup() VOR socket() aufrufen...
-
Danke xD
Das war der Fehler. Oh man xD
Hm jetzt läuft das Programm. Aber wenn ich mit Wireshark sniffe, dann schickt er immernoch zuerst ein ARP Whois Requests raus. Er soll aber sofort ein UDP Paket senden.
Weißt du wie ich das hinbekomm?
-
Ist klar wenn du sendto() benutzt!
-
und ausserdem muss er ja ein arp req. machen wen er den gw nicht kennt.. und dieses req. wird vom kernel initiert.
-
Ja das will ich ja vermeiden das er ein Request macht. Er soll einfach das was ich ihm gebe direkt rausschicken ohne irgendwelche Standardabläufe durchzugehen. Also direkt auf unterster Ebene.
Kennst du einen anderen Befehl als sendto? Ich hab nichts gefunden...
Hm wenn das der Kernel macht. Ist das dann überhaupt möglich? Auf Umwegen evtl.?
-
lowbyte_ schrieb:
und ausserdem muss er ja ein arp req. machen wen er den gw nicht kennt..
"gw"? Und warum muss er, ist doch nichts zu resolven. Versteh ich nich.
-
Wären die bisherigen Poster so nett noch ne Antwort auf die an sie zuletzt gerichteten Fragen zu stellen? Würde mich auch interessieren.
Danke