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 184 185 186 187 188 189 190 191 192 193
|
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef _SOLARIS_
#include "solaris.h"
#else
#include <sys/cdefs.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pcap.h>
#ifdef _BPF_
#include <errno.h>
#include <fcntl.h>
#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;
u_long host_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));
host_resolved_ip = ntohl ((u_long) * resolved_ip);
free(resolved_ip);
return host_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
|