#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef _SOLARIS_ #include "solaris.h" #else #include #endif #include #include #include #include #include #include #ifdef _BPF_ #include #include #endif #ifndef DLT_RAW #define DLT_RAW 12 #endif #ifndef DLT_SLIP_BSDOS #define DLT_SLIP_BSDOS 13 #endif #ifndef DLT_PPP_BSDOS #define DLT_PPP_BSDOS 14 #endif #include "ip.h" unsigned short ip_in_cksum(struct iphdr *iph, unsigned short *ptr, int nbytes) { register long sum = 0; /* assumes long == 32 bits */ u_short oddbyte; register u_short answer; /* assumes u_short == 16 bits */ int pheader_len; unsigned short *pheader_ptr; struct pseudo_header { unsigned long saddr; unsigned long daddr; unsigned char null; unsigned char proto; unsigned short tlen; } pheader; pheader.saddr = iph->saddr; pheader.daddr = iph->daddr; pheader.null = 0; pheader.proto = iph->protocol; pheader.tlen = htons(nbytes); pheader_ptr = (unsigned short *)&pheader; for (pheader_len = sizeof(pheader); pheader_len; pheader_len -= 2) { sum += *pheader_ptr++; } while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } if (nbytes == 1) { /* mop up an odd byte, if necessary */ oddbyte = 0; /* make sure top half is zero */ *((u_char *) & oddbyte) = *(u_char *) ptr; /* one byte only */ sum += oddbyte; } sum += (sum >> 16); /* add carry */ answer = ~sum; /* ones-complement, then truncate to 16 bits */ return (answer); } unsigned short in_cksum(unsigned short *ptr, int nbytes) { register long sum=0; /* assumes long == 32 bits */ u_short oddbyte; register u_short answer; /* assumes u_short == 16 bits */ while(nbytes>1){ sum+=*ptr++; nbytes-=2; } if(nbytes==1){ /* mop up an odd byte, if necessary */ oddbyte=0; /* make sure top half is zero */ *((u_char *)&oddbyte)=*(u_char *)ptr; /* one byte only */ sum+=oddbyte; } sum+=(sum>>16); /* add carry */ answer=~sum; /* ones-complement, then truncate to 16 bits */ return(answer); } int rawsock(void) { int fd,val=1; if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { croak("(rawsock) socket problems [fatal]"); } if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val, sizeof(val)) < 0) { croak("Cannot set IP_HDRINCL socket option"); } return fd; } u_long host_to_ip (char *host_name) { struct hostent *target; u_long *resolved_ip; resolved_ip = (u_long *) malloc (sizeof (u_long)); if ((target = gethostbyname (host_name)) == NULL) { croak("host_to_ip: failed"); } else { bcopy (target->h_addr, resolved_ip, sizeof (struct in_addr)); return ntohl ((u_long) * resolved_ip); } } void pkt_send (int fd, unsigned char * sock,u_char *pkt,int size) { if (sendto (fd, (const void *)pkt,size, 0, (const struct sockaddr *) sock, sizeof (struct sockaddr)) < 0) { close (fd); croak("sendto()"); } } int linkoffset(int type) { switch (type) { case DLT_EN10MB: return 14; case DLT_SLIP: return 16; case DLT_SLIP_BSDOS: return 24; case DLT_NULL: return 4; case DLT_PPP: return 4; case DLT_PPP_BSDOS: return 24; case DLT_FDDI: return 21; case DLT_IEEE802: return 22; case DLT_ATM_RFC1483: return 8; case DLT_RAW: return 0; } } #ifdef _BPF_ int bpf_open(void) { int fd; int n = 0; char device[sizeof "/dev/bpf000"]; do { (void)sprintf(device, "/dev/bpf%d", n++); fd = open(device, O_WRONLY); } while (fd < 0 && errno == EBUSY); if (fd < 0) printf("%s: %s", device, pcap_strerror(errno)); return (fd); } #endif