summaryrefslogtreecommitdiffstats
path: root/ipsd/ipsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipsd/ipsd.c')
-rw-r--r--ipsd/ipsd.c294
1 files changed, 294 insertions, 0 deletions
diff --git a/ipsd/ipsd.c b/ipsd/ipsd.c
new file mode 100644
index 0000000..51d0a14
--- /dev/null
+++ b/ipsd/ipsd.c
@@ -0,0 +1,294 @@
+/*
+ * (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 <stdlib.h>
+#include <netdb.h>
+#include <string.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[] = "@(#)ipsd.c 1.3 12/3/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipsd.c,v 2.2 2001/06/09 17:09:25 darrenr Exp $";
+#endif
+
+extern char *optarg;
+extern int optind;
+
+#ifdef linux
+char default_device[] = "eth0";
+#else
+# ifdef sun
+char default_device[] = "le0";
+# else
+# ifdef ultrix
+char default_device[] = "ln0";
+# else
+char default_device[] = "lan0";
+# endif
+# endif
+#endif
+
+#define NPORTS 21
+
+u_short defports[NPORTS] = {
+ 7, 9, 20, 21, 23, 25, 53, 69, 79, 111,
+ 123, 161, 162, 512, 513, 514, 515, 520, 540, 6000, 0
+ };
+
+ipsd_t *iphits[NPORTS];
+int writes = 0;
+
+
+int ipcmp(sh1, sh2)
+sdhit_t *sh1, *sh2;
+{
+ return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr;
+}
+
+
+/*
+ * 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(ip, tcp)
+ip_t *ip;
+tcphdr_t *tcp;
+{
+ ipsd_t *ihp;
+ sdhit_t *sh;
+ int i, j, k;
+
+ for (i = 10, j = 4; j >= 0; j--) {
+ k = tcp->th_dport - defports[i];
+ if (!k) {
+ ihp = iphits[i];
+ if (findhit(ihp, ip->ip_src, tcp->th_dport))
+ return 0;
+ sh = ihp->sd_hit + ihp->sd_cnt;
+ sh->sh_date = time(NULL);
+ sh->sh_ip.s_addr = ip->ip_src.s_addr;
+ 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);
+ }
+}
+
+
+/*
+ * cleanup exits
+ */
+waiter()
+{
+ wait(0);
+}
+
+
+/*
+ * Write statistics out to a file
+ */
+writestats(nwrites)
+int nwrites;
+{
+ ipsd_t **ipsd, *ips;
+ char fname[32];
+ int i, fd;
+
+ (void) sprintf(fname, "/var/log/ipsd/ipsd-hits.%d", nwrites);
+ fd = open(fname, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0644);
+ for (i = 0, ipsd = iphits; i < NPORTS; i++, ipsd++) {
+ ips = *ipsd;
+ if (ips->sd_cnt) {
+ write(fd, ips, sizeof(ipsd_t));
+ write(fd, ips->sd_hit, sizeof(sdhit_t) * ips->sd_sz);
+ }
+ }
+ (void) close(fd);
+ exit(0);
+}
+
+
+void writenow()
+{
+ signal(SIGCHLD, waiter);
+ switch (fork())
+ {
+ case 0 :
+ writestats(writes);
+ exit(0);
+ case -1 :
+ perror("vfork");
+ break;
+ default :
+ writes++;
+ setuphits();
+ break;
+ }
+}
+
+
+void usage(prog)
+char *prog;
+{
+ fprintf(stderr, "Usage: %s [-d device]\n", prog);
+ exit(1);
+}
+
+
+void detecthits(fd, writecount)
+int fd, writecount;
+{
+ struct in_addr ip;
+ int hits = 0;
+
+ while (1) {
+ hits += readloop(fd, ip);
+ if (hits > writecount) {
+ writenow();
+ hits = 0;
+ }
+ }
+}
+
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ char *name = argv[0], *dev = NULL;
+ int fd, writeafter = 10000, angelic = 0, c;
+
+ while ((c = getopt(argc, argv, "ad:n:")) != -1)
+ switch (c)
+ {
+ case 'a' :
+ angelic = 1;
+ break;
+ case 'd' :
+ dev = optarg;
+ break;
+ case 'n' :
+ writeafter = atoi(optarg);
+ break;
+ default :
+ fprintf(stderr, "Unknown option \"%c\"\n", c);
+ usage(name);
+ }
+
+ bzero(iphits, sizeof(iphits));
+ setuphits();
+
+ if (!dev)
+ dev = default_device;
+ printf("Device: %s\n", dev);
+ fd = initdevice(dev, 60);
+
+ if (!angelic) {
+ switch (fork())
+ {
+ case 0 :
+ (void) close(0);
+ (void) close(1);
+ (void) close(2);
+ (void) setpgrp(0, getpgrp());
+ (void) setsid();
+ break;
+ case -1:
+ perror("fork");
+ exit(-1);
+ default:
+ exit(0);
+ }
+ }
+ signal(SIGUSR1, writenow);
+ detecthits(fd, writeafter);
+}
OpenPOWER on IntegriCloud