diff options
author | darrenr <darrenr@FreeBSD.org> | 1997-02-09 22:50:16 +0000 |
---|---|---|
committer | darrenr <darrenr@FreeBSD.org> | 1997-02-09 22:50:16 +0000 |
commit | cb8d46a179f2d30ac1cd0a01eb156e1a4c08d717 (patch) | |
tree | 93c7db298b1fd70f9e27663b3fd527da063d0008 /contrib/ipfilter/ipsd | |
download | FreeBSD-src-cb8d46a179f2d30ac1cd0a01eb156e1a4c08d717.zip FreeBSD-src-cb8d46a179f2d30ac1cd0a01eb156e1a4c08d717.tar.gz |
Import IP Filter v3.1.7 into FreeBSD tree
Diffstat (limited to 'contrib/ipfilter/ipsd')
-rw-r--r-- | contrib/ipfilter/ipsd/Makefile | 63 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/README | 32 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/ip_compat.h | 201 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/ipsd.c | 297 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/ipsd.h | 30 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/ipsdr.c | 315 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/linux.h | 17 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/sbpf.c | 195 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/sdlpi.c | 263 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/slinux.c | 120 | ||||
-rw-r--r-- | contrib/ipfilter/ipsd/snit.c | 230 |
11 files changed, 1763 insertions, 0 deletions
diff --git a/contrib/ipfilter/ipsd/Makefile b/contrib/ipfilter/ipsd/Makefile new file mode 100644 index 0000000..eb1986e --- /dev/null +++ b/contrib/ipfilter/ipsd/Makefile @@ -0,0 +1,63 @@ +# +# (C)opyright 1993-1996 by Darren Reed. +# +# This code may be freely distributed as long as it retains this notice +# and is not changed in any way. The author accepts no responsibility +# for the use of this software. I hate legaleese, don't you ? +# +OBJS=ipsd.o +BINDEST=/usr/local/bin +SBINDEST=/sbin +MANDIR=/usr/share/man +BPF=sbpf.o +NIT=snit.o +SUNOS4= +BSD= +LINUX=slinux.o +SUNOS5=dlcommon.o sdlpi.o + +CC=gcc +CFLAGS=-g -I.. + +all: + @echo "Use one of these targets:" + @echo " sunos4-nit (standard SunOS 4.1.x)" + @echo " sunos4-bpf (SunOS4.1.x with BPF in the kernel)" + @echo " bsd-bpf (4.4BSD variant with BPF in the kernel)" + @echo " linux (Linux kernels)" + @echo " sunos5 (Solaris 2.x)" + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +ipsdr: ipsdr.o + $(CC) ipsdr.o -o $@ $(LIBS) + +bpf sunos4-bpf : + make ipsd "OBJS=$(OBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \ + "CFLAGS=$(CFLAGS)" + +nit sunos4 sunos4-nit : + make ipsd "OBJS=$(OBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \ + "CFLAGS=$(CFLAGS)" + +sunos5 : + make ipsd "OBJS=$(OBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \ + CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl" + +bsd-bpf : + make ipsd "OBJS=$(OBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \ + "CFLAGS=$(CFLAGS)" + +linux : + make ipsd "OBJS=$(OBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \ + CFLAGS="$(CFLAGS) -I /usr/src/linux" + +ipsd: $(OBJS) $(UNIXOBJS) + $(CC) $(OBJS) $(UNIXOBJS) -o $@ $(LIBS) + +../ipft_sn.o ../ipft_pc.o: + (cd ..; make $(@:../%=%)) + +clean: + rm -rf *.o core a.out ipsd ipsdr diff --git a/contrib/ipfilter/ipsd/README b/contrib/ipfilter/ipsd/README new file mode 100644 index 0000000..6746d01 --- /dev/null +++ b/contrib/ipfilter/ipsd/README @@ -0,0 +1,32 @@ + +IP Scan Detetor. +---------------- + +This program is designed to be a passive listener for TCP packets sent to +the host. It does not exercise the promiscous mode of interfaces. For +routing Unix boxes (and firewalls which route/proxy) this is sufficient to +detect all packets going to/through them. + +Upon compiling, a predefined set of "sensitive" ports are configured into +the program. Any TCP packets which are seen sent to these ports are counted +and the IP# of the sending host recorded, along with the time of the first +packet to that port for that IP#. + +After a given number of "hits", it will write the current table of packets +out to disk. This number defaults to 10,000. + +To analyze the information written to disk, a sample program called "ipsdr" +is used (should but doesn't implement a tree algorithm for storing data) +which reads all log files it recognises and totals up the number of ports +each host hit. By default, all ports have the same weighting (1). Another +group of passes is then made over this table using a netmask of 0xfffffffe, +grouping all results which fall under the same resulting IP#. This netmask +is then shrunk back to 0, with a output for each level given. This is aimed +at detecting port scans done from different hosts on the same subnet (although +I've not seen this done, if one was trying to do it obscurely...) + +Lastly, being passive means that no action is taken to stop port scans being +done or discourage them. + +Darren +darrenr@cyber.com.au diff --git a/contrib/ipfilter/ipsd/ip_compat.h b/contrib/ipfilter/ipsd/ip_compat.h new file mode 100644 index 0000000..a911fd8 --- /dev/null +++ b/contrib/ipfilter/ipsd/ip_compat.h @@ -0,0 +1,201 @@ +/* + * (C)opyright 1995 by Darren Reed. + * + * This code may be freely distributed as long as it retains this notice + * and is not changed in any way. The author accepts no responsibility + * for the use of this software. I hate legaleese, don't you ? + * + * @(#)ip_compat.h 1.1 9/14/95 + */ + +/* + * These #ifdef's are here mainly for linux, but who knows, they may + * not be in other places or maybe one day linux will grow up and some + * of these will turn up there too. + */ +#ifndef ICMP_UNREACH +# define ICMP_UNREACH ICMP_DEST_UNREACH +#endif +#ifndef ICMP_SOURCEQUENCH +# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH +#endif +#ifndef ICMP_TIMXCEED +# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED +#endif +#ifndef ICMP_PARAMPROB +# define ICMP_PARAMPROB ICMP_PARAMETERPROB +#endif +#ifndef IPVERSION +# define IPVERSION 4 +#endif +#ifndef IPOPT_MINOFF +# define IPOPT_MINOFF 4 +#endif +#ifndef IPOPT_COPIED +# define IPOPT_COPIED(x) ((x)&0x80) +#endif +#ifndef IPOPT_EOL +# define IPOPT_EOL 0 +#endif +#ifndef IPOPT_NOP +# define IPOPT_NOP 1 +#endif +#ifndef IP_MF +# define IP_MF ((u_short)0x2000) +#endif +#ifndef ETHERTYPE_IP +# define ETHERTYPE_IP ((u_short)0x0800) +#endif +#ifndef TH_FIN +# define TH_FIN 0x01 +#endif +#ifndef TH_SYN +# define TH_SYN 0x02 +#endif +#ifndef TH_RST +# define TH_RST 0x04 +#endif +#ifndef TH_PUSH +# define TH_PUSH 0x08 +#endif +#ifndef TH_ACK +# define TH_ACK 0x10 +#endif +#ifndef TH_URG +# define TH_URG 0x20 +#endif +#ifndef IPOPT_EOL +# define IPOPT_EOL 0 +#endif +#ifndef IPOPT_NOP +# define IPOPT_NOP 1 +#endif +#ifndef IPOPT_RR +# define IPOPT_RR 7 +#endif +#ifndef IPOPT_TS +# define IPOPT_TS 68 +#endif +#ifndef IPOPT_SECURITY +# define IPOPT_SECURITY 130 +#endif +#ifndef IPOPT_LSRR +# define IPOPT_LSRR 131 +#endif +#ifndef IPOPT_SATID +# define IPOPT_SATID 136 +#endif +#ifndef IPOPT_SSRR +# define IPOPT_SSRR 137 +#endif +#ifndef IPOPT_SECUR_UNCLASS +# define IPOPT_SECUR_UNCLASS ((u_short)0x0000) +#endif +#ifndef IPOPT_SECUR_CONFID +# define IPOPT_SECUR_CONFID ((u_short)0xf135) +#endif +#ifndef IPOPT_SECUR_EFTO +# define IPOPT_SECUR_EFTO ((u_short)0x789a) +#endif +#ifndef IPOPT_SECUR_MMMM +# define IPOPT_SECUR_MMMM ((u_short)0xbc4d) +#endif +#ifndef IPOPT_SECUR_RESTR +# define IPOPT_SECUR_RESTR ((u_short)0xaf13) +#endif +#ifndef IPOPT_SECUR_SECRET +# define IPOPT_SECUR_SECRET ((u_short)0xd788) +#endif +#ifndef IPOPT_SECUR_TOPSECRET +# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5) +#endif + +#ifdef linux +# define icmp icmphdr +# define icmp_type type +# define icmp_code code + +/* + * From /usr/include/netinet/ip_var.h + * !%@#!$@# linux... + */ +struct ipovly { + caddr_t ih_next, ih_prev; /* for protocol sequence q's */ + u_char ih_x1; /* (unused) */ + u_char ih_pr; /* protocol */ + short ih_len; /* protocol length */ + struct in_addr ih_src; /* source internet address */ + struct in_addr ih_dst; /* destination internet address */ +}; + +typedef struct { + __u16 th_sport; + __u16 th_dport; + __u32 th_seq; + __u32 th_ack; +# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\ + defined(vax) + __u8 th_res:4; + __u8 th_off:4; +#else + __u8 th_off:4; + __u8 th_res:4; +#endif + __u8 th_flags; + __u16 th_win; + __u16 th_sum; + __u16 th_urp; +} tcphdr_t; + +typedef struct { + __u16 uh_sport; + __u16 uh_dport; + __s16 uh_ulen; + __u16 uh_sum; +} udphdr_t; + +typedef struct { +# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\ + defined(vax) + __u8 ip_hl:4; + __u8 ip_v:4; +# else + __u8 ip_hl:4; + __u8 ip_v:4; +# endif + __u8 ip_tos; + __u16 ip_len; + __u16 ip_id; + __u16 ip_off; + __u8 ip_ttl; + __u8 ip_p; + __u16 ip_sum; + struct in_addr ip_src; + struct in_addr ip_dst; +} ip_t; + +typedef struct { + __u8 ether_dhost[6]; + __u8 ether_shost[6]; + __u16 ether_type; +} ether_header_t; + +# define bcopy(a,b,c) memmove(b,a,c) +# define bcmp(a,b,c) memcmp(a,b,c) + +# define ifnet device + +#else + +typedef struct udphdr udphdr_t; +typedef struct tcphdr tcphdr_t; +typedef struct ip ip_t; +typedef struct ether_header ether_header_t; + +#endif + +#ifdef solaris +# define bcopy(a,b,c) memmove(b,a,c) +# define bcmp(a,b,c) memcmp(a,b,c) +# define bzero(a,b) memset(a,0,b) +#endif diff --git a/contrib/ipfilter/ipsd/ipsd.c b/contrib/ipfilter/ipsd/ipsd.c new file mode 100644 index 0000000..96364dd --- /dev/null +++ b/contrib/ipfilter/ipsd/ipsd.c @@ -0,0 +1,297 @@ +/* + * (C)opyright December 1995 Darren Reed. + * + * This software may be freely distributed as long as it is not altered + * in any way and that this messagge always accompanies it. + * + * The author of this software makes no garuntee about the + * performance of this package or its suitability to fulfill any purpose. + * + */ +#include <stdio.h> +#include <fcntl.h> +#include <signal.h> +#include <stdlib.h> +#include <netdb.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> +#include <netinet/ip_icmp.h> +#ifndef linux +#include <netinet/ip_var.h> +#include <netinet/tcpip.h> +#endif +#include "ip_compat.h" +#ifdef linux +#include <linux/sockios.h> +#include "tcpip.h" +#endif +#include "ipsd.h" + +#ifndef lint +static char sccsid[] = "@(#)ipsd.c 1.3 12/3/95 (C)1995 Darren Reed"; +#endif + +extern char *optarg; +extern int optind; + +#ifdef linux +char default_device[] = "eth0"; +#else +# ifdef sun +char default_device[] = "le0"; +# else +# ifdef ultrix +char default_device[] = "ln0"; +# else +char default_device[] = "lan0"; +# endif +# endif +#endif + +#define NPORTS 21 + +u_short defports[NPORTS] = { + 7, 9, 20, 21, 23, 25, 53, 69, 79, 111, + 123, 161, 162, 512, 513, 514, 515, 520, 540, 6000, 0 + }; + +ipsd_t *iphits[NPORTS]; +int writes = 0; + + +int ipcmp(sh1, sh2) +sdhit_t *sh1, *sh2; +{ + return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr; +} + + +/* + * Check to see if we've already received a packet from this host for this + * port. + */ +int findhit(ihp, src, dport) +ipsd_t *ihp; +struct in_addr src; +u_short dport; +{ + int i, j, k; + sdhit_t *sh; + + sh = NULL; + + if (ihp->sd_sz == 4) { + for (i = 0, sh = ihp->sd_hit; i < ihp->sd_cnt; i++, sh++) + if (src.s_addr == sh->sh_ip.s_addr) + return 1; + } else { + for (i = ihp->sd_cnt / 2, j = (i / 2) - 1; j >= 0; j--) { + k = ihp->sd_hit[i].sh_ip.s_addr - src.s_addr; + if (!k) + return 1; + else if (k < 0) + i -= j; + else + i += j; + } + } + return 0; +} + + +/* + * Search for port number amongst the sorted array of targets we're + * interested in. + */ +int detect(ip, tcp) +ip_t *ip; +tcphdr_t *tcp; +{ + ipsd_t *ihp; + sdhit_t *sh; + int i, j, k; + + for (i = 10, j = 4; j >= 0; j--) { + k = tcp->th_dport - defports[i]; + if (!k) { + ihp = iphits[i]; + if (findhit(ihp, ip->ip_src, tcp->th_dport)) + return 0; + sh = ihp->sd_hit + ihp->sd_cnt; + sh->sh_date = time(NULL); + sh->sh_ip.s_addr = ip->ip_src.s_addr; + if (++ihp->sd_cnt == ihp->sd_sz) + { + ihp->sd_sz += 8; + sh = realloc(sh, ihp->sd_sz * sizeof(*sh)); + ihp->sd_hit = sh; + } + qsort(sh, ihp->sd_cnt, sizeof(*sh), ipcmp); + return 0; + } + if (k < 0) + i -= j; + else + i += j; + } + return -1; +} + + +/* + * Allocate initial storage for hosts + */ +setuphits() +{ + int i; + + for (i = 0; i < NPORTS; i++) { + if (iphits[i]) { + if (iphits[i]->sd_hit) + free(iphits[i]->sd_hit); + free(iphits[i]); + } + iphits[i] = (ipsd_t *)malloc(sizeof(ipsd_t)); + iphits[i]->sd_port = defports[i]; + iphits[i]->sd_cnt = 0; + iphits[i]->sd_sz = 4; + iphits[i]->sd_hit = (sdhit_t *)malloc(sizeof(sdhit_t) * 4); + } +} + + +/* + * cleanup exits + */ +waiter() +{ + wait(0); +} + + +/* + * Write statistics out to a file + */ +writestats(nwrites) +int nwrites; +{ + ipsd_t **ipsd, *ips; + char fname[32]; + int i, fd; + + (void) sprintf(fname, "/var/log/ipsd/ipsd-hits.%d", nwrites); + fd = open(fname, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0644); + for (i = 0, ipsd = iphits; i < NPORTS; i++, ipsd++) { + ips = *ipsd; + if (ips->sd_cnt) { + write(fd, ips, sizeof(ipsd_t)); + write(fd, ips->sd_hit, sizeof(sdhit_t) * ips->sd_sz); + } + } + (void) close(fd); + exit(0); +} + + +void writenow() +{ + signal(SIGCHLD, waiter); + switch (fork()) + { + case 0 : + writestats(writes); + exit(0); + case -1 : + perror("vfork"); + break; + default : + writes++; + setuphits(); + break; + } +} + + +void usage(prog) +char *prog; +{ + fprintf(stderr, "Usage: %s [-d device]\n", prog); + exit(1); +} + + +void detecthits(fd, writecount) +int fd, writecount; +{ + struct in_addr ip; + int hits = 0; + + while (1) { + hits += readloop(fd, ip); + if (hits > writecount) { + writenow(); + hits = 0; + } + } +} + + +main(argc, argv) +int argc; +char *argv[]; +{ + char c, *name = argv[0], *dev = NULL; + int fd, writeafter = 10000, angelic = 0; + + while ((c = getopt(argc, argv, "ad:n:")) != -1) + switch (c) + { + case 'a' : + angelic = 1; + break; + case 'd' : + dev = optarg; + break; + case 'n' : + writeafter = atoi(optarg); + break; + default : + fprintf(stderr, "Unknown option \"%c\"\n", c); + usage(name); + } + + bzero(iphits, sizeof(iphits)); + setuphits(); + + if (!dev) + dev = default_device; + printf("Device: %s\n", dev); + fd = initdevice(dev, 60); + + if (!angelic) { + switch (fork()) + { + case 0 : + (void) close(0); + (void) close(1); + (void) close(2); + (void) setpgrp(0, getpgrp()); + (void) setsid(); + break; + case -1: + perror("fork"); + exit(-1); + default: + exit(0); + } + } + signal(SIGUSR1, writenow); + detecthits(fd, writeafter); +} diff --git a/contrib/ipfilter/ipsd/ipsd.h b/contrib/ipfilter/ipsd/ipsd.h new file mode 100644 index 0000000..a9f3920 --- /dev/null +++ b/contrib/ipfilter/ipsd/ipsd.h @@ -0,0 +1,30 @@ +/* + * (C)opyright December 1995 Darren Reed. + * + * This software may be freely distributed as long as it is not altered + * in any way and that this messagge always accompanies it. + * + * The author of this software makes no garuntee about the + * performance of this package or its suitability to fulfill any purpose. + * + * @(#)ipsd.h 1.3 12/3/95 + */ + +typedef struct { + time_t sh_date; + struct in_addr sh_ip; +} sdhit_t; + +typedef struct { + u_int sd_sz; + u_int sd_cnt; + u_short sd_port; + sdhit_t *sd_hit; +} ipsd_t; + +typedef struct { + struct in_addr ss_ip; + int ss_hits; + u_long ss_ports; +} ipss_t; + diff --git a/contrib/ipfilter/ipsd/ipsdr.c b/contrib/ipfilter/ipsd/ipsdr.c new file mode 100644 index 0000000..b3bf957 --- /dev/null +++ b/contrib/ipfilter/ipsd/ipsdr.c @@ -0,0 +1,315 @@ +/* + * (C)opyright December 1995 Darren Reed. + * + * This software may be freely distributed as long as it is not altered + * in any way and that this messagge always accompanies it. + * + * The author of this software makes no garuntee about the + * performance of this package or its suitability to fulfill any purpose. + * + */ +#include <stdio.h> +#include <fcntl.h> +#include <signal.h> +#include <malloc.h> +#include <netdb.h> +#include <string.h> +#include <sys/dir.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> +#include <netinet/ip_icmp.h> +#ifndef linux +#include <netinet/ip_var.h> +#include <netinet/tcpip.h> +#endif +#include "ip_compat.h" +#ifdef linux +#include <linux/sockios.h> +#include "tcpip.h" +#endif +#include "ipsd.h" + +#ifndef lint +static char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed"; +#endif + +extern char *optarg; +extern int optind; + +#define NPORTS 21 + +u_short defports[NPORTS] = { + 7, 9, 20, 21, 23, 25, 53, 69, 79, 111, + 123, 161, 162, 512, 513, 513, 515, 520, 540, 6000, 0 + }; +u_short pweights[NPORTS] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + +ipsd_t *iphits[NPORTS]; +int pkts; + + +int ipcmp(sh1, sh2) +sdhit_t *sh1, *sh2; +{ + return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr; +} + + +int ssipcmp(sh1, sh2) +ipss_t *sh1, *sh2; +{ + return sh1->ss_ip.s_addr - sh2->ss_ip.s_addr; +} + + +int countpbits(num) +u_long num; +{ + int i, j; + + for (i = 1, j = 0; i; i <<= 1) + if (num & i) + j++; + return j; +} + + +/* + * Check to see if we've already received a packet from this host for this + * port. + */ +int findhit(ihp, src, dport) +ipsd_t *ihp; +struct in_addr src; +u_short dport; +{ + int i, j, k; + sdhit_t *sh; + + sh = NULL; + + if (ihp->sd_sz == 4) { + for (i = 0, sh = ihp->sd_hit; i < ihp->sd_cnt; i++, sh++) + if (src.s_addr == sh->sh_ip.s_addr) + return 1; + } else { + for (i = ihp->sd_cnt / 2, j = (i / 2) - 1; j >= 0; j--) { + k = ihp->sd_hit[i].sh_ip.s_addr - src.s_addr; + if (!k) + return 1; + else if (k < 0) + i -= j; + else + i += j; + } + } + return 0; +} + + +/* + * Search for port number amongst the sorted array of targets we're + * interested in. + */ +int detect(srcip, dport, date) +struct in_addr srcip; +u_short dport; +time_t date; +{ + ipsd_t *ihp; + sdhit_t *sh; + int i, j, k; + + for (i = 10, j = 4; j >= 0; j--) { + k = dport - defports[i]; + if (!k) { + ihp = iphits[i]; + if (findhit(ihp, srcip, dport)) + return 0; + sh = ihp->sd_hit + ihp->sd_cnt; + sh->sh_date = date; + sh->sh_ip = srcip; + if (++ihp->sd_cnt == ihp->sd_sz) + { + ihp->sd_sz += 8; + sh = realloc(sh, ihp->sd_sz * sizeof(*sh)); + ihp->sd_hit = sh; + } + qsort(sh, ihp->sd_cnt, sizeof(*sh), ipcmp); + return 0; + } + if (k < 0) + i -= j; + else + i += j; + } + return -1; +} + + +/* + * Allocate initial storage for hosts + */ +setuphits() +{ + int i; + + for (i = 0; i < NPORTS; i++) { + if (iphits[i]) { + if (iphits[i]->sd_hit) + free(iphits[i]->sd_hit); + free(iphits[i]); + } + iphits[i] = (ipsd_t *)malloc(sizeof(ipsd_t)); + iphits[i]->sd_port = defports[i]; + iphits[i]->sd_cnt = 0; + iphits[i]->sd_sz = 4; + iphits[i]->sd_hit = (sdhit_t *)malloc(sizeof(sdhit_t) * 4); + } +} + + +/* + * Write statistics out to a file + */ +addfile(file) +char *file; +{ + ipsd_t ipsd, *ips = &ipsd; + sdhit_t hit, *hp; + char fname[32]; + int i, fd, sz; + + if ((fd = open(file, O_RDONLY)) == -1) { + perror("open"); + return; + } + + printf("opened %s\n", file); + do { + if (read(fd, ips, sizeof(*ips)) != sizeof(*ips)) + break; + sz = ips->sd_sz * sizeof(*hp); + hp = (sdhit_t *)malloc(sz); + if (read(fd, hp, sz) != sz) + break; + for (i = 0; i < ips->sd_cnt; i++) + detect(hp[i].sh_ip, ips->sd_port, hp[i].sh_date); + } while (1); + (void) close(fd); +} + + +readfiles(dir) +char *dir; +{ + struct direct **d; + int i, j; + + d = NULL; + i = scandir(dir, &d, NULL, NULL); + + for (j = 0; j < i; j++) { + if (strncmp(d[j]->d_name, "ipsd-hits.", 10)) + continue; + addfile(d[j]->d_name); + } +} + + +void printreport(ss, num) +ipss_t *ss; +int num; +{ + struct in_addr ip; + ipss_t *sp; + int i, j, mask; + u_long ports; + + printf("Hosts detected: %d\n", num); + if (!num) + return; + for (i = 0; i < num; i++) + printf("%s %d %d\n", inet_ntoa(ss[i].ss_ip), ss[i].ss_hits, + countpbits(ss[i].ss_ports)); + + printf("--------------------------\n"); + for (mask = 0xfffffffe, j = 32; j; j--, mask <<= 1) { + ip.s_addr = ss[0].ss_ip.s_addr & mask; + ports = ss[0].ss_ports; + for (i = 1; i < num; i++) { + sp = ss + i; + if (ip.s_addr != (sp->ss_ip.s_addr & mask)) { + printf("Netmask: 0x%08x\n", mask); + printf("%s %d\n", inet_ntoa(ip), + countpbits(ports)); + ip.s_addr = sp->ss_ip.s_addr & mask; + ports = 0; + } + ports |= sp->ss_ports; + } + if (ports) { + printf("Netmask: 0x%08x\n", mask); + printf("%s %d\n", inet_ntoa(ip), countpbits(ports)); + } + } +} + + +collectips() +{ + ipsd_t *ips; + ipss_t *ss; + int i, num, nip, in, j, k; + + for (i = 0; i < NPORTS; i++) + nip += iphits[i]->sd_cnt; + + ss = (ipss_t *)malloc(sizeof(ipss_t) * nip); + + for (in = 0, i = 0, num = 0; i < NPORTS; i++) { + ips = iphits[i]; + for (j = 0; j < ips->sd_cnt; j++) { + for (k = 0; k < num; k++) + if (!bcmp(&ss[k].ss_ip, &ips->sd_hit[j].sh_ip, + sizeof(struct in_addr))) { + ss[k].ss_hits += pweights[i]; + ss[k].ss_ports |= (1 << i); + break; + } + if (k == num) { + ss[num].ss_ip = ips->sd_hit[j].sh_ip; + ss[num].ss_hits = pweights[i]; + ss[k].ss_ports |= (1 << i); + num++; + } + } + } + + qsort(ss, num, sizeof(*ss), ssipcmp); + + printreport(ss, num); +} + + +main(argc, argv) +int argc; +char *argv[]; +{ + char c, *name = argv[0], *dir = NULL; + int fd; + + setuphits(); + dir = dir ? dir : "."; + readfiles(dir); + collectips(); +} diff --git a/contrib/ipfilter/ipsd/linux.h b/contrib/ipfilter/ipsd/linux.h new file mode 100644 index 0000000..7eb382b --- /dev/null +++ b/contrib/ipfilter/ipsd/linux.h @@ -0,0 +1,17 @@ +/* + * (C)opyright 1995 by Darren Reed. + * + * This code may be freely distributed as long as it retains this notice + * and is not changed in any way. The author accepts no responsibility + * for the use of this software. I hate legaleese, don't you ? + * + * @(#)linux.h 1.1 8/19/95 + */ + +#include <linux/config.h> +#ifdef MODULE +#include <linux/module.h> +#include <linux/version.h> +#endif /* MODULE */ + +#include "ip_compat.h" diff --git a/contrib/ipfilter/ipsd/sbpf.c b/contrib/ipfilter/ipsd/sbpf.c new file mode 100644 index 0000000..d008a5f --- /dev/null +++ b/contrib/ipfilter/ipsd/sbpf.c @@ -0,0 +1,195 @@ +/* + * (C)opyright October 1995 Darren Reed. (from tcplog) + * + * This software may be freely distributed as long as it is not altered + * in any way and that this messagge always accompanies it. + * + */ +#include <stdio.h> +#include <netdb.h> +#include <ctype.h> +#include <signal.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/mbuf.h> +#include <sys/time.h> +#include <sys/timeb.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <sys/ioctl.h> +#if BSD < 199103 +#include <sys/fcntlcom.h> +#endif +#include <sys/dir.h> +#include <net/bpf.h> + +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/if_ether.h> +#include <netinet/ip_var.h> +#include <netinet/udp.h> +#include <netinet/udp_var.h> +#include <netinet/tcp.h> +#include <netinet/tcpip.h> +#include "ip_compat.h" + +#ifndef lint +static char sbpf[] = "@(#)sbpf.c 1.2 12/3/95 (C)1995 Darren Reed"; +#endif + +/* +(000) ldh [12] +(001) jeq #0x800 jt 2 jf 5 +(002) ldb [23] +(003) jeq #0x6 jt 4 jf 5 +(004) ret #68 +(005) ret #0 +*/ +struct bpf_insn filter[] = { +/* 0. */ { BPF_LD|BPF_H|BPF_ABS, 0, 0, 12 }, +/* 1. */ { BPF_JMP|BPF_JEQ, 0, 3, 0x0800 }, +/* 2. */ { BPF_LD|BPF_B|BPF_ABS, 0, 0, 23 }, +/* 3. */ { BPF_JMP|BPF_JEQ, 0, 1, 0x06 }, +/* 4. */ { BPF_RET, 0, 0, 68 }, +/* 5. */ { BPF_RET, 0, 0, 0 } +}; +/* + * the code herein is dervied from libpcap. + */ +static u_char *buf = NULL; +static u_int bufsize = 32768, timeout = 1; + + +int ack_recv(ep) +char *ep; +{ + struct tcpiphdr tip; + tcphdr_t *tcp; + ip_t *ip; + + ip = (ip_t *)&tip; + tcp = (tcphdr_t *)(ip + 1); + bcopy(ep + 14, (char *)ip, sizeof(*ip)); + bcopy(ep + 14 + (ip->ip_hl << 2), (char *)tcp, sizeof(*tcp)); + if (ip->ip_p != IPPROTO_TCP && ip->ip_p != IPPROTO_UDP) + return -1; + if (ip->ip_p & 0x1fff != 0) + return 0; + if (0 == detect(ip, tcp)) + return 1; + return 0; +} + + +int readloop(fd, port, dst) +int fd, port; +struct in_addr dst; +{ + register u_char *bp, *cp, *bufend; + register struct bpf_hdr *bh; + register int cc; + time_t in = time(NULL); + int done = 0; + + while ((cc = read(fd, buf, bufsize)) >= 0) { + if (!cc && (time(NULL) - in) > timeout) + return done; + bp = buf; + bufend = buf + cc; + /* + * loop through each snapshot in the chunk + */ + while (bp < bufend) { + bh = (struct bpf_hdr *)bp; + cp = bp + bh->bh_hdrlen; + done += ack_recv(cp); + bp += BPF_WORDALIGN(bh->bh_caplen + bh->bh_hdrlen); + } + return done; + } + perror("read"); + exit(-1); +} + +int initdevice(device, tout) +char *device; +int tout; +{ + struct bpf_program prog; + struct bpf_version bv; + struct timeval to; + struct ifreq ifr; + char bpfname[16]; + int fd, i; + + for (i = 0; i < 16; i++) + { + (void) sprintf(bpfname, "/dev/bpf%d", i); + if ((fd = open(bpfname, O_RDWR)) >= 0) + break; + } + if (i == 16) + { + fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); + return -1; + } + + if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) + { + perror("BIOCVERSION"); + return -1; + } + if (bv.bv_major != BPF_MAJOR_VERSION || + bv.bv_minor < BPF_MINOR_VERSION) + { + fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n", + bv.bv_major, bv.bv_minor); + fprintf(stderr, "current version: %d.%d\n", + BPF_MAJOR_VERSION, BPF_MINOR_VERSION); + return -1; + } + + (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(fd, BIOCSETIF, &ifr) == -1) + { + fprintf(stderr, "%s(%d):", ifr.ifr_name, fd); + perror("BIOCSETIF"); + exit(1); + } + /* + * set the timeout + */ + timeout = tout; + to.tv_sec = 1; + to.tv_usec = 0; + if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1) + { + perror("BIOCSRTIMEOUT"); + exit(-1); + } + /* + * get kernel buffer size + */ + if (ioctl(fd, BIOCSBLEN, &bufsize) == -1) + perror("BIOCSBLEN"); + if (ioctl(fd, BIOCGBLEN, &bufsize) == -1) + { + perror("BIOCGBLEN"); + exit(-1); + } + printf("BPF buffer size: %d\n", bufsize); + buf = (u_char*)malloc(bufsize); + + prog.bf_len = sizeof(filter) / sizeof(struct bpf_insn); + prog.bf_insns = filter; + if (ioctl(fd, BIOCSETF, (caddr_t)&prog) == -1) + { + perror("BIOCSETF"); + exit(-1); + } + (void) ioctl(fd, BIOCFLUSH, 0); + return fd; +} diff --git a/contrib/ipfilter/ipsd/sdlpi.c b/contrib/ipfilter/ipsd/sdlpi.c new file mode 100644 index 0000000..1d0e41d --- /dev/null +++ b/contrib/ipfilter/ipsd/sdlpi.c @@ -0,0 +1,263 @@ +/* + * (C)opyright October 1992 Darren Reed. (from tcplog) + * + * This software may be freely distributed as long as it is not altered + * in any way and that this messagge always accompanies it. + * + * The author of this software makes no garuntee about the + * performance of this package or its suitability to fulfill any purpose. + * + */ + +#include <stdio.h> +#include <netdb.h> +#include <ctype.h> +#include <fcntl.h> +#include <signal.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/timeb.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <sys/ioctl.h> +#include <sys/stropts.h> + +#include <sys/pfmod.h> +#include <sys/bufmod.h> +#include <sys/dlpi.h> + +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/if_ether.h> +#include <netinet/ip_var.h> +#include <netinet/udp.h> +#include <netinet/udp_var.h> +#include <netinet/tcp.h> +#include <netinet/tcpip.h> + +#include "ip_compat.h" + +#ifndef lint +static char snitid[] = "%W% %G% (C)1995 Darren Reed"; +#endif + +#define BUFSPACE 32768 + +static int solfd; + +/* + * Be careful to only include those defined in the flags option for the + * interface are included in the header size. + */ +static int timeout; + + +void nullbell() +{ + return 0; +} + + +int ack_recv(ep) +char *ep; +{ + struct tcpiphdr tip; + tcphdr_t *tcp; + ip_t *ip; + + ip = (ip_t *)&tip; + tcp = (tcphdr_t *)(ip + 1); + bcopy(ep, (char *)ip, sizeof(*ip)); + bcopy(ep + (ip->ip_hl << 2), (char *)tcp, sizeof(*tcp)); + + if (ip->ip_off & 0x1fff != 0) + return 0; + if (0 == detect(ip, tcp)) + return 1; + return 0; +} + + +int readloop(fd, port, dst) +int fd, port; +struct in_addr dst; +{ + static u_char buf[BUFSPACE]; + register u_char *bp, *cp, *bufend; + register struct sb_hdr *hp; + register int cc; + struct strbuf dbuf; + ether_header_t eh; + time_t now = time(NULL); + int flags = 0, i, done = 0; + + fd = solfd; + dbuf.len = 0; + dbuf.buf = buf; + dbuf.maxlen = sizeof(buf); + /* + * no control data buffer... + */ + while (1) { + (void) signal(SIGALRM, nullbell); + alarm(1); + i = getmsg(fd, NULL, &dbuf, &flags); + alarm(0); + (void) signal(SIGALRM, nullbell); + + cc = dbuf.len; + if ((time(NULL) - now) > timeout) + return done; + if (i == -1) + if (errno == EINTR) + continue; + else + break; + bp = buf; + bufend = buf + cc; + /* + * loop through each snapshot in the chunk + */ + while (bp < bufend) { + /* + * get past bufmod header + */ + hp = (struct sb_hdr *)bp; + cp = (u_char *)((char *)bp + sizeof(*hp)); + bcopy(cp, (char *)&eh, sizeof(eh)); + /* + * next snapshot + */ + bp += hp->sbh_totlen; + cc -= hp->sbh_totlen; + + if (eh.ether_type != ETHERTYPE_IP) + continue; + + cp += sizeof(eh); + done += ack_recv(cp); + } + alarm(1); + } + perror("getmsg"); + exit(-1); +} + +int initdevice(device, tout) +char *device; +int tout; +{ + struct strioctl si; + struct timeval to; + struct ifreq ifr; + struct packetfilt pfil; + u_long if_flags; + u_short *fwp = pfil.Pf_Filter; + char devname[16], *s, buf[256]; + int i, offset, fd, snaplen= 58, chunksize = BUFSPACE; + + (void) sprintf(devname, "/dev/%s", device); + + s = devname + 5; + while (*s && !isdigit(*s)) + s++; + if (!*s) + { + fprintf(stderr, "bad device name %s\n", devname); + exit(-1); + } + i = atoi(s); + *s = '\0'; + /* + * For reading + */ + if ((fd = open(devname, O_RDWR)) < 0) + { + fprintf(stderr, "O_RDWR(0) "); + perror(devname); + exit(-1); + } + if (dlattachreq(fd, i) == -1 || dlokack(fd, buf) == -1) + { + fprintf(stderr, "DLPI error\n"); + exit(-1); + } + dlbindreq(fd, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0); + dlbindack(fd, buf); + /* + * read full headers + */ + if (strioctl(fd, DLIOCRAW, -1, 0, NULL) == -1) + { + fprintf(stderr, "DLIOCRAW error\n"); + exit(-1); + } + /* + * Create some filter rules for our TCP watcher. We only want ethernet + * pacets which are IP protocol and only the TCP packets from IP. + */ + offset = 6; + *fwp++ = ENF_PUSHWORD + offset; + *fwp++ = ENF_PUSHLIT | ENF_CAND; + *fwp++ = htons(ETHERTYPE_IP); + *fwp++ = ENF_PUSHWORD + sizeof(struct ether_header)/sizeof(short)+4; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0x00ff); + *fwp++ = ENF_PUSHLIT | ENF_COR; + *fwp++ = htons(IPPROTO_TCP); + *fwp++ = ENF_PUSHWORD + sizeof(struct ether_header)/sizeof(short)+4; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0x00ff); + *fwp++ = ENF_PUSHLIT | ENF_CAND; + *fwp++ = htons(IPPROTO_UDP); + pfil.Pf_FilterLen = (fwp - &pfil.Pf_Filter[0]); + /* + * put filter in place. + */ + + if (ioctl(fd, I_PUSH, "pfmod") == -1) + { + perror("ioctl: I_PUSH pf"); + exit(1); + } + if (strioctl(fd, PFIOCSETF, -1, sizeof(pfil), (char *)&pfil) == -1) + { + perror("ioctl: PFIOCSETF"); + exit(1); + } + + /* + * arrange to get messages from the NIT STREAM and use NIT_BUF option + */ + if (ioctl(fd, I_PUSH, "bufmod") == -1) + { + perror("ioctl: I_PUSH bufmod"); + exit(1); + } + i = 128; + strioctl(fd, SBIOCSSNAP, -1, sizeof(i), (char *)&i); + /* + * set the timeout + */ + to.tv_sec = 1; + to.tv_usec = 0; + if (strioctl(fd, SBIOCSTIME, -1, sizeof(to), (char *)&to) == -1) + { + perror("strioctl(SBIOCSTIME)"); + exit(-1); + } + /* + * flush read queue + */ + if (ioctl(fd, I_FLUSH, FLUSHR) == -1) + { + perror("I_FLUSHR"); + exit(-1); + } + timeout = tout; + solfd = fd; + return fd; +} diff --git a/contrib/ipfilter/ipsd/slinux.c b/contrib/ipfilter/ipsd/slinux.c new file mode 100644 index 0000000..1115b86 --- /dev/null +++ b/contrib/ipfilter/ipsd/slinux.c @@ -0,0 +1,120 @@ +/* + * (C)opyright October 1992 Darren Reed. (from tcplog) + * + * This software may be freely distributed as long as it is not altered + * in any way and that this messagge always accompanies it. + * + * The author of this software makes no garuntee about the + * performance of this package or its suitability to fulfill any purpose. + * + */ + +#include <stdio.h> +#include <netdb.h> +#include <ctype.h> +#include <signal.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/timeb.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <sys/ioctl.h> +#include <sys/dir.h> +#include <linux/netdevice.h> +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include "ip_compat.h" +#include "tcpip.h" + +#ifndef lint +static char sccsid[] = "@(#)slinux.c 1.1 12/3/95 (C) 1995 Darren Reed"; +#endif + +#define BUFSPACE 32768 + +/* + * Be careful to only include those defined in the flags option for the + * interface are included in the header size. + */ + +static int timeout; +static char *eth_dev = NULL; + + +int ack_recv(bp) +char *bp; +{ + struct tcpip tip; + tcphdr_t *tcp; + ip_t *ip; + + ip = (struct ip *)&tip; + tcp = (tcphdr_t *)(ip + 1); + + bcopy(bp, (char *)&tip, sizeof(tip)); + bcopy(bp + (ip.ip_hl << 2), (char *)tcp, sizeof(*tcp)); + if (0 == detect(ip, tcp)) + return 1; + return 0; +} + + +void readloop(fd, port, dst) +int fd, port; +struct in_addr dst; +{ + static u_char buf[BUFSPACE]; + struct sockaddr dest; + register u_char *bp = buf; + register int cc; + int dlen, done = 0; + time_t now = time(NULL); + + do { + fflush(stdout); + dlen = sizeof(dest); + bzero((char *)&dest, dlen); + cc = recvfrom(fd, buf, BUFSPACE, 0, &dest, &dlen); + if (!cc) + if ((time(NULL) - now) > timeout) + return done; + else + continue; + + if (bp[12] != 0x8 || bp[13] != 0) + continue; /* not ip */ + + /* + * get rid of non-tcp or fragmented packets here. + */ + if (cc >= sizeof(struct tcpiphdr)) + { + if (((bp[14+9] != IPPROTO_TCP) && + (bp[14+9] != IPPROTO_UDP)) || + (bp[14+6] & 0x1f) || (bp[14+6] & 0xff)) + continue; + done += ack_recv(bp + 14); + } + } while (cc >= 0); + perror("read"); + exit(-1); +} + +int initdevice(dev, tout) +char *dev; +int tout; +{ + int fd; + + eth_dev = strdup(dev); + if ((fd = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_IP))) == -1) + { + perror("socket(SOCK_PACKET)"); + exit(-1); + } + + return fd; +} diff --git a/contrib/ipfilter/ipsd/snit.c b/contrib/ipfilter/ipsd/snit.c new file mode 100644 index 0000000..4b5fd03 --- /dev/null +++ b/contrib/ipfilter/ipsd/snit.c @@ -0,0 +1,230 @@ +/* + * (C)opyright October 1992 Darren Reed. (from tcplog) + * + * This software may be freely distributed as long as it is not altered + * in any way and that this messagge always accompanies it. + * + * The author of this software makes no garuntee about the + * performance of this package or its suitability to fulfill any purpose. + * + */ + +#include <stdio.h> +#include <netdb.h> +#include <ctype.h> +#include <signal.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/timeb.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <sys/ioctl.h> +#include <net/nit.h> +#include <sys/fcntlcom.h> +#include <sys/dir.h> +#include <net/nit_if.h> +#include <net/nit_pf.h> +#include <net/nit_buf.h> +#include <net/packetfilt.h> +#include <sys/stropts.h> + +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/if_ether.h> +#include <netinet/ip_var.h> +#include <netinet/udp.h> +#include <netinet/udp_var.h> +#include <netinet/tcp.h> +#include <netinet/tcpip.h> + +#ifndef lint +static char snitid[] = "@(#)snit.c 1.2 12/3/95 (C)1995 Darren Reed"; +#endif + +#define BUFSPACE 32768 + +/* + * Be careful to only include those defined in the flags option for the + * interface are included in the header size. + */ +#define BUFHDR_SIZE (sizeof(struct nit_bufhdr)) +#define NIT_HDRSIZE (BUFHDR_SIZE) + +static int timeout; + + +int ack_recv(ep) +char *ep; +{ + struct tcpiphdr tip; + struct tcphdr *tcp; + struct ip *ip; + + ip = (struct ip *)&tip; + tcp = (struct tcphdr *)(ip + 1); + bcopy(ep + 14, (char *)ip, sizeof(*ip)); + bcopy(ep + 14 + (ip->ip_hl << 2), (char *)tcp, sizeof(*tcp)); + if (ip->ip_off & 0x1fff != 0) + return 0; + if (0 == detect(ip, tcp)) + return 1; + return 0; +} + + +int readloop(fd, dst) +int fd; +struct in_addr dst; +{ + static u_char buf[BUFSPACE]; + register u_char *bp, *cp, *bufend; + register struct nit_bufhdr *hp; + register int cc; + time_t now = time(NULL); + int done = 0; + + while ((cc = read(fd, buf, BUFSPACE-1)) >= 0) { + if (!cc) + if ((time(NULL) - now) > timeout) + return done; + else + continue; + bp = buf; + bufend = buf + cc; + /* + * loop through each snapshot in the chunk + */ + while (bp < bufend) { + cp = (u_char *)((char *)bp + NIT_HDRSIZE); + /* + * get past NIT buffer + */ + hp = (struct nit_bufhdr *)bp; + /* + * next snapshot + */ + bp += hp->nhb_totlen; + done += ack_recv(cp); + } + return done; + } + perror("read"); + exit(-1); +} + +int initdevice(device, tout) +char *device; +int tout; +{ + struct strioctl si; + struct timeval to; + struct ifreq ifr; + struct packetfilt pfil; + u_long if_flags; + u_short *fwp = pfil.Pf_Filter; + int ret, offset, fd, snaplen= 76, chunksize = BUFSPACE; + + if ((fd = open("/dev/nit", O_RDWR)) < 0) + { + perror("/dev/nit"); + exit(-1); + } + + /* + * Create some filter rules for our TCP watcher. We only want ethernet + * pacets which are IP protocol and only the TCP packets from IP. + */ + offset = 6; + *fwp++ = ENF_PUSHWORD + offset; + *fwp++ = ENF_PUSHLIT | ENF_CAND; + *fwp++ = htons(ETHERTYPE_IP); + *fwp++ = ENF_PUSHWORD + sizeof(struct ether_header)/sizeof(short)+4; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0x00ff); + *fwp++ = ENF_PUSHLIT | ENF_COR; + *fwp++ = htons(IPPROTO_TCP); + *fwp++ = ENF_PUSHWORD + sizeof(struct ether_header)/sizeof(short)+4; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0x00ff); + *fwp++ = ENF_PUSHLIT | ENF_CAND; + *fwp++ = htons(IPPROTO_UDP); + pfil.Pf_FilterLen = fwp - &pfil.Pf_Filter[0]; + /* + * put filter in place. + */ + if (ioctl(fd, I_PUSH, "pf") == -1) + { + perror("ioctl: I_PUSH pf"); + exit(1); + } + if (ioctl(fd, NIOCSETF, &pfil) == -1) + { + perror("ioctl: NIOCSETF"); + exit(1); + } + /* + * arrange to get messages from the NIT STREAM and use NIT_BUF option + */ + ioctl(fd, I_SRDOPT, (char*)RMSGD); + ioctl(fd, I_PUSH, "nbuf"); + /* + * set the timeout + */ + timeout = tout; + si.ic_timout = 1; + to.tv_sec = 1; + to.tv_usec = 0; + si.ic_cmd = NIOCSTIME; + si.ic_len = sizeof(to); + si.ic_dp = (char*)&to; + if (ioctl(fd, I_STR, (char*)&si) == -1) + { + perror("ioctl: NIT timeout"); + exit(-1); + } + /* + * set the chunksize + */ + si.ic_cmd = NIOCSCHUNK; + si.ic_len = sizeof(chunksize); + si.ic_dp = (char*)&chunksize; + if (ioctl(fd, I_STR, (char*)&si) == -1) + perror("ioctl: NIT chunksize"); + if (ioctl(fd, NIOCGCHUNK, (char*)&chunksize) == -1) + { + perror("ioctl: NIT chunksize"); + exit(-1); + } + printf("NIT buffer size: %d\n", chunksize); + + /* + * request the interface + */ + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' '; + si.ic_cmd = NIOCBIND; + si.ic_len = sizeof(ifr); + si.ic_dp = (char*)𝔦 + if (ioctl(fd, I_STR, (char*)&si) == -1) + { + perror(ifr.ifr_name); + exit(1); + } + + /* + * set the snapshot length + */ + si.ic_cmd = NIOCSSNAP; + si.ic_len = sizeof(snaplen); + si.ic_dp = (char*)&snaplen; + if (ioctl(fd, I_STR, (char*)&si) == -1) + { + perror("ioctl: NIT snaplen"); + exit(1); + } + (void) ioctl(fd, I_FLUSH, (char*)FLUSHR); + return fd; +} |