1145519Sdarrenr/* $FreeBSD$ */ 2145510Sdarrenr 322514Sdarrenr/* 453024Sguido * (C)opyright 1992-1998 Darren Reed. (from tcplog) 522514Sdarrenr * 680486Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 722514Sdarrenr * 822514Sdarrenr */ 922514Sdarrenr 1022514Sdarrenr#include <stdio.h> 1122514Sdarrenr#include <netdb.h> 1222514Sdarrenr#include <ctype.h> 1322514Sdarrenr#include <signal.h> 1422514Sdarrenr#include <errno.h> 1522514Sdarrenr#include <sys/types.h> 1622514Sdarrenr#include <sys/time.h> 1722514Sdarrenr#include <sys/timeb.h> 1822514Sdarrenr#include <sys/socket.h> 1922514Sdarrenr#include <sys/file.h> 2022514Sdarrenr#include <sys/ioctl.h> 2122514Sdarrenr#include <net/nit.h> 2222514Sdarrenr#include <sys/fcntlcom.h> 2322514Sdarrenr#include <sys/dir.h> 2422514Sdarrenr#include <net/nit_if.h> 2522514Sdarrenr#include <net/nit_pf.h> 2622514Sdarrenr#include <net/nit_buf.h> 2722514Sdarrenr#include <net/packetfilt.h> 2822514Sdarrenr#include <sys/stropts.h> 2922514Sdarrenr 3022514Sdarrenr#include <net/if.h> 3122514Sdarrenr#include <netinet/in.h> 3222514Sdarrenr#include <netinet/in_systm.h> 3322514Sdarrenr#include <netinet/ip.h> 3422514Sdarrenr#include <netinet/if_ether.h> 3522514Sdarrenr#include <netinet/ip_var.h> 3622514Sdarrenr#include <netinet/udp.h> 3722514Sdarrenr#include <netinet/udp_var.h> 3822514Sdarrenr#include <netinet/tcp.h> 3922514Sdarrenr#include <netinet/tcpip.h> 4022514Sdarrenr 4122514Sdarrenr#ifndef lint 4222514Sdarrenrstatic char snitid[] = "@(#)snit.c 1.2 12/3/95 (C)1995 Darren Reed"; 4322514Sdarrenr#endif 4422514Sdarrenr 4522514Sdarrenr#define BUFSPACE 32768 4622514Sdarrenr 4722514Sdarrenr/* 4822514Sdarrenr * Be careful to only include those defined in the flags option for the 4922514Sdarrenr * interface are included in the header size. 5022514Sdarrenr */ 5122514Sdarrenr#define BUFHDR_SIZE (sizeof(struct nit_bufhdr)) 5222514Sdarrenr#define NIT_HDRSIZE (BUFHDR_SIZE) 5322514Sdarrenr 5422514Sdarrenrstatic int timeout; 5522514Sdarrenr 5622514Sdarrenr 5722514Sdarrenrint ack_recv(ep) 58255332Scy char *ep; 5922514Sdarrenr{ 6022514Sdarrenr struct tcpiphdr tip; 6122514Sdarrenr struct tcphdr *tcp; 6222514Sdarrenr struct ip *ip; 6322514Sdarrenr 6422514Sdarrenr ip = (struct ip *)&tip; 6522514Sdarrenr tcp = (struct tcphdr *)(ip + 1); 6622514Sdarrenr bcopy(ep + 14, (char *)ip, sizeof(*ip)); 6722514Sdarrenr bcopy(ep + 14 + (ip->ip_hl << 2), (char *)tcp, sizeof(*tcp)); 6822514Sdarrenr if (ip->ip_off & 0x1fff != 0) 6922514Sdarrenr return 0; 7022514Sdarrenr if (0 == detect(ip, tcp)) 7122514Sdarrenr return 1; 7222514Sdarrenr return 0; 7322514Sdarrenr} 7422514Sdarrenr 7522514Sdarrenr 7622514Sdarrenrint readloop(fd, dst) 77255332Scy int fd; 78255332Scy struct in_addr dst; 7922514Sdarrenr{ 8022514Sdarrenr static u_char buf[BUFSPACE]; 8122514Sdarrenr register u_char *bp, *cp, *bufend; 8222514Sdarrenr register struct nit_bufhdr *hp; 8322514Sdarrenr register int cc; 8422514Sdarrenr time_t now = time(NULL); 8522514Sdarrenr int done = 0; 8622514Sdarrenr 8722514Sdarrenr while ((cc = read(fd, buf, BUFSPACE-1)) >= 0) { 8822514Sdarrenr if (!cc) 8922514Sdarrenr if ((time(NULL) - now) > timeout) 9022514Sdarrenr return done; 9122514Sdarrenr else 9222514Sdarrenr continue; 9322514Sdarrenr bp = buf; 9422514Sdarrenr bufend = buf + cc; 9522514Sdarrenr /* 9622514Sdarrenr * loop through each snapshot in the chunk 9722514Sdarrenr */ 9822514Sdarrenr while (bp < bufend) { 9922514Sdarrenr cp = (u_char *)((char *)bp + NIT_HDRSIZE); 10022514Sdarrenr /* 10122514Sdarrenr * get past NIT buffer 10222514Sdarrenr */ 10322514Sdarrenr hp = (struct nit_bufhdr *)bp; 10422514Sdarrenr /* 10522514Sdarrenr * next snapshot 10622514Sdarrenr */ 10722514Sdarrenr bp += hp->nhb_totlen; 10822514Sdarrenr done += ack_recv(cp); 10922514Sdarrenr } 11022514Sdarrenr return done; 11122514Sdarrenr } 11222514Sdarrenr perror("read"); 11322514Sdarrenr exit(-1); 11422514Sdarrenr} 11522514Sdarrenr 11622514Sdarrenrint initdevice(device, tout) 117255332Scy char *device; 118255332Scy int tout; 11922514Sdarrenr{ 12022514Sdarrenr struct strioctl si; 12122514Sdarrenr struct timeval to; 12222514Sdarrenr struct ifreq ifr; 12322514Sdarrenr struct packetfilt pfil; 12422514Sdarrenr u_long if_flags; 12522514Sdarrenr u_short *fwp = pfil.Pf_Filter; 12622514Sdarrenr int ret, offset, fd, snaplen= 76, chunksize = BUFSPACE; 12722514Sdarrenr 12822514Sdarrenr if ((fd = open("/dev/nit", O_RDWR)) < 0) 12922514Sdarrenr { 13022514Sdarrenr perror("/dev/nit"); 13122514Sdarrenr exit(-1); 13222514Sdarrenr } 13322514Sdarrenr 13422514Sdarrenr /* 13522514Sdarrenr * Create some filter rules for our TCP watcher. We only want ethernet 13622514Sdarrenr * pacets which are IP protocol and only the TCP packets from IP. 13722514Sdarrenr */ 13822514Sdarrenr offset = 6; 13922514Sdarrenr *fwp++ = ENF_PUSHWORD + offset; 14022514Sdarrenr *fwp++ = ENF_PUSHLIT | ENF_CAND; 14122514Sdarrenr *fwp++ = htons(ETHERTYPE_IP); 14222514Sdarrenr *fwp++ = ENF_PUSHWORD + sizeof(struct ether_header)/sizeof(short)+4; 14322514Sdarrenr *fwp++ = ENF_PUSHLIT | ENF_AND; 14422514Sdarrenr *fwp++ = htons(0x00ff); 14522514Sdarrenr *fwp++ = ENF_PUSHLIT | ENF_COR; 14622514Sdarrenr *fwp++ = htons(IPPROTO_TCP); 14722514Sdarrenr *fwp++ = ENF_PUSHWORD + sizeof(struct ether_header)/sizeof(short)+4; 14822514Sdarrenr *fwp++ = ENF_PUSHLIT | ENF_AND; 14922514Sdarrenr *fwp++ = htons(0x00ff); 15022514Sdarrenr *fwp++ = ENF_PUSHLIT | ENF_CAND; 15122514Sdarrenr *fwp++ = htons(IPPROTO_UDP); 15222514Sdarrenr pfil.Pf_FilterLen = fwp - &pfil.Pf_Filter[0]; 15322514Sdarrenr /* 15422514Sdarrenr * put filter in place. 15522514Sdarrenr */ 15622514Sdarrenr if (ioctl(fd, I_PUSH, "pf") == -1) 15722514Sdarrenr { 15822514Sdarrenr perror("ioctl: I_PUSH pf"); 15922514Sdarrenr exit(1); 16022514Sdarrenr } 16122514Sdarrenr if (ioctl(fd, NIOCSETF, &pfil) == -1) 16222514Sdarrenr { 16322514Sdarrenr perror("ioctl: NIOCSETF"); 16422514Sdarrenr exit(1); 16522514Sdarrenr } 16622514Sdarrenr /* 16722514Sdarrenr * arrange to get messages from the NIT STREAM and use NIT_BUF option 16822514Sdarrenr */ 16922514Sdarrenr ioctl(fd, I_SRDOPT, (char*)RMSGD); 17022514Sdarrenr ioctl(fd, I_PUSH, "nbuf"); 17122514Sdarrenr /* 17222514Sdarrenr * set the timeout 17322514Sdarrenr */ 17422514Sdarrenr timeout = tout; 17522514Sdarrenr si.ic_timout = 1; 17622514Sdarrenr to.tv_sec = 1; 17722514Sdarrenr to.tv_usec = 0; 17822514Sdarrenr si.ic_cmd = NIOCSTIME; 17922514Sdarrenr si.ic_len = sizeof(to); 18022514Sdarrenr si.ic_dp = (char*)&to; 18122514Sdarrenr if (ioctl(fd, I_STR, (char*)&si) == -1) 18222514Sdarrenr { 18322514Sdarrenr perror("ioctl: NIT timeout"); 18422514Sdarrenr exit(-1); 18522514Sdarrenr } 18622514Sdarrenr /* 18722514Sdarrenr * set the chunksize 18822514Sdarrenr */ 18922514Sdarrenr si.ic_cmd = NIOCSCHUNK; 19022514Sdarrenr si.ic_len = sizeof(chunksize); 19122514Sdarrenr si.ic_dp = (char*)&chunksize; 19222514Sdarrenr if (ioctl(fd, I_STR, (char*)&si) == -1) 19322514Sdarrenr perror("ioctl: NIT chunksize"); 19422514Sdarrenr if (ioctl(fd, NIOCGCHUNK, (char*)&chunksize) == -1) 19522514Sdarrenr { 19622514Sdarrenr perror("ioctl: NIT chunksize"); 19722514Sdarrenr exit(-1); 19822514Sdarrenr } 19922514Sdarrenr printf("NIT buffer size: %d\n", chunksize); 20022514Sdarrenr 20122514Sdarrenr /* 20222514Sdarrenr * request the interface 20322514Sdarrenr */ 20422514Sdarrenr strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 20522514Sdarrenr ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' '; 20622514Sdarrenr si.ic_cmd = NIOCBIND; 20722514Sdarrenr si.ic_len = sizeof(ifr); 20822514Sdarrenr si.ic_dp = (char*)𝔦 20922514Sdarrenr if (ioctl(fd, I_STR, (char*)&si) == -1) 21022514Sdarrenr { 21122514Sdarrenr perror(ifr.ifr_name); 21222514Sdarrenr exit(1); 21322514Sdarrenr } 21422514Sdarrenr 21522514Sdarrenr /* 21622514Sdarrenr * set the snapshot length 21722514Sdarrenr */ 21822514Sdarrenr si.ic_cmd = NIOCSSNAP; 21922514Sdarrenr si.ic_len = sizeof(snaplen); 22022514Sdarrenr si.ic_dp = (char*)&snaplen; 22122514Sdarrenr if (ioctl(fd, I_STR, (char*)&si) == -1) 22222514Sdarrenr { 22322514Sdarrenr perror("ioctl: NIT snaplen"); 22422514Sdarrenr exit(1); 22522514Sdarrenr } 22622514Sdarrenr (void) ioctl(fd, I_FLUSH, (char*)FLUSHR); 22722514Sdarrenr return fd; 22822514Sdarrenr} 229