233
/* Prepend pseudoheader to the udp datagram and calculate checksum */
234
int udp_checksum(void *pheader, void *udata, int psize, int dsize)
236
unsigned int tsize = psize + dsize;
237
char csumpacket[tsize];
238
memset(csumpacket, (unsigned char) abs(bitpattern), abs(tsize));
240
struct UDPv4PHeader *prepend = (struct UDPv4PHeader *) csumpacket;
241
struct UDPv4PHeader *udppheader = (struct UDPv4PHeader *) pheader;
242
prepend->saddr = udppheader->saddr;
243
prepend->daddr = udppheader->daddr;
245
prepend->protocol = udppheader->protocol;
246
prepend->len = udppheader->len;
248
struct UDPHeader *content = (struct UDPHeader *)(csumpacket + psize);
249
struct UDPHeader *udpdata = (struct UDPHeader *) udata;
250
content->srcport = udpdata->srcport;
251
content->dstport = udpdata->dstport;
252
content->length = udpdata->length;
253
content->checksum = udpdata->checksum;
255
return checksum(csumpacket,tsize);
209
259
int new_sequence(int index)
211
static int next_sequence = 0;
261
static int next_sequence = MinSequence;
214
264
seq = next_sequence++;
215
265
if (next_sequence >= MaxSequence)
266
next_sequence = MinSequence;
218
268
sequence[seq].index = index;
219
269
sequence[seq].transit = 1;
236
286
/*ok char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader)];*/
237
287
char packet[MAXPACKET];
238
288
struct IPHeader *ip = (struct IPHeader *) packet;
239
struct ICMPHeader *icmp;
289
struct ICMPHeader *icmp = NULL;
290
struct UDPHeader *udp = NULL;
291
struct UDPv4PHeader *udpp = NULL;
241
294
/*ok int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + datasize;*/
243
296
static int first=1;
244
int ttl, iphsize = 0, echotype = 0, salen = 0;
297
int ttl, iphsize = 0, echotype = 0, salen = 0, udphsize = 0;
301
/* offset for ipv6 checksum calculation */
248
304
if ( packetsize < MINPACKET ) packetsize = MINPACKET;
249
305
if ( packetsize > MAXPACKET ) packetsize = MAXPACKET;
298
icmp = (struct ICMPHeader *)(packet + iphsize);
299
icmp->type = echotype;
303
icmp->sequence = new_sequence(index);
304
icmp->checksum = checksum(icmp, abs(packetsize) - iphsize);
356
icmp = (struct ICMPHeader *)(packet + iphsize);
357
icmp->type = echotype;
361
icmp->sequence = new_sequence(index);
362
icmp->checksum = checksum(icmp, abs(packetsize) - iphsize);
364
gettimeofday(&sequence[icmp->sequence].time, NULL);
368
udp = (struct UDPHeader *)(packet + iphsize);
369
udphsize = sizeof (struct UDPHeader);
371
mypid = (uint16)getpid();
375
udp->srcport = htons(mypid);
376
udp->length = abs(packetsize) - iphsize;
378
udp->length = htons(udp->length);
380
udp->dstport = new_sequence(index);
381
gettimeofday(&sequence[udp->dstport].time, NULL);
382
udp->dstport = htons(udp->dstport);
390
/* checksum is not mandatory. only calculate if we know ip->saddr */
392
udpp = (struct UDPv4PHeader *)(malloc(sizeof(struct UDPv4PHeader)));
393
udpp->saddr = ip->saddr;
394
udpp->daddr = ip->daddr;
395
udpp->protocol = ip->protocol;
396
udpp->len = udp->length;
397
udp->checksum = udp_checksum(udpp, udp, sizeof(struct UDPv4PHeader), abs(packetsize) - iphsize);
308
402
ip->check = checksum(packet, abs(packetsize));
408
/* kernel checksum calculation */
409
if ( setsockopt(sendsock, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)) ) {
410
perror( "setsockopt IPV6_CHECKSUM" );
312
gettimeofday(&sequence[icmp->sequence].time, NULL);
314
419
rv = sendto(sendsock, packet, abs(packetsize), 0,
315
420
remotesockaddr, salen);
316
421
if (first && (rv < 0) && ((errno == EINVAL) || (errno == EMSGSIZE))) {
450
555
socklen_t fromsockaddrsize;
452
557
struct ICMPHeader *header = NULL;
558
struct UDPHeader *udpheader = NULL;
453
559
struct timeval now;
454
560
ip_t * fromaddress = NULL;
455
int echoreplytype = 0, timeexceededtype = 0;
561
int echoreplytype = 0, timeexceededtype = 0, unreachabletype = 0;
457
564
gettimeofday(&now, NULL);
493
if (header->type == echoreplytype) {
494
if(header->id != (uint16)getpid())
497
net_process_ping (header->sequence, (void *) fromaddress, now);
498
} else if (header->type == timeexceededtype) {
502
if ((size_t) num < sizeof(struct IPHeader) +
503
sizeof(struct ICMPHeader) +
504
sizeof (struct IPHeader) +
505
sizeof (struct ICMPHeader))
507
header = (struct ICMPHeader *)(packet + sizeof (struct IPHeader) +
508
sizeof (struct ICMPHeader) +
509
sizeof (struct IPHeader));
513
if ( num < sizeof (struct ICMPHeader) +
514
sizeof (struct ip6_hdr) + sizeof (struct ICMPHeader) )
516
header = (struct ICMPHeader *) ( packet +
517
sizeof (struct ICMPHeader) +
518
sizeof (struct ip6_hdr) );
523
if (header->id != (uint16)getpid())
526
net_process_ping(header->sequence, (void *)fromaddress, now);
605
if (header->type == echoreplytype) {
606
if(header->id != (uint16)getpid())
609
sequence = header->sequence;
610
} else if (header->type == timeexceededtype) {
614
if ((size_t) num < sizeof(struct IPHeader) +
615
sizeof(struct ICMPHeader) +
616
sizeof (struct IPHeader) +
617
sizeof (struct ICMPHeader))
619
header = (struct ICMPHeader *)(packet + sizeof (struct IPHeader) +
620
sizeof (struct ICMPHeader) +
621
sizeof (struct IPHeader));
625
if ( num < sizeof (struct ICMPHeader) +
626
sizeof (struct ip6_hdr) + sizeof (struct ICMPHeader) )
628
header = (struct ICMPHeader *) ( packet +
629
sizeof (struct ICMPHeader) +
630
sizeof (struct ip6_hdr) );
635
if (header->id != (uint16)getpid())
638
sequence = header->sequence;
643
if (header->type == timeexceededtype || header->type == unreachabletype) {
647
if ((size_t) num < sizeof(struct IPHeader) +
648
sizeof(struct ICMPHeader) +
649
sizeof (struct IPHeader) +
650
sizeof (struct UDPHeader))
652
udpheader = (struct UDPHeader *)(packet + sizeof (struct IPHeader) +
653
sizeof (struct ICMPHeader) +
654
sizeof (struct IPHeader));
658
if ( num < sizeof (struct ICMPHeader) +
659
sizeof (struct ip6_hdr) + sizeof (struct UDPHeader) )
661
udpheader = (struct UDPHeader *) ( packet +
662
sizeof (struct ICMPHeader) +
663
sizeof (struct ip6_hdr) );
667
sequence = ntohs(udpheader->dstport);
673
net_process_ping(sequence, (void *)fromaddress, now);
901
static void set_fd_flags(int fd)
903
#if defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
906
oldflags = fcntl(fd, F_GETFD);
907
if (oldflags == -1) {
908
perror("Couldn't get fd's flags");
911
if (fcntl(fd, F_SETFD, oldflags | FD_CLOEXEC))
912
perror("Couldn't set fd's flags");
756
916
int net_preopen(void)
760
920
#if !defined(IP_HDRINCL) && defined(IP_TOS) && defined(IP_TTL)
761
sendsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
921
sendsock4_icmp = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
922
sendsock4_udp = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
763
924
sendsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
765
926
if (sendsock4 < 0)
767
928
#ifdef ENABLE_IPV6
768
sendsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
929
sendsock6_icmp = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
930
sendsock6_udp = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP);
771
933
#ifdef IP_HDRINCL
780
942
recvsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
781
943
if (recvsock4 < 0)
945
set_fd_flags(recvsock4);
783
946
#ifdef ENABLE_IPV6
784
947
recvsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
949
set_fd_flags(recvsock6);
955
int net_selectsocket(void)
957
#if !defined(IP_HDRINCL) && defined(IP_TOS) && defined(IP_TTL)
960
sendsock4 = sendsock4_icmp;
963
sendsock4 = sendsock4_udp;
972
sendsock6 = sendsock6_icmp;
975
sendsock6 = sendsock6_udp;
978
if ((sendsock6 < 0) && (sendsock4 < 0))
791
986
int net_open(struct hostent * host)
793
988
#ifdef ENABLE_IPV6