Sockets: Message too long
-
hi,
ich schicke ein Paket via Raw-Socket durchs Netz, wenn ich aber eine Paketgröße nehme die mehr als 1500 Byte umfasst schlägt der sendto()-Befehl fehl(Message too long).
Nun entsinne ich mich, dass dies was mit der MTU zu tun haben kann?! Jemand eine Idee warum die automatische Fragementierung nicht greift? Oder was könnte sonst noch die ursache für diese Fehlermeldung sein?
Ich arbeite auf einem Suse-System....
-
sose schrieb:
Jemand eine Idee warum die automatische Fragementierung nicht greift?
Evtl. weil Du RAW-Sockets verwendest?!
-
oje,
also muss ich die komplette Fragmentierung selber machen :o ?
Kann ich rigendwie die MTU erfragen ?
-
Also das glaube ich nicht. Das geniale an IP ist ja das Schichtenmodel, die Kapselung und daß man sich um die darunter liegende Schicht nicht kümmern muss.
Man kann die MTU mit ioctl erfragen. Genauer mit dem Flag SIOCGIFMTU.
Aber soviel ich weiß kann nur ein mit root-Rechten versehener Prozess RAW-Sockets aufrufen. Man muss mit setsockopt genau definieren was diese Verbindung machen soll. Es gibt ja nicht mal Ports auf dieser Ebene.
Deshalb solltest Du uns einfach mal Deinen Code zeigen.Gruss Christian
-
Also mein konreter Code sieht so aus, erhöhe ich die Größe der Payload auf z.b. 25000 entsteht der "Message too long" fehler.
#define __USE_LINUX #include <unistd.h> #include <stdlib.h> #include <sys/socket.h> #include <arpa/inet.h> #define __FAVOR_BSD #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/udp.h> #include <netdb.h> #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char **argv) { int uid = geteuid(); if ( uid != 0) { printf("You must be root to do this ! Current Id: %i\n", uid); exit(1); } unsigned int headersize = sizeof(struct ip) + sizeof(struct udphdr); unsigned int payload = 96; unsigned int packetsize = headersize + payload; unsigned char packet[packetsize]; memset(packet,0,packetsize); int rawsock=0; if ((rawsock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0) { perror("socket() - failed"); exit(1); } /* Eigenen IP-Header verwenden, Kernel-Header unterdrücken */ int on=1; if (setsockopt(rawsock, IPPROTO_IP, IP_HDRINCL, (const char* )&on, sizeof(on)) < 0 ) { perror("IP_HDRINCL failed!\n"); exit(1); } struct sockaddr_in sin; memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_addr.s_addr = inet_addr("192.168.2.102"); sin.sin_port = htons(2010); sin.sin_family = AF_INET; /* IP Header*/ struct ip *iph = (struct ip*) packet; iph->ip_v = 4; iph->ip_hl = 5; iph->ip_tos = 0x0; iph->ip_len = packetsize; iph->ip_ttl = 100; iph->ip_sum = 0; iph->ip_p = IPPROTO_UDP; iph->ip_src.s_addr = sin.sin_addr.s_addr; iph->ip_dst.s_addr = inet_addr("192.168.2.101"); iph->ip_id = htons(random()); /* UDP Header */ struct udphdr *udp = (struct udphdr *) (packet + sizeof(struct ip)); udp->uh_sport = htons(55555); udp->uh_dport = htons(2010); udp->uh_ulen = htons(packetsize - sizeof(struct ip)); udp->uh_sum = 0; char text[] = "Hallo Netzwerk"; memcpy(&packet[headersize],text,sizeof(text)); printf("\nCalculated Header Checksum: %i\n", iph->ip_sum); if (sendto(rawsock, packet, packetsize, 0, (struct sockaddr*) &sin, sizeof(sin)) < 0 ) perror("sendto() failed"); close(rawsock); return 0; }