ipsdr.c revision 53024
122514Sdarrenr/* 253024Sguido * (C)opyright 1995-1998 Darren Reed. 322514Sdarrenr * 431183Speter * Redistribution and use in source and binary forms are permitted 531183Speter * provided that this notice is preserved and due credit is given 631183Speter * to the original author and the contributors. 722514Sdarrenr * 822514Sdarrenr * The author of this software makes no garuntee about the 922514Sdarrenr * performance of this package or its suitability to fulfill any purpose. 1022514Sdarrenr * 1122514Sdarrenr */ 1222514Sdarrenr#include <stdio.h> 1322514Sdarrenr#include <fcntl.h> 1422514Sdarrenr#include <signal.h> 1522514Sdarrenr#include <malloc.h> 1622514Sdarrenr#include <netdb.h> 1722514Sdarrenr#include <string.h> 1822514Sdarrenr#include <sys/dir.h> 1922514Sdarrenr#include <sys/types.h> 2022514Sdarrenr#include <sys/time.h> 2122514Sdarrenr#include <sys/socket.h> 2222514Sdarrenr#include <netinet/in.h> 2322514Sdarrenr#include <netinet/in_systm.h> 2422514Sdarrenr#include <netinet/ip.h> 2522514Sdarrenr#include <netinet/tcp.h> 2622514Sdarrenr#include <netinet/udp.h> 2722514Sdarrenr#include <netinet/ip_icmp.h> 2822514Sdarrenr#ifndef linux 2922514Sdarrenr#include <netinet/ip_var.h> 3022514Sdarrenr#include <netinet/tcpip.h> 3122514Sdarrenr#endif 3222514Sdarrenr#include "ip_compat.h" 3322514Sdarrenr#ifdef linux 3422514Sdarrenr#include <linux/sockios.h> 3522514Sdarrenr#include "tcpip.h" 3622514Sdarrenr#endif 3722514Sdarrenr#include "ipsd.h" 3822514Sdarrenr 3922514Sdarrenr#ifndef lint 4031183Speterstatic const char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed"; 4153024Sguidostatic const char rcsid[] = "@(#)$Id: ipsdr.c,v 2.1 1999/08/04 17:30:57 darrenr Exp $"; 4222514Sdarrenr#endif 4322514Sdarrenr 4422514Sdarrenrextern char *optarg; 4522514Sdarrenrextern int optind; 4622514Sdarrenr 4722514Sdarrenr#define NPORTS 21 4822514Sdarrenr 4922514Sdarrenru_short defports[NPORTS] = { 5022514Sdarrenr 7, 9, 20, 21, 23, 25, 53, 69, 79, 111, 5122514Sdarrenr 123, 161, 162, 512, 513, 513, 515, 520, 540, 6000, 0 5222514Sdarrenr }; 5322514Sdarrenru_short pweights[NPORTS] = { 5422514Sdarrenr 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5522514Sdarrenr 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 5622514Sdarrenr }; 5722514Sdarrenr 5822514Sdarrenripsd_t *iphits[NPORTS]; 5922514Sdarrenrint pkts; 6022514Sdarrenr 6122514Sdarrenr 6222514Sdarrenrint ipcmp(sh1, sh2) 6322514Sdarrenrsdhit_t *sh1, *sh2; 6422514Sdarrenr{ 6522514Sdarrenr return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr; 6622514Sdarrenr} 6722514Sdarrenr 6822514Sdarrenr 6922514Sdarrenrint ssipcmp(sh1, sh2) 7022514Sdarrenripss_t *sh1, *sh2; 7122514Sdarrenr{ 7222514Sdarrenr return sh1->ss_ip.s_addr - sh2->ss_ip.s_addr; 7322514Sdarrenr} 7422514Sdarrenr 7522514Sdarrenr 7622514Sdarrenrint countpbits(num) 7722514Sdarrenru_long num; 7822514Sdarrenr{ 7922514Sdarrenr int i, j; 8022514Sdarrenr 8122514Sdarrenr for (i = 1, j = 0; i; i <<= 1) 8222514Sdarrenr if (num & i) 8322514Sdarrenr j++; 8422514Sdarrenr return j; 8522514Sdarrenr} 8622514Sdarrenr 8722514Sdarrenr 8822514Sdarrenr/* 8922514Sdarrenr * Check to see if we've already received a packet from this host for this 9022514Sdarrenr * port. 9122514Sdarrenr */ 9222514Sdarrenrint findhit(ihp, src, dport) 9322514Sdarrenripsd_t *ihp; 9422514Sdarrenrstruct in_addr src; 9522514Sdarrenru_short dport; 9622514Sdarrenr{ 9722514Sdarrenr int i, j, k; 9822514Sdarrenr sdhit_t *sh; 9922514Sdarrenr 10022514Sdarrenr sh = NULL; 10122514Sdarrenr 10222514Sdarrenr if (ihp->sd_sz == 4) { 10322514Sdarrenr for (i = 0, sh = ihp->sd_hit; i < ihp->sd_cnt; i++, sh++) 10422514Sdarrenr if (src.s_addr == sh->sh_ip.s_addr) 10522514Sdarrenr return 1; 10622514Sdarrenr } else { 10722514Sdarrenr for (i = ihp->sd_cnt / 2, j = (i / 2) - 1; j >= 0; j--) { 10822514Sdarrenr k = ihp->sd_hit[i].sh_ip.s_addr - src.s_addr; 10922514Sdarrenr if (!k) 11022514Sdarrenr return 1; 11122514Sdarrenr else if (k < 0) 11222514Sdarrenr i -= j; 11322514Sdarrenr else 11422514Sdarrenr i += j; 11522514Sdarrenr } 11622514Sdarrenr } 11722514Sdarrenr return 0; 11822514Sdarrenr} 11922514Sdarrenr 12022514Sdarrenr 12122514Sdarrenr/* 12222514Sdarrenr * Search for port number amongst the sorted array of targets we're 12322514Sdarrenr * interested in. 12422514Sdarrenr */ 12522514Sdarrenrint detect(srcip, dport, date) 12622514Sdarrenrstruct in_addr srcip; 12722514Sdarrenru_short dport; 12822514Sdarrenrtime_t date; 12922514Sdarrenr{ 13022514Sdarrenr ipsd_t *ihp; 13122514Sdarrenr sdhit_t *sh; 13222514Sdarrenr int i, j, k; 13322514Sdarrenr 13422514Sdarrenr for (i = 10, j = 4; j >= 0; j--) { 13522514Sdarrenr k = dport - defports[i]; 13622514Sdarrenr if (!k) { 13722514Sdarrenr ihp = iphits[i]; 13822514Sdarrenr if (findhit(ihp, srcip, dport)) 13922514Sdarrenr return 0; 14022514Sdarrenr sh = ihp->sd_hit + ihp->sd_cnt; 14122514Sdarrenr sh->sh_date = date; 14222514Sdarrenr sh->sh_ip = srcip; 14322514Sdarrenr if (++ihp->sd_cnt == ihp->sd_sz) 14422514Sdarrenr { 14522514Sdarrenr ihp->sd_sz += 8; 14622514Sdarrenr sh = realloc(sh, ihp->sd_sz * sizeof(*sh)); 14722514Sdarrenr ihp->sd_hit = sh; 14822514Sdarrenr } 14922514Sdarrenr qsort(sh, ihp->sd_cnt, sizeof(*sh), ipcmp); 15022514Sdarrenr return 0; 15122514Sdarrenr } 15222514Sdarrenr if (k < 0) 15322514Sdarrenr i -= j; 15422514Sdarrenr else 15522514Sdarrenr i += j; 15622514Sdarrenr } 15722514Sdarrenr return -1; 15822514Sdarrenr} 15922514Sdarrenr 16022514Sdarrenr 16122514Sdarrenr/* 16222514Sdarrenr * Allocate initial storage for hosts 16322514Sdarrenr */ 16422514Sdarrenrsetuphits() 16522514Sdarrenr{ 16622514Sdarrenr int i; 16722514Sdarrenr 16822514Sdarrenr for (i = 0; i < NPORTS; i++) { 16922514Sdarrenr if (iphits[i]) { 17022514Sdarrenr if (iphits[i]->sd_hit) 17122514Sdarrenr free(iphits[i]->sd_hit); 17222514Sdarrenr free(iphits[i]); 17322514Sdarrenr } 17422514Sdarrenr iphits[i] = (ipsd_t *)malloc(sizeof(ipsd_t)); 17522514Sdarrenr iphits[i]->sd_port = defports[i]; 17622514Sdarrenr iphits[i]->sd_cnt = 0; 17722514Sdarrenr iphits[i]->sd_sz = 4; 17822514Sdarrenr iphits[i]->sd_hit = (sdhit_t *)malloc(sizeof(sdhit_t) * 4); 17922514Sdarrenr } 18022514Sdarrenr} 18122514Sdarrenr 18222514Sdarrenr 18322514Sdarrenr/* 18422514Sdarrenr * Write statistics out to a file 18522514Sdarrenr */ 18622514Sdarrenraddfile(file) 18722514Sdarrenrchar *file; 18822514Sdarrenr{ 18922514Sdarrenr ipsd_t ipsd, *ips = &ipsd; 19022514Sdarrenr sdhit_t hit, *hp; 19122514Sdarrenr char fname[32]; 19222514Sdarrenr int i, fd, sz; 19322514Sdarrenr 19422514Sdarrenr if ((fd = open(file, O_RDONLY)) == -1) { 19522514Sdarrenr perror("open"); 19622514Sdarrenr return; 19722514Sdarrenr } 19822514Sdarrenr 19922514Sdarrenr printf("opened %s\n", file); 20022514Sdarrenr do { 20122514Sdarrenr if (read(fd, ips, sizeof(*ips)) != sizeof(*ips)) 20222514Sdarrenr break; 20322514Sdarrenr sz = ips->sd_sz * sizeof(*hp); 20422514Sdarrenr hp = (sdhit_t *)malloc(sz); 20522514Sdarrenr if (read(fd, hp, sz) != sz) 20622514Sdarrenr break; 20722514Sdarrenr for (i = 0; i < ips->sd_cnt; i++) 20822514Sdarrenr detect(hp[i].sh_ip, ips->sd_port, hp[i].sh_date); 20922514Sdarrenr } while (1); 21022514Sdarrenr (void) close(fd); 21122514Sdarrenr} 21222514Sdarrenr 21322514Sdarrenr 21422514Sdarrenrreadfiles(dir) 21522514Sdarrenrchar *dir; 21622514Sdarrenr{ 21722514Sdarrenr struct direct **d; 21822514Sdarrenr int i, j; 21922514Sdarrenr 22022514Sdarrenr d = NULL; 22122514Sdarrenr i = scandir(dir, &d, NULL, NULL); 22222514Sdarrenr 22322514Sdarrenr for (j = 0; j < i; j++) { 22422514Sdarrenr if (strncmp(d[j]->d_name, "ipsd-hits.", 10)) 22522514Sdarrenr continue; 22622514Sdarrenr addfile(d[j]->d_name); 22722514Sdarrenr } 22822514Sdarrenr} 22922514Sdarrenr 23022514Sdarrenr 23122514Sdarrenrvoid printreport(ss, num) 23222514Sdarrenripss_t *ss; 23322514Sdarrenrint num; 23422514Sdarrenr{ 23522514Sdarrenr struct in_addr ip; 23622514Sdarrenr ipss_t *sp; 23722514Sdarrenr int i, j, mask; 23822514Sdarrenr u_long ports; 23922514Sdarrenr 24022514Sdarrenr printf("Hosts detected: %d\n", num); 24122514Sdarrenr if (!num) 24222514Sdarrenr return; 24322514Sdarrenr for (i = 0; i < num; i++) 24422514Sdarrenr printf("%s %d %d\n", inet_ntoa(ss[i].ss_ip), ss[i].ss_hits, 24522514Sdarrenr countpbits(ss[i].ss_ports)); 24622514Sdarrenr 24722514Sdarrenr printf("--------------------------\n"); 24822514Sdarrenr for (mask = 0xfffffffe, j = 32; j; j--, mask <<= 1) { 24922514Sdarrenr ip.s_addr = ss[0].ss_ip.s_addr & mask; 25022514Sdarrenr ports = ss[0].ss_ports; 25122514Sdarrenr for (i = 1; i < num; i++) { 25222514Sdarrenr sp = ss + i; 25322514Sdarrenr if (ip.s_addr != (sp->ss_ip.s_addr & mask)) { 25422514Sdarrenr printf("Netmask: 0x%08x\n", mask); 25522514Sdarrenr printf("%s %d\n", inet_ntoa(ip), 25622514Sdarrenr countpbits(ports)); 25722514Sdarrenr ip.s_addr = sp->ss_ip.s_addr & mask; 25822514Sdarrenr ports = 0; 25922514Sdarrenr } 26022514Sdarrenr ports |= sp->ss_ports; 26122514Sdarrenr } 26222514Sdarrenr if (ports) { 26322514Sdarrenr printf("Netmask: 0x%08x\n", mask); 26422514Sdarrenr printf("%s %d\n", inet_ntoa(ip), countpbits(ports)); 26522514Sdarrenr } 26622514Sdarrenr } 26722514Sdarrenr} 26822514Sdarrenr 26922514Sdarrenr 27022514Sdarrenrcollectips() 27122514Sdarrenr{ 27222514Sdarrenr ipsd_t *ips; 27322514Sdarrenr ipss_t *ss; 27422514Sdarrenr int i, num, nip, in, j, k; 27522514Sdarrenr 27622514Sdarrenr for (i = 0; i < NPORTS; i++) 27722514Sdarrenr nip += iphits[i]->sd_cnt; 27822514Sdarrenr 27922514Sdarrenr ss = (ipss_t *)malloc(sizeof(ipss_t) * nip); 28022514Sdarrenr 28122514Sdarrenr for (in = 0, i = 0, num = 0; i < NPORTS; i++) { 28222514Sdarrenr ips = iphits[i]; 28322514Sdarrenr for (j = 0; j < ips->sd_cnt; j++) { 28422514Sdarrenr for (k = 0; k < num; k++) 28522514Sdarrenr if (!bcmp(&ss[k].ss_ip, &ips->sd_hit[j].sh_ip, 28622514Sdarrenr sizeof(struct in_addr))) { 28722514Sdarrenr ss[k].ss_hits += pweights[i]; 28822514Sdarrenr ss[k].ss_ports |= (1 << i); 28922514Sdarrenr break; 29022514Sdarrenr } 29122514Sdarrenr if (k == num) { 29222514Sdarrenr ss[num].ss_ip = ips->sd_hit[j].sh_ip; 29322514Sdarrenr ss[num].ss_hits = pweights[i]; 29422514Sdarrenr ss[k].ss_ports |= (1 << i); 29522514Sdarrenr num++; 29622514Sdarrenr } 29722514Sdarrenr } 29822514Sdarrenr } 29922514Sdarrenr 30022514Sdarrenr qsort(ss, num, sizeof(*ss), ssipcmp); 30122514Sdarrenr 30222514Sdarrenr printreport(ss, num); 30322514Sdarrenr} 30422514Sdarrenr 30522514Sdarrenr 30622514Sdarrenrmain(argc, argv) 30722514Sdarrenrint argc; 30822514Sdarrenrchar *argv[]; 30922514Sdarrenr{ 31022514Sdarrenr char c, *name = argv[0], *dir = NULL; 31122514Sdarrenr int fd; 31222514Sdarrenr 31322514Sdarrenr setuphits(); 31422514Sdarrenr dir = dir ? dir : "."; 31522514Sdarrenr readfiles(dir); 31622514Sdarrenr collectips(); 31722514Sdarrenr} 318