]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ipfilter/ipsd/ipsdr.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ipfilter / ipsd / ipsdr.c
1 /*      $FreeBSD$       */
2
3 /*
4  * (C)opyright 1995-1998 Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  *
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"
35
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$";
39 #endif
40
41 extern  char    *optarg;
42 extern  int     optind;
43
44 #define NPORTS  21
45
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
49         };
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
53         };
54
55 ipsd_t  *iphits[NPORTS];
56 int     pkts;
57
58
59 int     ipcmp(sh1, sh2)
60         sdhit_t *sh1, *sh2;
61 {
62         return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr;
63 }
64
65
66 int     ssipcmp(sh1, sh2)
67         ipss_t  *sh1, *sh2;
68 {
69         return sh1->ss_ip.s_addr - sh2->ss_ip.s_addr;
70 }
71
72
73 int countpbits(num)
74         u_long  num;
75 {
76         int     i, j;
77
78         for (i = 1, j = 0; i; i <<= 1)
79                 if (num & i)
80                         j++;
81         return j;
82 }
83
84
85 /*
86  * Check to see if we've already received a packet from this host for this
87  * port.
88  */
89 int     findhit(ihp, src, dport)
90         ipsd_t  *ihp;
91         struct  in_addr src;
92         u_short dport;
93 {
94         int     i, j, k;
95         sdhit_t *sh;
96
97         sh = NULL;
98
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;
112                 }
113         }
114         return 0;
115 }
116
117
118 /*
119  * Search for port number amongst the sorted array of targets we're
120  * interested in.
121  */
122 int     detect(srcip, dport, date)
123         struct  in_addr srcip;
124         u_short dport;
125         time_t  date;
126 {
127         ipsd_t  *ihp;
128         sdhit_t *sh;
129         int     i, j, k;
130
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)
141                         {
142                                 ihp->sd_sz += 8;
143                                 sh = realloc(sh, ihp->sd_sz * sizeof(*sh));
144                                 ihp->sd_hit = sh;
145                         }
146                         qsort(sh, ihp->sd_cnt, sizeof(*sh), ipcmp);
147                         return 0;
148                 }
149                 if (k < 0)
150                         i -= j;
151                 else
152                         i += j;
153         }
154         return -1;
155 }
156
157
158 /*
159  * Allocate initial storage for hosts
160  */
161 setuphits()
162 {
163         int     i;
164
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]);
170                 }
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);
176         }
177 }
178
179
180 /*
181  * Write statistics out to a file
182  */
183 addfile(file)
184         char    *file;
185 {
186         ipsd_t  ipsd, *ips = &ipsd;
187         sdhit_t hit, *hp;
188         char    fname[32];
189         int     i, fd, sz;
190
191         if ((fd = open(file, O_RDONLY)) == -1) {
192                 perror("open");
193                 return;
194         }
195
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);
208 }
209
210
211 readfiles(dir)
212         char *dir;
213 {
214         struct  direct  **d;
215         int     i, j;
216
217         d = NULL;
218         i = scandir(dir, &d, NULL, NULL);
219
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);
224         }
225 }
226
227
228 void printreport(ss, num)
229         ipss_t  *ss;
230         int     num;
231 {
232         struct  in_addr ip;
233         ipss_t  *sp;
234         int     i, j, mask;
235         u_long  ports;
236
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));
243
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;
256                         }
257                         ports |= sp->ss_ports;
258                 }
259                 if (ports) {
260                         printf("Netmask: 0x%08x\n", mask);
261                         printf("%s %d\n", inet_ntoa(ip), countpbits(ports));
262                 }
263         }
264 }
265
266
267 collectips()
268 {
269         ipsd_t  *ips;
270         ipss_t  *ss;
271         int     i, num, nip, in, j, k;
272
273         for (i = 0; i < NPORTS; i++)
274                 nip += iphits[i]->sd_cnt;
275
276         ss = (ipss_t *)malloc(sizeof(ipss_t) * nip);
277
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;
287                                 }
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++;
293                         }
294                 }
295         }
296
297         qsort(ss, num, sizeof(*ss), ssipcmp);
298
299         printreport(ss, num);
300 }
301
302
303 main(argc, argv)
304         int     argc;
305         char    *argv[];
306 {
307         char    c, *name =  argv[0], *dir = NULL;
308         int     fd;
309
310         setuphits();
311         dir = dir ? dir : ".";
312         readfiles(dir);
313         collectips();
314 }