summaryrefslogtreecommitdiffstats
path: root/ipsd/ipsdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipsd/ipsdr.c')
-rw-r--r--ipsd/ipsdr.c312
1 files changed, 312 insertions, 0 deletions
diff --git a/ipsd/ipsdr.c b/ipsd/ipsdr.c
new file mode 100644
index 0000000..af007e4
--- /dev/null
+++ b/ipsd/ipsdr.c
@@ -0,0 +1,312 @@
+/*
+ * (C)opyright 1995-1998 Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ */
+#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 const char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipsdr.c,v 2.2 2001/06/09 17:09:25 darrenr Exp $";
+#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();
+}
OpenPOWER on IntegriCloud