Sync usage with man page.
[netbsd-mini2440.git] / dist / ipf / ipsd / ipsdr.c
blob4689cbad83e7ec59be1ed753f88cada63e290a21
1 /* $NetBSD$ */
3 /*
4 * (C)opyright 1995-1998 Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
8 */
9 #include <stdio.h>
10 #include <fcntl.h>
11 #include <signal.h>
12 #include <malloc.h>
13 #include <netdb.h>
14 #include <string.h>
15 #include <sys/dir.h>
16 #include <sys/types.h>
17 #include <sys/time.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <netinet/in_systm.h>
21 #include <netinet/ip.h>
22 #include <netinet/tcp.h>
23 #include <netinet/udp.h>
24 #include <netinet/ip_icmp.h>
25 #ifndef linux
26 #include <netinet/ip_var.h>
27 #include <netinet/tcpip.h>
28 #endif
29 #include "ip_compat.h"
30 #ifdef linux
31 #include <linux/sockios.h>
32 #include "tcpip.h"
33 #endif
34 #include "ipsd.h"
36 #ifndef lint
37 static const char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed";
38 static const char rcsid[] = "@(#)Id: ipsdr.c,v 2.2 2001/06/09 17:09:25 darrenr Exp";
39 #endif
41 extern char *optarg;
42 extern int optind;
44 #define NPORTS 21
46 u_short defports[NPORTS] = {
47 7, 9, 20, 21, 23, 25, 53, 69, 79, 111,
48 123, 161, 162, 512, 513, 513, 515, 520, 540, 6000, 0
50 u_short pweights[NPORTS] = {
51 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
52 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
55 ipsd_t *iphits[NPORTS];
56 int pkts;
59 int ipcmp(sh1, sh2)
60 sdhit_t *sh1, *sh2;
62 return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr;
66 int ssipcmp(sh1, sh2)
67 ipss_t *sh1, *sh2;
69 return sh1->ss_ip.s_addr - sh2->ss_ip.s_addr;
73 int countpbits(num)
74 u_long num;
76 int i, j;
78 for (i = 1, j = 0; i; i <<= 1)
79 if (num & i)
80 j++;
81 return j;
86 * Check to see if we've already received a packet from this host for this
87 * port.
89 int findhit(ihp, src, dport)
90 ipsd_t *ihp;
91 struct in_addr src;
92 u_short dport;
94 int i, j, k;
95 sdhit_t *sh;
97 sh = NULL;
99 if (ihp->sd_sz == 4) {
100 for (i = 0, sh = ihp->sd_hit; i < ihp->sd_cnt; i++, sh++)
101 if (src.s_addr == sh->sh_ip.s_addr)
102 return 1;
103 } else {
104 for (i = ihp->sd_cnt / 2, j = (i / 2) - 1; j >= 0; j--) {
105 k = ihp->sd_hit[i].sh_ip.s_addr - src.s_addr;
106 if (!k)
107 return 1;
108 else if (k < 0)
109 i -= j;
110 else
111 i += j;
114 return 0;
119 * Search for port number amongst the sorted array of targets we're
120 * interested in.
122 int detect(srcip, dport, date)
123 struct in_addr srcip;
124 u_short dport;
125 time_t date;
127 ipsd_t *ihp;
128 sdhit_t *sh;
129 int i, j, k;
131 for (i = 10, j = 4; j >= 0; j--) {
132 k = dport - defports[i];
133 if (!k) {
134 ihp = iphits[i];
135 if (findhit(ihp, srcip, dport))
136 return 0;
137 sh = ihp->sd_hit + ihp->sd_cnt;
138 sh->sh_date = date;
139 sh->sh_ip = srcip;
140 if (++ihp->sd_cnt == ihp->sd_sz)
142 ihp->sd_sz += 8;
143 sh = realloc(sh, ihp->sd_sz * sizeof(*sh));
144 ihp->sd_hit = sh;
146 qsort(sh, ihp->sd_cnt, sizeof(*sh), ipcmp);
147 return 0;
149 if (k < 0)
150 i -= j;
151 else
152 i += j;
154 return -1;
159 * Allocate initial storage for hosts
161 setuphits()
163 int i;
165 for (i = 0; i < NPORTS; i++) {
166 if (iphits[i]) {
167 if (iphits[i]->sd_hit)
168 free(iphits[i]->sd_hit);
169 free(iphits[i]);
171 iphits[i] = (ipsd_t *)malloc(sizeof(ipsd_t));
172 iphits[i]->sd_port = defports[i];
173 iphits[i]->sd_cnt = 0;
174 iphits[i]->sd_sz = 4;
175 iphits[i]->sd_hit = (sdhit_t *)malloc(sizeof(sdhit_t) * 4);
181 * Write statistics out to a file
183 addfile(file)
184 char *file;
186 ipsd_t ipsd, *ips = &ipsd;
187 sdhit_t hit, *hp;
188 char fname[32];
189 int i, fd, sz;
191 if ((fd = open(file, O_RDONLY)) == -1) {
192 perror("open");
193 return;
196 printf("opened %s\n", file);
197 do {
198 if (read(fd, ips, sizeof(*ips)) != sizeof(*ips))
199 break;
200 sz = ips->sd_sz * sizeof(*hp);
201 hp = (sdhit_t *)malloc(sz);
202 if (read(fd, hp, sz) != sz)
203 break;
204 for (i = 0; i < ips->sd_cnt; i++)
205 detect(hp[i].sh_ip, ips->sd_port, hp[i].sh_date);
206 } while (1);
207 (void) close(fd);
211 readfiles(dir)
212 char *dir;
214 struct direct **d;
215 int i, j;
217 d = NULL;
218 i = scandir(dir, &d, NULL, NULL);
220 for (j = 0; j < i; j++) {
221 if (strncmp(d[j]->d_name, "ipsd-hits.", 10))
222 continue;
223 addfile(d[j]->d_name);
228 void printreport(ss, num)
229 ipss_t *ss;
230 int num;
232 struct in_addr ip;
233 ipss_t *sp;
234 int i, j, mask;
235 u_long ports;
237 printf("Hosts detected: %d\n", num);
238 if (!num)
239 return;
240 for (i = 0; i < num; i++)
241 printf("%s %d %d\n", inet_ntoa(ss[i].ss_ip), ss[i].ss_hits,
242 countpbits(ss[i].ss_ports));
244 printf("--------------------------\n");
245 for (mask = 0xfffffffe, j = 32; j; j--, mask <<= 1) {
246 ip.s_addr = ss[0].ss_ip.s_addr & mask;
247 ports = ss[0].ss_ports;
248 for (i = 1; i < num; i++) {
249 sp = ss + i;
250 if (ip.s_addr != (sp->ss_ip.s_addr & mask)) {
251 printf("Netmask: 0x%08x\n", mask);
252 printf("%s %d\n", inet_ntoa(ip),
253 countpbits(ports));
254 ip.s_addr = sp->ss_ip.s_addr & mask;
255 ports = 0;
257 ports |= sp->ss_ports;
259 if (ports) {
260 printf("Netmask: 0x%08x\n", mask);
261 printf("%s %d\n", inet_ntoa(ip), countpbits(ports));
267 collectips()
269 ipsd_t *ips;
270 ipss_t *ss;
271 int i, num, nip, in, j, k;
273 for (i = 0; i < NPORTS; i++)
274 nip += iphits[i]->sd_cnt;
276 ss = (ipss_t *)malloc(sizeof(ipss_t) * nip);
278 for (in = 0, i = 0, num = 0; i < NPORTS; i++) {
279 ips = iphits[i];
280 for (j = 0; j < ips->sd_cnt; j++) {
281 for (k = 0; k < num; k++)
282 if (!bcmp(&ss[k].ss_ip, &ips->sd_hit[j].sh_ip,
283 sizeof(struct in_addr))) {
284 ss[k].ss_hits += pweights[i];
285 ss[k].ss_ports |= (1 << i);
286 break;
288 if (k == num) {
289 ss[num].ss_ip = ips->sd_hit[j].sh_ip;
290 ss[num].ss_hits = pweights[i];
291 ss[k].ss_ports |= (1 << i);
292 num++;
297 qsort(ss, num, sizeof(*ss), ssipcmp);
299 printreport(ss, num);
303 main(argc, argv)
304 int argc;
305 char *argv[];
307 char c, *name = argv[0], *dir = NULL;
308 int fd;
310 setuphits();
311 dir = dir ? dir : ".";
312 readfiles(dir);
313 collectips();