| 1 | recv_buff = new IPHeader + 1024; |
haha, ja dat is het ookquote:Op dinsdag 18 juni 2013 20:17 schreef thabit het volgende:
[ code verwijderd ]
Lijkt me nogal een vreemd stukje code. Wat wil je hier precies mee doen?
En ook een memory leak, want je delete the IPHeader niet.quote:Op dinsdag 18 juni 2013 23:03 schreef netolk het volgende:
[..]
haha, ja dat is het ook
maar dat is zodat de buffer groot genoeg is omdat de ping request toevallig 1024 byte is (dat kan idd veel netter)
bedankt maar dat word ergens aan het einde van het programma gedaanquote:
En wat doet je code dan precies? Deadlock?quote:Op dinsdag 18 juni 2013 19:22 schreef netolk het volgende:
hey, ik zit met een probleempje
Ik ben bezig om data via icmp te versturen (zoals ping ect.)
nu is het zo dat ik via het programmaatje dat ik gemaakt heb wel data kan versturen alleen niet kan ontvangen (wireshark ziet wel een ping reply terug komen).
nu is dit mijn ontvang code:
[ code verwijderd ]
[ code verwijderd ]
Ik weet dat het dus aan dit stukje code moet liggen aangezien wireshark wel een ping reply vind op een request dat ik gemaakt heb
Weet iemand waarom het programmaatje dat pakketje niet onderschept?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | // include ook de lib (D:\IDE\MinGW\lib\libws2_32.a) #include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #include <string> /* ICMP codes */ #define ICMP_ECHO_REPLY 0 #define ICMP_DEST_UNREACH 3 #define ICMP_TTL_EXPIRE 11 #define ICMP_ECHO_REQUEST 8 class Error{ }; struct icmp{ unsigned char _TYPE; unsigned char _CODE; unsigned short _CHECKSUM; }; // The IP header struct IPHeader { char h_len:4; // Length of the header in dwords char version:4; // Version of IP char tos; // Type of service unsigned short total_len; // Length of the packet in dwords unsigned short ident; // unique identifier unsigned short flags; // Flags char ttl; // Time to live char proto; // Protocol number (TCP, UDP etc) unsigned short checksum; // IP checksum unsigned long source_ip; unsigned long dest_ip; }; // ICMP header struct ICMPHeader { char type; // ICMP packet type char code; // Type sub code unsigned short checksum; unsigned short id; unsigned short seq; unsigned long timestamp; // not part of ICMP, but we need it }; unsigned short ip_checksum(unsigned short* buffer, int size){ unsigned long cksum = 0; // Sum all the words together, adding the final byte if size is odd while (size > 1) { cksum += *buffer++; size -= sizeof(unsigned short); } if (size) { cksum += *(unsigned char*)buffer; } // Do a little shuffling cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); // Return the bitwise complement of the resulting mishmash return (unsigned short)(~cksum); } unsigned long FindHostIP(const char *pServerName){ std::cout << "Looking up host... "; HOSTENT *pHostent; // Get hostent structure for hostname: if(!(pHostent = gethostbyname(pServerName))){ std::cout << "Failed!\n"; throw Error(); } // Extract primary IP address from hostent structure: if(pHostent->h_addr_list && pHostent->h_addr_list[0]){ std::cout << "Done.\n"; return *reinterpret_cast<unsigned long*>(pHostent->h_addr_list[0]); } return 0; } int main(int argc, char* argv[]){ WSADATA wsaData; unsigned long IP = 0; ICMPHeader *send_buff = 0; IPHeader *recv_buff = 0; if(argc == 1){ std::cout << argv[0] << " [IP adres]\n"; return 0; } std::cout << "inizializing... "; if(WSAStartup(MAKEWORD(2,0),&wsaData)==0){ if(LOBYTE(wsaData.wVersion) >= 2){ std::cout << "Done.\n"; /* hier moet de ICMP verbinding gemaakt worden */ SOCKET hSocket = INVALID_SOCKET; try{ std::cout << "Creating socket... "; if((hSocket = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) == INVALID_SOCKET){ std::cout << "Failed!\n"; throw Error(); } std::cout << "Done.\n"; sockaddr_in sockAddr; sockAddr.sin_family = AF_INET; sockAddr.sin_addr.S_un.S_addr = FindHostIP(argv[1]); std::cout << "Connecting... "; if(connect(hSocket,reinterpret_cast<sockaddr*>(&sockAddr),sizeof(sockAddr))!= 0){ std::cout << "Failed!\n"; throw Error(); } std::cout << "Done.\n"; send_buff = new ICMPHeader; send_buff->type = ICMP_ECHO_REQUEST; send_buff->code = 0; send_buff->checksum = 0; // als 0 dan genereerd zelf send_buff->id = (unsigned short)GetCurrentProcessId(); send_buff->seq = 1; // thread nr??? send_buff->timestamp = GetTickCount(); send_buff->checksum = ip_checksum((unsigned short*)send_buff,1024+sizeof(ICMPHeader)); std::cout << "Sending... "; if(send(hSocket,(char*)send_buff,1024+sizeof(ICMPHeader),0) == SOCKET_ERROR){ std::cout << "Failed!\n"; throw Error(); } std::cout << "Done.\n"; std::cout << "Receiving... "; recv_buff = new IPHeader + 1024; char buff[1024+sizeof(IPHeader)]; int i = recv(hSocket,buff,1024+sizeof(IPHeader),0); if(i == 0) std::cout << "Connection closed\n"; else if(i == SOCKET_ERROR){ std::cout << "Failed!\n"; if(WSAGetLastError() == WSAEMSGSIZE) std::cout << "Buffer is too small!\n"; throw Error(); } else{ std::cout << "Done.\n"; std::cout << '\n'; for(int j = 0; j < i; j++){ //std::cout << tempbuff[j]; } std::cout << "\n-------------\n"; } } catch(Error){ } delete send_buff; delete recv_buff; } else std::cout << "Failed!\n"; std::cout << "Cleaning up winsock... "; if(WSACleanup()!=0) std::cout << "Failed!\n"; else std::cout << "Done.\n"; } else std::cout << "Failed!\n"; return 0; } |
De buffer die gereserveerd wordt is gewoon sizeof(IPHeader) bytes in dat stukje code. Het enige wat + 1024 doet, is 1024*sizeof(IPHeader) (en niet 1024) bytes bij de pointer optellen optellen. Lijkt me dus iets wat in alle opzichten fout is.quote:Op dinsdag 18 juni 2013 23:03 schreef netolk het volgende:
[..]
haha, ja dat is het ook
maar dat is zodat de buffer groot genoeg is omdat de ping request toevallig 1024 byte is (dat kan idd veel netter)
hij komt bij het block recv aan alleen vervolgens blijft hij daar "wachten" en doet dan dus niks meerquote:Op woensdag 19 juni 2013 01:43 schreef trancethrust het volgende:
Het probleem is meer dat we geen glazen bol hebben. Een recv blockt totdat hij wat ontvangt. Als je programma niet vastloopt, heeft hij dus wel wat ontvangen; de vraag is dan wat. Als het programma wel vastloopt dan komt het bericht nooit bij de recv aan en is er compleet wat anders aan de hand.
ow, dat is idd niet de bedoeling (normaal doe ik het wel eens met een char maar gezien dat die 1 byte is klopt dat sowieso... hoe kan ik hem dan de grote van 1024 bytes + de sizeof(IPHeader) geven? is new char + (1024+sizeof(IPHeader)) daar de enige optie voor? Vind ik er namelijk niet netjes uitzienquote:Op woensdag 19 juni 2013 08:54 schreef thabit het volgende:
[..]
De buffer die gereserveerd wordt is gewoon sizeof(IPHeader) bytes in dat stukje code. Het enige wat + 1024 doet, is 1024*sizeof(IPHeader) (en niet 1024) bytes bij de pointer optellen optellen. Lijkt me dus iets wat in alle opzichten fout is.
Dat is een deadlock. Die message komt dus nooit aan bij de recv. Ervanuitgaande dat er geen bug zit in die code, moet je echt in de hoek zoeken van een firewall die ICMP/jouw applicatie blokkeert, of het luisteren op de verkeerde poort. Controleren of de socket open is alvorens de recv aan te roepen is ook handig.quote:Op woensdag 19 juni 2013 10:27 schreef netolk het volgende:
[..]
hij komt bij het block recv aan alleen vervolgens blijft hij daar "wachten" en doet dan dus niks meer
Precies.quote:[..]
ow, dat is idd niet de bedoeling (normaal doe ik het wel eens met een char maar gezien dat die 1 byte is klopt dat sowieso... hoe kan ik hem dan de grote van 1024 bytes + de sizeof(IPHeader) geven? is new char + (1024+sizeof(IPHeader)) daar de enige optie voor? Vind ik er namelijk niet netjes uitzien
EDIT: zie net dat die recv_buff toch niet gebruikt word.
zucht haat aan code die ik niet zelf geschreven heb
hmm, ICMP heeft geen poort maar dat terzijde.quote:Op woensdag 19 juni 2013 10:32 schreef trancethrust het volgende:
[..]
Dat is een deadlock. Die message komt dus nooit aan bij de recv. Ervanuitgaande dat er geen bug zit in die code, moet je echt in de hoek zoeken van een firewall die ICMP/jouw applicatie blokkeert, of het luisteren op de verkeerde poort. Controleren of de socket open is alvorens de recv aan te roepen is ook handig.
[..]
Precies.
Bovendien maak je hier een denkfout; als iets van de grootte 1024+sizeof(IPHeader) is, dan is het geen IPHeader meer. Je `new char' notatie maakt bovendien precies dezelfde fout; hij alloceert 4 bytes en sprint dan 1024+x bytes ernaast.quote:Op woensdag 19 juni 2013 10:27 schreef netolk het volgende:
[..]
ow, dat is idd niet de bedoeling (normaal doe ik het wel eens met een char maar gezien dat die 1 byte is klopt dat sowieso... hoe kan ik hem dan de grote van 1024 bytes + de sizeof(IPHeader) geven? is new char + (1024+sizeof(IPHeader)) daar de enige optie voor? Vind ik er namelijk niet netjes uitzien
..
OKquote:Op woensdag 19 juni 2013 10:34 schreef netolk het volgende:
[..]
hmm, ICMP heeft geen poort maar dat terzijde.
Volgens mij het gedrag van recv ongedefineerd wanneer het een ongeldige socket wordt gevoerd.quote:Zal idd even een check er voor gooien die checkt of de socket nog wel open is (maar zou recv niet gewoon 0 moeten returnen als de socket niet meer open is?)
[..]
goed punt.quote:Op woensdag 19 juni 2013 10:37 schreef trancethrust het volgende:
[..]
Bovendien maak je hier een denkfout; als iets van de grootte 1024+sizeof(IPHeader) is, dan is het geen IPHeader meer. Je `new char' notatie maakt bovendien precies dezelfde fout; hij alloceert 4 bytes en sprint dan 1024+x bytes ernaast.
Wat je wilt is new char[ 1024+sizeof(IPHeader) ] maar dit is totaal geen C++ meer. Beter maak je een klasse gebaseerd op IPHeader die als eerste veld iets van 1024 heeft, en alloceer je dat gevaarte. Let wel dat het me nog steeds compleet onduidelijk is wat de bedoeling is van die 1024 bytes.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | std::cout << "Receiving... "; int result = 0; fd_set socks; struct timeval t; /* Set socket listening descriptors */ FD_ZERO(&socks); FD_SET(hSocket, &socks); if((result = select(hSocket + 1, &socks, 0, 0, &t)) < 0){ std::cout << "Failed!.\nCould not select socket.\n"; throw Error(); } else if(result > 0){ char recv_buff[4048]; sockaddr_in dst; int dst_addr_len = sizeof(dst); //int Received_bytes = recv(hSocket, (char*)recv_buff,sizeof(recv_buff),0); int Received_bytes = recv(hSocket, recv_buff, sizeof(recv_buff), 0); std::cout << "\nReceived bytes: " << Received_bytes << ".\n";// temp } else std::cout << "Failed!\nPacket not received.\n"; |
die timeout is op 5 sec gezet dat klopt want daarna stopt het programma.quote:Op woensdag 19 juni 2013 12:14 schreef trancethrust het volgende:
Moet je je timeout niet zetten? Stel dat de compiler t initialiseert als 0, dan wordt select een poll ipv een wait-to-get-ready.
Wat gebeurt overigens eerst? Een program exit of het binnenkomen van die reply?
Dus je socket is na 5 seconden nog steeds niet klaar voor ontvangst zoals gedetecteerd door gebruik van select, metgevolg dat je dat detectiemechanisme eruit haalt? Is het niet logischer te onderzoeken waarom je socket nooit klaar is om uitgelezen te worden?quote:Op woensdag 19 juni 2013 13:24 schreef netolk het volgende:
[..]
die timeout is op 5 sec gezet dat klopt want daarna stopt het programma.
Ondertussen die select er weer uitgesloopt aangezien het niet werkte en volgens mij overbodig is.
overigens ping ik naar de router en heb ik bijna meteen (lees 1ms) een ping reply terug alleen onderschept mijn programma dat niet
Het programma blijft namelijk tot in den treuren wachten op een pakketje
Dat is dus het punt ik kan niks raars vinden waardoor het niet zou moeten werken. Had ooit een http request programma gemaakt en daar werkte de boel wel gewoon (zonder select)quote:Op woensdag 19 juni 2013 13:58 schreef trancethrust het volgende:
[..]
Dus je socket is na 5 seconden nog steeds niet klaar voor ontvangst zoals gedetecteerd door gebruik van select, metgevolg dat je dat detectiemechanisme eruit haalt? Is het niet logischer te onderzoeken waarom je socket nooit klaar is om uitgelezen te worden?
Tijdens debuggen moet je de fout proberen te isoleren; select helpt door te detecteren dat het probleem bij de socket zit. Ik zou daaruit verder gaan met isoleren; ligt het aan een firewall / heeft je programma wel rechten om een socket te openen? Is je socket-initialisatie code wel OK?quote:Op woensdag 19 juni 2013 14:08 schreef netolk het volgende:
[..]
Dat is dus het punt ik kan niks raars vinden waardoor het niet zou moeten werken. Had ooit een http request programma gemaakt en daar werkte de boel wel gewoon (zonder select)
Ja, ik ken het principe wel.quote:Op woensdag 19 juni 2013 14:13 schreef trancethrust het volgende:
[..]
Tijdens debuggen moet je de fout proberen te isoleren; select helpt door te detecteren dat het probleem bij de socket zit. Ik zou daaruit verder gaan met isoleren; ligt het aan een firewall / heeft je programma wel rechten om een socket te openen? Is je socket-initialisatie code wel OK?
Bedenk oorzaken en vind methodes om te controleren of je hypothese klopt of niet. Zo ja, zoek verder in die richting, zo nee, vind een nieuwe hypothese. Dat is zo'n beetje de debug-cyclus en ja, dat kan vervelend zijn.
Is ICMP synchroon? Ik denk dan meer aan TCP ofzo. Misschien is select helemaal niet van toepassing?quote:The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.
Ligt de sleutel dan in het gebruiken van recvfrom ipv recv?quote:Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using sendto and recvfrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer using send and can be received only from this peer using recv.
Ja, zat ook al te denken dat het recvfrom moet zijn dat is nu ook wat ik gebruik maar tot nu toe nog steeds het zelfde probleemquote:Op woensdag 19 juni 2013 15:46 schreef trancethrust het volgende:
M.i. moet het iets basaals zijn als functies als select en recv misgaan.
[..]
Is ICMP synchroon? Ik denk dan meer aan TCP ofzo. Misschien is select helemaal niet van toepassing?
[..]
Ligt de sleutel dan in het gebruiken van recvfrom ipv recv?
SPOILEROm spoilers te kunnen lezen moet je zijn ingelogd. Je moet je daarvoor eerst gratis Registreren. Ook kun je spoilers niet lezen als je een ban hebt.Ik vraag me nu alleen af of ik bij de recvfrom functie de buffer grote niet via een sizeof() kan doen ipv. de 1500 die er nu staat (want ja dat ga je natuurlijk geheid vergeten als je de buffer grote aanpast)Beware of the Raping Zebra's
| 1 2 3 | struct receive_buffer { char buffer[ 1500 ]; }; |
| Forum Opties | |
|---|---|
| Forumhop: | |
| Hop naar: | |