Home | History | Annotate | Line # | Download | only in ipsd
      1 /*	$NetBSD: ipsdr.c,v 1.2 2012/07/22 14:27:35 darrenr Exp $	*/
      2 
      3 /*
      4  * (C)opyright 1995-1998 Darren Reed.
      5  *
      6  * See the IPFILTER.LICENCE file for details on licencing.
      7  *
      8  */
      9 #include <stdio.h>
     10 #include <fcntl.h>
     11 #include <signal.h>
     12 #include <malloc.h>
     13 #include <netdb.h>
     14 #include <string.h>
     15 #include <sys/dir.h>
     16 #include <sys/types.h>
     17 #include <sys/time.h>
     18 #include <sys/socket.h>
     19 #include <netinet/in.h>
     20 #include <netinet/in_systm.h>
     21 #include <netinet/ip.h>
     22 #include <netinet/tcp.h>
     23 #include <netinet/udp.h>
     24 #include <netinet/ip_icmp.h>
     25 #ifndef	linux
     26 #include <netinet/ip_var.h>
     27 #include <netinet/tcpip.h>
     28 #endif
     29 #include "ip_compat.h"
     30 #ifdef	linux
     31 #include <linux/sockios.h>
     32 #include "tcpip.h"
     33 #endif
     34 #include "ipsd.h"
     35 
     36 #ifndef	lint
     37 static const char sccsid[] = "@(#)ipsdr.c	1.3 12/3/95 (C)1995 Darren Reed";
     38 static const char rcsid[] = "@(#)Id: ipsdr.c,v 1.1.1.2 2012/07/22 13:44:34 darrenr Exp $";
     39 #endif
     40 
     41 extern	char	*optarg;
     42 extern	int	optind;
     43 
     44 #define	NPORTS	21
     45 
     46 u_short	defports[NPORTS] = {
     47 		7,   9,  20,  21,  23,  25,  53,  69,  79, 111,
     48 		123, 161, 162, 512, 513, 513, 515, 520, 540, 6000, 0
     49 	};
     50 u_short	pweights[NPORTS] = {
     51 		1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     52 		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
     53 	};
     54 
     55 ipsd_t	*iphits[NPORTS];
     56 int	pkts;
     57 
     58 
     59 int	ipcmp(sh1, sh2)
     60 	sdhit_t	*sh1, *sh2;
     61 {
     62 	return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr;
     63 }
     64 
     65 
     66 int	ssipcmp(sh1, sh2)
     67 	ipss_t	*sh1, *sh2;
     68 {
     69 	return sh1->ss_ip.s_addr - sh2->ss_ip.s_addr;
     70 }
     71 
     72 
     73 int countpbits(num)
     74 	u_long	num;
     75 {
     76 	int	i, j;
     77 
     78 	for (i = 1, j = 0; i; i <<= 1)
     79 		if (num & i)
     80 			j++;
     81 	return j;
     82 }
     83 
     84 
     85 /*
     86  * Check to see if we've already received a packet from this host for this
     87  * port.
     88  */
     89 int	findhit(ihp, src, dport)
     90 	ipsd_t	*ihp;
     91 	struct	in_addr	src;
     92 	u_short	dport;
     93 {
     94 	int	i, j, k;
     95 	sdhit_t	*sh;
     96 
     97 	sh = NULL;
     98 
     99 	if (ihp->sd_sz == 4) {
    100 		for (i = 0, sh = ihp->sd_hit; i < ihp->sd_cnt; i++, sh++)
    101 			if (src.s_addr == sh->sh_ip.s_addr)
    102 				return 1;
    103 	} else {
    104 		for (i = ihp->sd_cnt / 2, j = (i / 2) - 1; j >= 0; j--) {
    105 			k = ihp->sd_hit[i].sh_ip.s_addr - src.s_addr;
    106 			if (!k)
    107 				return 1;
    108 			else if (k < 0)
    109 				i -= j;
    110 			else
    111 				i += j;
    112 		}
    113 	}
    114 	return 0;
    115 }
    116 
    117 
    118 /*
    119  * Search for port number amongst the sorted array of targets we're
    120  * interested in.
    121  */
    122 int	detect(srcip, dport, date)
    123 	struct	in_addr	srcip;
    124 	u_short	dport;
    125 	time_t	date;
    126 {
    127 	ipsd_t	*ihp;
    128 	sdhit_t	*sh;
    129 	int	i, j, k;
    130 
    131 	for (i = 10, j = 4; j >= 0; j--) {
    132 		k = dport - defports[i];
    133 		if (!k) {
    134 			ihp = iphits[i];
    135 			if (findhit(ihp, srcip, dport))
    136 				return 0;
    137 			sh = ihp->sd_hit + ihp->sd_cnt;
    138 			sh->sh_date = date;
    139 			sh->sh_ip = srcip;
    140 			if (++ihp->sd_cnt == ihp->sd_sz)
    141 			{
    142 				ihp->sd_sz += 8;
    143 				sh = realloc(sh, ihp->sd_sz * sizeof(*sh));
    144 				ihp->sd_hit = sh;
    145 			}
    146 			qsort(sh, ihp->sd_cnt, sizeof(*sh), ipcmp);
    147 			return 0;
    148 		}
    149 		if (k < 0)
    150 			i -= j;
    151 		else
    152 			i += j;
    153 	}
    154 	return -1;
    155 }
    156 
    157 
    158 /*
    159  * Allocate initial storage for hosts
    160  */
    161 setuphits()
    162 {
    163 	int	i;
    164 
    165 	for (i = 0; i < NPORTS; i++) {
    166 		if (iphits[i]) {
    167 			if (iphits[i]->sd_hit)
    168 				free(iphits[i]->sd_hit);
    169 			free(iphits[i]);
    170 		}
    171 		iphits[i] = (ipsd_t *)malloc(sizeof(ipsd_t));
    172 		iphits[i]->sd_port = defports[i];
    173 		iphits[i]->sd_cnt = 0;
    174 		iphits[i]->sd_sz = 4;
    175 		iphits[i]->sd_hit = (sdhit_t *)malloc(sizeof(sdhit_t) * 4);
    176 	}
    177 }
    178 
    179 
    180 /*
    181  * Write statistics out to a file
    182  */
    183 addfile(file)
    184 	char	*file;
    185 {
    186 	ipsd_t	ipsd, *ips = &ipsd;
    187 	sdhit_t	hit, *hp;
    188 	char	fname[32];
    189 	int	i, fd, sz;
    190 
    191 	if ((fd = open(file, O_RDONLY)) == -1) {
    192 		perror("open");
    193 		return;
    194 	}
    195 
    196 	printf("opened %s\n", file);
    197 	do {
    198 		if (read(fd, ips, sizeof(*ips)) != sizeof(*ips))
    199 			break;
    200 		sz = ips->sd_sz * sizeof(*hp);
    201 		hp = (sdhit_t *)malloc(sz);
    202 		if (read(fd, hp, sz) != sz)
    203 			break;
    204 		for (i = 0; i < ips->sd_cnt; i++)
    205 			detect(hp[i].sh_ip, ips->sd_port, hp[i].sh_date);
    206 	} while (1);
    207 	(void) close(fd);
    208 }
    209 
    210 
    211 readfiles(dir)
    212 	char *dir;
    213 {
    214 	struct	direct	**d;
    215 	int	i, j;
    216 
    217 	d = NULL;
    218 	i = scandir(dir, &d, NULL, NULL);
    219 
    220 	for (j = 0; j < i; j++) {
    221 		if (strncmp(d[j]->d_name, "ipsd-hits.", 10))
    222 			continue;
    223 		addfile(d[j]->d_name);
    224 	}
    225 }
    226 
    227 
    228 void printreport(ss, num)
    229 	ipss_t	*ss;
    230 	int	num;
    231 {
    232 	struct	in_addr	ip;
    233 	ipss_t	*sp;
    234 	int	i, j, mask;
    235 	u_long	ports;
    236 
    237 	printf("Hosts detected: %d\n", num);
    238 	if (!num)
    239 		return;
    240 	for (i = 0; i < num; i++)
    241 		printf("%s %d %d\n", inet_ntoa(ss[i].ss_ip), ss[i].ss_hits,
    242 			countpbits(ss[i].ss_ports));
    243 
    244 	printf("--------------------------\n");
    245 	for (mask = 0xfffffffe, j = 32; j; j--, mask <<= 1) {
    246 		ip.s_addr = ss[0].ss_ip.s_addr & mask;
    247 		ports = ss[0].ss_ports;
    248 		for (i = 1; i < num; i++) {
    249 			sp = ss + i;
    250 			if (ip.s_addr != (sp->ss_ip.s_addr & mask)) {
    251 				printf("Netmask: 0x%08x\n", mask);
    252 				printf("%s %d\n", inet_ntoa(ip),
    253 					countpbits(ports));
    254 				ip.s_addr = sp->ss_ip.s_addr & mask;
    255 				ports = 0;
    256 			}
    257 			ports |= sp->ss_ports;
    258 		}
    259 		if (ports) {
    260 			printf("Netmask: 0x%08x\n", mask);
    261 			printf("%s %d\n", inet_ntoa(ip), countpbits(ports));
    262 		}
    263 	}
    264 }
    265 
    266 
    267 collectips()
    268 {
    269 	ipsd_t	*ips;
    270 	ipss_t	*ss;
    271 	int	i, num, nip, in, j, k;
    272 
    273 	for (i = 0; i < NPORTS; i++)
    274 		nip += iphits[i]->sd_cnt;
    275 
    276 	ss = (ipss_t *)malloc(sizeof(ipss_t) * nip);
    277 
    278 	for (in = 0, i = 0, num = 0; i < NPORTS; i++) {
    279 		ips = iphits[i];
    280 		for (j = 0; j < ips->sd_cnt; j++) {
    281 			for (k = 0; k < num; k++)
    282 				if (!bcmp(&ss[k].ss_ip, &ips->sd_hit[j].sh_ip,
    283 					  sizeof(struct in_addr))) {
    284 					ss[k].ss_hits += pweights[i];
    285 					ss[k].ss_ports |= (1 << i);
    286 					break;
    287 				}
    288 			if (k == num) {
    289 				ss[num].ss_ip = ips->sd_hit[j].sh_ip;
    290 				ss[num].ss_hits = pweights[i];
    291 				ss[k].ss_ports |= (1 << i);
    292 				num++;
    293 			}
    294 		}
    295 	}
    296 
    297 	qsort(ss, num, sizeof(*ss), ssipcmp);
    298 
    299 	printreport(ss, num);
    300 }
    301 
    302 
    303 main(argc, argv)
    304 	int	argc;
    305 	char	*argv[];
    306 {
    307 	char	c, *name =  argv[0], *dir = NULL;
    308 	int	fd;
    309 
    310 	setuphits();
    311 	dir = dir ? dir : ".";
    312 	readfiles(dir);
    313 	collectips();
    314 }
    315