Prüfsumme eines IP-Headers errechnen C++

souljumper

Neues Mitglied
Thread Starter
Registriert
15.10.2008
Beiträge
26
hi,

ich experementiere etwas mit raw-Sockets herum und möchte ein IP-Paket via UDP verschicken. Nun ist aber scheinbar mein errechneter IP-Header murcks, ein Monitoringprogramm sagt mir das der Header 0x000 ist (also nicht gesetzt?). Nun weis ich nicht ob ih falsch rechne und die methode fehlerhaft ist oder ob ich vorher was falsch mache.

hier mal mein code:

meine structur(en)
Code:
 unsigned int headersize = sizeof(struct ip) + sizeof(struct udphdr);
 unsigned int payload = 512;
 unsigned int packetsize = headersize + payload;
 unsigned char packet[packetsize]; 
 memset(packet,0,packetsize);

Code:
/* Systemmitteilen das ich den Header selbst berechne */
 int on=1;
 if (setsockopt(rs, IPPROTO_IP, IP_HDRINCL, (const char* )&on, sizeof(on)) < 0 )
 {
   perror("IP_HDRINCL failed!\n");
   exit(1);
 }

Header zusammen setzen
Code:
 /* IP Header zusammenbauen */
  struct ip *iph        = (struct ip*) packet;
 iph->ip_v 		       	= 4; //IPv4
 iph->ip_hl		    	= 5;
 iph->ip_tos           	= 0x0;
 iph->ip_len		  	= sizeof(struct ip) + sizeof(struct udphdr);
 iph->ip_ttl        	= 100;
 iph->ip_p		 		= IPPROTO_UDP;
 iph->ip_src.s_addr 	= inet_addr(SRC_ADR);
 iph->ip_dst.s_addr 	= inet_addr(DST_ADR);
 iph->ip_id 			= htons(random());
 iph->ip_sum 			= ip_sum_calc(iph->ip_hl, (unsigned short*) &iph);

Methode zur Prüfsummenberechnung
Code:
//typedef unsigned short u16;
//typedef unsigned long u32;

u16 ip_sum_calc(u16 len_ip_header, u16 buff[])
{
  u16 word16;
  u32 sum=0;
  u16 i;
              
  for (i=0;i<len_ip_header;i=i+2)
  {
    word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
    sum = sum + (u32) word16;	
  }
	
  //Nimmt von der 32-Bit Summe nur die ersten 16 Bit
  while (sum>>16)
  {
    sum = (sum & 0xFFFF)+(sum >> 16);
  }
  
  sum = ~sum;     //Einerkomplement des Ergebnis
	
  return ((u16) sum);
}

hab jetzt schon mehrere ip-header prüfsummen funktionen gegoogelt, wobei manche gleiche ergebnise liefern und andere wiederherum abweichen.

Ich hab jetzt schon vil rumprobiert, aber ich krieg eifnach nicht raus was falsch ist...

Kann mir wer helfen ?
 

souljumper

Neues Mitglied
Thread Starter
Registriert
15.10.2008
Beiträge
26
ich muss ja zuerst die ip prüfsumme ermitteln, die ght ja nur über den ipheader. die udp prüfsumme kommt dann später dran.

oder kann ich mit der udp-prüfsumme auch den ipheader berechnen?
 

oneOeight

Aktives Mitglied
Registriert
23.11.2004
Beiträge
59.987
nee, der UDP header nimmt ja nur teile des IP headers für den eigenen pseudo header...
 

souljumper

Neues Mitglied
Thread Starter
Registriert
15.10.2008
Beiträge
26
was mich halt etws verdutzt ist, dass wenn ih den ip header berechne (egal ob jetzt falsch oder richtig) und ich das paket mit wireshark abhöre (hab derzeit kein receive programm) steht als IP-header 0x0000 (also 0 = nicht berechnet?)

er scheint den wert also gar nicht gesetzt zu haben? die restlichen von ir gesetzten header-informationen wurden aber angenommen....
 

oneOeight

Aktives Mitglied
Registriert
23.11.2004
Beiträge
59.987
dann setz doch mal einen breakpoint und guck, ob der wert richtig gesetzt wird...
 

souljumper

Neues Mitglied
Thread Starter
Registriert
15.10.2008
Beiträge
26
also der Wert wird zugewiesen....

mal eine andere frage, was passiert mit paketen di eine falsche prüfsumme haben? werden die verworfen oder trotzdem gesendet ?

muss ich prüfsummenwerte eigentlich als netzwork-byteorder setzen oder einfach als normalen zahlenwert ?
 

souljumper

Neues Mitglied
Thread Starter
Registriert
15.10.2008
Beiträge
26
interessante kehrtwende.

hab jetzt festgestellt das sich den selbe code unter os-x und gentoo mit gcc compilieren kann, aber die ausführung andere ergebnisse liefert!

hab jetzt mal einen älteren sourcecodestand verwendet und unter Linux versendet das packet und kommt wohl auch an. Unter os-x führt es zu "Invalid-Arguments", der von der sendto() - Methode erzeugt wird.

jemand eine idee woran das liegen kann?

wenn die kompilierung funktioniert wäre ich jetzt davon ausgegangen das auch die ausführung zu vergleichbaren ergebnis führt. sind di sockets von os-x soo anders?
 
Oben Unten