ipsdr.c revision 31183
152419Sjulian/*
252419Sjulian * (C)opyright 1995-1997 Darren Reed.
352419Sjulian *
452419Sjulian * Redistribution and use in source and binary forms are permitted
552419Sjulian * provided that this notice is preserved and due credit is given
652419Sjulian * to the original author and the contributors.
752419Sjulian *
852419Sjulian *   The author of this software makes no garuntee about the
952419Sjulian * performance of this package or its suitability to fulfill any purpose.
1052419Sjulian *
1152419Sjulian */
1252419Sjulian#include <stdio.h>
1352419Sjulian#include <fcntl.h>
1452419Sjulian#include <signal.h>
1552419Sjulian#include <malloc.h>
1652419Sjulian#include <netdb.h>
1752419Sjulian#include <string.h>
1852419Sjulian#include <sys/dir.h>
1952419Sjulian#include <sys/types.h>
2052419Sjulian#include <sys/time.h>
2152419Sjulian#include <sys/socket.h>
2252419Sjulian#include <netinet/in.h>
2352419Sjulian#include <netinet/in_systm.h>
2452419Sjulian#include <netinet/ip.h>
2552419Sjulian#include <netinet/tcp.h>
2652419Sjulian#include <netinet/udp.h>
2752419Sjulian#include <netinet/ip_icmp.h>
2852419Sjulian#ifndef	linux
2952419Sjulian#include <netinet/ip_var.h>
3052419Sjulian#include <netinet/tcpip.h>
3152419Sjulian#endif
3252419Sjulian#include "ip_compat.h"
3352419Sjulian#ifdef	linux
3452419Sjulian#include <linux/sockios.h>
3552419Sjulian#include "tcpip.h"
3652419Sjulian#endif
3752419Sjulian#include "ipsd.h"
3852419Sjulian
3952419Sjulian#ifndef	lint
4052752Sjulianstatic const char sccsid[] = "@(#)ipsdr.c	1.3 12/3/95 (C)1995 Darren Reed";
4152419Sjulianstatic const char rcsid[] = "@(#)$Id: ipsdr.c,v 2.0.2.3 1997/09/28 07:13:18 darrenr Exp $";
4252419Sjulian#endif
4352419Sjulian
4452419Sjulianextern	char	*optarg;
4552419Sjulianextern	int	optind;
4652419Sjulian
4752419Sjulian#define	NPORTS	21
4853997Sarchie
4952419Sjulianu_short	defports[NPORTS] = {
5052419Sjulian		7,   9,  20,  21,  23,  25,  53,  69,  79, 111,
5152419Sjulian		123, 161, 162, 512, 513, 513, 515, 520, 540, 6000, 0
5252419Sjulian	};
5353997Sarchieu_short	pweights[NPORTS] = {
5452419Sjulian		1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5552419Sjulian		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
5652419Sjulian	};
5752419Sjulian
5852419Sjulianipsd_t	*iphits[NPORTS];
5952419Sjulianint	pkts;
6052419Sjulian
6152419Sjulian
6252752Sjulianint	ipcmp(sh1, sh2)
6352752Sjuliansdhit_t	*sh1, *sh2;
6452752Sjulian{
6552752Sjulian	return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr;
6652752Sjulian}
6752752Sjulian
6852752Sjulian
6952752Sjulianint	ssipcmp(sh1, sh2)
7052419Sjulianipss_t	*sh1, *sh2;
7153997Sarchie{
7253997Sarchie	return sh1->ss_ip.s_addr - sh2->ss_ip.s_addr;
7353997Sarchie}
7453997Sarchie
7553997Sarchie
7653997Sarchieint countpbits(num)
7753997Sarchieu_long	num;
7853997Sarchie{
7953997Sarchie	int	i, j;
8053997Sarchie
8153997Sarchie	for (i = 1, j = 0; i; i <<= 1)
8253997Sarchie		if (num & i)
8353997Sarchie			j++;
8453997Sarchie	return j;
8553997Sarchie}
8653997Sarchie
8753997Sarchie
8853997Sarchie/*
8953997Sarchie * Check to see if we've already received a packet from this host for this
9053997Sarchie * port.
9153997Sarchie */
9253997Sarchieint	findhit(ihp, src, dport)
9353997Sarchieipsd_t	*ihp;
9453997Sarchiestruct	in_addr	src;
9553997Sarchieu_short	dport;
9653997Sarchie{
9753997Sarchie	int	i, j, k;
9852419Sjulian	sdhit_t	*sh;
9952419Sjulian
10052419Sjulian	sh = NULL;
10152419Sjulian
10252419Sjulian	if (ihp->sd_sz == 4) {
10352419Sjulian		for (i = 0, sh = ihp->sd_hit; i < ihp->sd_cnt; i++, sh++)
10452419Sjulian			if (src.s_addr == sh->sh_ip.s_addr)
10552419Sjulian				return 1;
10652419Sjulian	} else {
10752419Sjulian		for (i = ihp->sd_cnt / 2, j = (i / 2) - 1; j >= 0; j--) {
10852419Sjulian			k = ihp->sd_hit[i].sh_ip.s_addr - src.s_addr;
10952419Sjulian			if (!k)
11052419Sjulian				return 1;
11153913Sarchie			else if (k < 0)
11253997Sarchie				i -= j;
11352419Sjulian			else
11452419Sjulian				i += j;
11552419Sjulian		}
11652419Sjulian	}
11752419Sjulian	return 0;
11852419Sjulian}
11952419Sjulian
12052419Sjulian
12152419Sjulian/*
12252419Sjulian * Search for port number amongst the sorted array of targets we're
12352419Sjulian * interested in.
12452419Sjulian */
12552419Sjulianint	detect(srcip, dport, date)
12652419Sjulianstruct	in_addr	srcip;
12752419Sjulianu_short	dport;
12852419Sjuliantime_t	date;
12952419Sjulian{
13052419Sjulian	ipsd_t	*ihp;
13152419Sjulian	sdhit_t	*sh;
13252419Sjulian	int	i, j, k;
13352419Sjulian
13452419Sjulian	for (i = 10, j = 4; j >= 0; j--) {
13552419Sjulian		k = dport - defports[i];
13652419Sjulian		if (!k) {
13752419Sjulian			ihp = iphits[i];
13852419Sjulian			if (findhit(ihp, srcip, dport))
13952419Sjulian				return 0;
14052419Sjulian			sh = ihp->sd_hit + ihp->sd_cnt;
14152419Sjulian			sh->sh_date = date;
14252419Sjulian			sh->sh_ip = srcip;
14352419Sjulian			if (++ihp->sd_cnt == ihp->sd_sz)
14452419Sjulian			{
14552419Sjulian				ihp->sd_sz += 8;
14652419Sjulian				sh = realloc(sh, ihp->sd_sz * sizeof(*sh));
14752419Sjulian				ihp->sd_hit = sh;
14852419Sjulian			}
14952419Sjulian			qsort(sh, ihp->sd_cnt, sizeof(*sh), ipcmp);
15052419Sjulian			return 0;
15152419Sjulian		}
15252419Sjulian		if (k < 0)
15352419Sjulian			i -= j;
15452419Sjulian		else
15552419Sjulian			i += j;
15652419Sjulian	}
15752419Sjulian	return -1;
15852419Sjulian}
15952419Sjulian
16052419Sjulian
16152419Sjulian/*
16252419Sjulian * Allocate initial storage for hosts
16352419Sjulian */
16452419Sjuliansetuphits()
16552419Sjulian{
16652419Sjulian	int	i;
16752419Sjulian
16852419Sjulian	for (i = 0; i < NPORTS; i++) {
16952419Sjulian		if (iphits[i]) {
17052419Sjulian			if (iphits[i]->sd_hit)
17152419Sjulian				free(iphits[i]->sd_hit);
17252419Sjulian			free(iphits[i]);
17352419Sjulian		}
17452419Sjulian		iphits[i] = (ipsd_t *)malloc(sizeof(ipsd_t));
17552419Sjulian		iphits[i]->sd_port = defports[i];
17652419Sjulian		iphits[i]->sd_cnt = 0;
17752419Sjulian		iphits[i]->sd_sz = 4;
17852419Sjulian		iphits[i]->sd_hit = (sdhit_t *)malloc(sizeof(sdhit_t) * 4);
17952419Sjulian	}
18052419Sjulian}
18152419Sjulian
18252419Sjulian
18352419Sjulian/*
18452419Sjulian * Write statistics out to a file
18552419Sjulian */
18652419Sjulianaddfile(file)
18752419Sjulianchar	*file;
18852419Sjulian{
18952419Sjulian	ipsd_t	ipsd, *ips = &ipsd;
19052419Sjulian	sdhit_t	hit, *hp;
19152419Sjulian	char	fname[32];
19252419Sjulian	int	i, fd, sz;
19352419Sjulian
19452419Sjulian	if ((fd = open(file, O_RDONLY)) == -1) {
19552419Sjulian		perror("open");
19652419Sjulian		return;
19752419Sjulian	}
19852419Sjulian
19952419Sjulian	printf("opened %s\n", file);
20052419Sjulian	do {
20152419Sjulian		if (read(fd, ips, sizeof(*ips)) != sizeof(*ips))
20252419Sjulian			break;
20352419Sjulian		sz = ips->sd_sz * sizeof(*hp);
20452419Sjulian		hp = (sdhit_t *)malloc(sz);
20552419Sjulian		if (read(fd, hp, sz) != sz)
20652419Sjulian			break;
20752816Sarchie		for (i = 0; i < ips->sd_cnt; i++)
20852816Sarchie			detect(hp[i].sh_ip, ips->sd_port, hp[i].sh_date);
20953648Sarchie	} while (1);
21052816Sarchie	(void) close(fd);
21152419Sjulian}
21252816Sarchie
21352419Sjulian
21452816Sarchiereadfiles(dir)
21552816Sarchiechar *dir;
21652816Sarchie{
21752816Sarchie	struct	direct	**d;
21852419Sjulian	int	i, j;
21952419Sjulian
22052419Sjulian	d = NULL;
22152419Sjulian	i = scandir(dir, &d, NULL, NULL);
22252419Sjulian
22352419Sjulian	for (j = 0; j < i; j++) {
22452419Sjulian		if (strncmp(d[j]->d_name, "ipsd-hits.", 10))
22552419Sjulian			continue;
22652419Sjulian		addfile(d[j]->d_name);
22752419Sjulian	}
22852419Sjulian}
22952419Sjulian
23052419Sjulian
23152419Sjulianvoid printreport(ss, num)
23252419Sjulianipss_t	*ss;
23352419Sjulianint	num;
23452419Sjulian{
23552419Sjulian	struct	in_addr	ip;
23652419Sjulian	ipss_t	*sp;
23752419Sjulian	int	i, j, mask;
23852419Sjulian	u_long	ports;
23952419Sjulian
24052419Sjulian	printf("Hosts detected: %d\n", num);
24152419Sjulian	if (!num)
24252419Sjulian		return;
24352419Sjulian	for (i = 0; i < num; i++)
24452419Sjulian		printf("%s %d %d\n", inet_ntoa(ss[i].ss_ip), ss[i].ss_hits,
24552419Sjulian			countpbits(ss[i].ss_ports));
24652419Sjulian
24752419Sjulian	printf("--------------------------\n");
24852419Sjulian	for (mask = 0xfffffffe, j = 32; j; j--, mask <<= 1) {
24952419Sjulian		ip.s_addr = ss[0].ss_ip.s_addr & mask;
25052419Sjulian		ports = ss[0].ss_ports;
25152419Sjulian		for (i = 1; i < num; i++) {
25252419Sjulian			sp = ss + i;
25352419Sjulian			if (ip.s_addr != (sp->ss_ip.s_addr & mask)) {
25452419Sjulian				printf("Netmask: 0x%08x\n", mask);
25552419Sjulian				printf("%s %d\n", inet_ntoa(ip),
25652419Sjulian					countpbits(ports));
25752419Sjulian				ip.s_addr = sp->ss_ip.s_addr & mask;
25852419Sjulian				ports = 0;
25952419Sjulian			}
26052419Sjulian			ports |= sp->ss_ports;
26152419Sjulian		}
26252419Sjulian		if (ports) {
26352419Sjulian			printf("Netmask: 0x%08x\n", mask);
26452419Sjulian			printf("%s %d\n", inet_ntoa(ip), countpbits(ports));
26552419Sjulian		}
26652419Sjulian	}
26752419Sjulian}
26852419Sjulian
26952419Sjulian
27052419Sjuliancollectips()
27152419Sjulian{
27252419Sjulian	ipsd_t	*ips;
27352419Sjulian	ipss_t	*ss;
27452419Sjulian	int	i, num, nip, in, j, k;
27552419Sjulian
27652419Sjulian	for (i = 0; i < NPORTS; i++)
27752419Sjulian		nip += iphits[i]->sd_cnt;
27852419Sjulian
27952419Sjulian	ss = (ipss_t *)malloc(sizeof(ipss_t) * nip);
28052419Sjulian
28152419Sjulian	for (in = 0, i = 0, num = 0; i < NPORTS; i++) {
28252419Sjulian		ips = iphits[i];
28352419Sjulian		for (j = 0; j < ips->sd_cnt; j++) {
28452419Sjulian			for (k = 0; k < num; k++)
28552419Sjulian				if (!bcmp(&ss[k].ss_ip, &ips->sd_hit[j].sh_ip,
28652419Sjulian					  sizeof(struct in_addr))) {
28752419Sjulian					ss[k].ss_hits += pweights[i];
28852419Sjulian					ss[k].ss_ports |= (1 << i);
28952419Sjulian					break;
29052419Sjulian				}
29152419Sjulian			if (k == num) {
29252419Sjulian				ss[num].ss_ip = ips->sd_hit[j].sh_ip;
29352419Sjulian				ss[num].ss_hits = pweights[i];
29452419Sjulian				ss[k].ss_ports |= (1 << i);
29552419Sjulian				num++;
29652419Sjulian			}
29752419Sjulian		}
29852419Sjulian	}
29952419Sjulian
30052419Sjulian	qsort(ss, num, sizeof(*ss), ssipcmp);
30152419Sjulian
30252419Sjulian	printreport(ss, num);
30352419Sjulian}
30452419Sjulian
30552419Sjulian
30652419Sjulianmain(argc, argv)
30752419Sjulianint	argc;
30852419Sjulianchar	*argv[];
30952419Sjulian{
31052419Sjulian	char	c, *name =  argv[0], *dir = NULL;
31152419Sjulian	int	fd;
31252419Sjulian
31352419Sjulian	setuphits();
31452419Sjulian	dir = dir ? dir : ".";
31552419Sjulian	readfiles(dir);
31652419Sjulian	collectips();
31752419Sjulian}
31852419Sjulian