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