Annotation of embedaddon/ipguard/packet.c, revision 1.1.1.1.2.1
1.1 misho 1: /* packet.c
2: *
3: * Copyright (c) 2010 SeaD <sead at deep.perm.ru>
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17: * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24: * SUCH DAMAGE.
25: *
26: * $Id: packet.c,v 1.19 2010/07/12 03:46:36 sead Exp $
27: *
28: */
29:
30: #include <sys/types.h>
31: #include <sys/socket.h>
32: #include <netinet/in.h>
33:
34: #ifdef __OpenBSD__
35: # include <net/if.h>
36: # include <net/if_arp.h>
37: #endif /* __OpenBSD__ */
38:
39: #ifdef __linux__
40: # include <time.h>
41: # include <netinet/ether.h>
42: #else /* __linux__ */
43: # include <netinet/if_ether.h>
44: #endif /* __linux__ */
45:
46: #include <pcap.h>
47:
48: #ifndef __GLIBC__
49: # define __GLIBC__ 1
50: # include <libnet.h>
51: # undef __GLIBC__
52: #else /* __GLIBC__ */
53: # include <libnet.h>
54: #endif /* __GLIBC__ */
55:
56: #include "ipguard.h"
57:
58: static struct ether_addr se_addr, te_addr, sh_addr, th_addr, bh_addr, zh_addr,
59: fake_addr, pfake_addr;
60: static struct in_addr sp_addr, tp_addr, zp_addr;
61:
62: static pcap_t *pcap = NULL;
63: static libnet_t *ln = NULL;
64: static char ifname[IFNAMSIZ];
65:
66: static struct pair_t {
67: struct ether_addr mac;
68: struct in_addr ip;
69: struct in_addr mask;
70: } *pairs = NULL;
71: static int pair_num = 0;
72:
73: static struct buffer_t {
74: struct ether_addr mac;
75: struct in_addr ip;
76: int num;
77: time_t last;
78: } *buffer = NULL;
79:
80: void buffer_init(void) {
81: if ((buffer = (struct buffer_t *) malloc(sizeof(struct buffer_t) * buffer_num)) == NULL) {
82: log_str(ERROR, "malloc():", strerror(errno));
83: exit(EXIT_FAILURE);
84: }
85: }
86:
87: void buffer_destroy(void) {
88: free(buffer);
89: }
90:
91: void buffer_add(void) {
92: struct buffer_t *p = NULL, *pn = NULL;
93: register int n;
94:
95: for (n = 0, p = buffer; n < buffer_num; n++, p++)
96: if (!memcmp(&sh_addr, &p->mac, sizeof(struct ether_addr))) {
97: memcpy(&p->ip, &sp_addr, sizeof(struct in_addr));
98: p->num++; p->last = time(&p->last); return;
99: }
100:
101: for (n = 0, p = buffer, pn = p + 1; n < buffer_num - 1; n++, p++, pn++)
102: memcpy(p, pn, sizeof(struct buffer_t));
103: memcpy(&p->mac, &sh_addr, sizeof(struct ether_addr));
104: memcpy(&p->ip, &sp_addr, sizeof(struct in_addr));
105: p->num = 1; p->last = time(&p->last);
106: }
107:
108: void buffer_dump(void) {
109: struct buffer_t *p = NULL;
110: register int n;
111:
112: snprintf(s, 64, "Bad MAC-IP buffer (%d pairs)", buffer_num);
113: log_str(INFO, s, "");
114:
115: for (n = 0, p = buffer + buffer_num - 1; n < buffer_num && p->num > 0; n++, p--) {
116: snprintf(s, 64, "%03d %s %-15s %2d %lu",
117: n+1, ether_ntoa(&p->mac), inet_ntoa(p->ip), p->num, (unsigned long) p->last);
118: log_str(INFO, "dump:", s);
119: }
120: }
121:
122: void buffer_dump2ethers(void) {
123: struct buffer_t *p = NULL;
124: register int n;
125:
126: for (n = 0, p = buffer + buffer_num - 1; n < buffer_num && p->num > 0; n++, p--) {
127: snprintf(s, 64, "%-17s %-15s", ether_ntoa(&p->mac), inet_ntoa(p->ip));
128: log_str(INFO, s, "");
129: }
130: }
131:
132: uint32_t bit_2mask(int bit) {
133: uint32_t mask = 0;
134: register int n;
135:
136: for (n = 0; n < bit; n++) { mask >>= 1; mask |= 0x80000000; }
137:
138: return mask;
139: }
140:
141: void pair_init(void) {
142: struct libnet_ether_addr *ha = NULL;
143: uint32_t pa = 0, mask;
144: int bit = 0;
145:
146: if ((pairs = (struct pair_t *) malloc(sizeof(struct pair_t))) == NULL) {
147: log_str(ERROR, "malloc():", strerror(errno));
148: exit(EXIT_FAILURE);
149: }
150: if ((ha = libnet_get_hwaddr(ln)) == NULL) {
151: log_str(ERROR, libnet_geterror(ln), "");
152: exit(EXIT_FAILURE);
153: }
154: if (!(pa = libnet_get_ipaddr4(ln))) {
155: log_str(ERROR, libnet_geterror(ln), "");
156: exit(EXIT_FAILURE);
157: }
158: mask = htonl(bit_2mask(bit));
159: if (!nofirst) {
160: memcpy(&pairs->mac, ha, sizeof(struct ether_addr));
161: memcpy(&pairs->ip, &pa, sizeof(struct in_addr));
162: memcpy(&pairs->mask, &mask, sizeof(struct in_addr));
163: pair_num++;
164:
165: if (debug > 1)
166: fprintf(stderr, "PAIR ADD FIRST: %s %s %u\n",
167: ether_ntoa(&pairs->mac), inet_ntoa(pairs->ip), bit);
168: }
169: }
170:
171: void pair_destroy(void) {
172: free(pairs);
173: pair_num = 0;
174: }
175:
176: void pair_add(char *mac, char *ip) {
177: struct pair_t *p = NULL;
178: struct ether_addr *fmac = NULL;
179: uint32_t fip, mask;
180: char *m;
181: int bit;
182:
183: if ((m = strchr(ip, '/'))) {
184: *m++ = '\0'; bit = atoi(m);
185: if (!bit || (bit < 0) || (bit > 32)) {
186: log_str(NOTICE, "Wrong mask", m); return;
187: }
188: if (debug > 2) fprintf(stderr, "NETWORK MASK: %s %u\n", ip, bit);
189: } else bit = 0;
190:
191: if ((fmac = ether_aton(mac)) == NULL) {
192: if (verbose) log_str(WARNING, "Invalid MAC:", mac); return;
193: }
194: if ((fip = libnet_name2addr4(ln, ip, LIBNET_RESOLVE)) == -1) {
195: if (verbose) log_str(WARNING, "Host unknown:", ip); return;
196: }
197:
198: mask = htonl(bit_2mask(bit));
199: if (mask) fip &= mask;
200:
201: if ((pairs = realloc(pairs, ++pair_num * sizeof(struct pair_t))) == NULL) {
202: log_str(ERROR, "realloc():", strerror(errno));
203: exit(EXIT_FAILURE);
204: }
205: p = pairs + pair_num - 1;
206:
207: memcpy(&p->mac, fmac, sizeof(struct ether_addr));
208: memcpy(&p->ip, &fip, sizeof(struct in_addr));
209: memcpy(&p->mask, &mask, sizeof(struct in_addr));
210:
211: if (debug > 1)
212: fprintf(stderr, "PAIR ADD: %s %s %u\n",
213: ether_ntoa(&p->mac), inet_ntoa(p->ip), bit);
214: }
215:
216: void pair_dump(void) {
217: struct pair_t *p = pairs;
218: char ntoasw[16];
219: register int n;
220:
221: snprintf(s, 64, "Current MAC-IP table (%d pairs)", pair_num);
222: log_str(INFO, s, "");
223:
224: for (n = 0; n < pair_num; n++, p++) {
225: strncpy(ntoasw, inet_ntoa(p->mask), 16);
226: snprintf(s, 64, "%s %s %s",
227: ether_ntoa(&p->mac), inet_ntoa(p->ip), ntoasw);
228: log_str(INFO, "dump:", s);
229: }
230: }
231:
232: void packet_fmacs(int op) {
233: switch (op) {
234: /* init */
235: case 1: mac_rand(fmac); strncpy(pfmac, fmac, 18); break;
236: /* regenerate */
237: case 2: strncpy(pfmac, fmac, 18); mac_regen(fmac); break;
238: }
239:
240: memcpy(&fake_addr, ether_aton(fmac), sizeof(struct ether_addr));
241: memcpy(&pfake_addr, ether_aton(pfmac), sizeof(struct ether_addr));
242: }
243:
244: void packet_init(char *iface) {
245: struct bpf_program arp_p;
246: char ebuf[PCAP_ERRBUF_SIZE] = "\0";
247:
248: strncpy(ifname, iface, IFNAMSIZ);
249: memset(&bh_addr, 0xff, sizeof(struct ether_addr));
250: memset(&zh_addr, 0x00, sizeof(struct ether_addr));
251: memset(&zp_addr, 0x00, sizeof(struct in_addr));
252: packet_fmacs(1);
253:
254: /* pcap init */
255: if (!(pcap = pcap_open_live(ifname, 100, promisc, 10, ebuf))) {
256: debug = 2; log_str(ERROR, "pcap_open_live():", ebuf);
257: exit(EXIT_FAILURE);
258: }
259: if (strlen(ebuf)) fprintf(stderr, "warning: %s\n", ebuf);
260: if (pcap_compile(pcap, &arp_p, pcapf, 0, -1) == -1) {
261: snprintf(s, 128, "pcap_compile(%s):", pcapf);
262: debug = 2; log_str(ERROR, s, "wrong expression");
263: exit(EXIT_FAILURE);
264: }
265: if (pcap_setfilter(pcap, &arp_p) == -1) {
266: debug = 2; log_str(ERROR, "pcap_setfilter():", "failed");
267: exit(EXIT_FAILURE);
268: }
269:
270: /* libnet init */
271: if (!(ln = libnet_init(LIBNET_LINK_ADV, ifname, ebuf))) {
272: debug = 2; log_str(ERROR, ebuf, "");
273: exit(EXIT_FAILURE);
274: }
275:
276: pair_init();
277: if (buffer_num) buffer_init();
278: ethers_init();
279:
280: snprintf(s, 128, "%s %s %s (%d pairs) fake %s%s",
281: iface, ether_ntoa(&pairs->mac), inet_ntoa(pairs->ip), pair_num, fmac,
282: (read_only ? " RO mode" : ""));
283: log_str(NOTICE, s, "");
284: if (verbose) pair_dump();
285: }
286:
287: void packet_destroy (void) {
288: if (buffer_num) buffer_destroy();
289: pair_destroy();
290: libnet_destroy(ln);
291: pcap_close(pcap);
292: }
293:
294: void packet_send(int op, int num) {
295: register int n;
296:
297: if (libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, 6, 4, op,
298: (u_char *) &sh_addr, (u_char *) &sp_addr,
299: (u_char *) &th_addr, (u_char *) &tp_addr,
300: NULL, 0, ln, 0) == -1) {
301: log_str(ERROR, libnet_geterror(ln), "");
302: exit(EXIT_FAILURE);
303: }
304:
305: if (libnet_build_ethernet(
306: (u_char *) &te_addr, (u_char *) &se_addr,
307: ETHERTYPE_ARP, NULL, 0, ln, 0) == -1) {
308: log_str(ERROR, libnet_geterror(ln), "");
309: exit(EXIT_FAILURE);
310: }
311:
312: if ((n = num)) while (1) {
313: if (debug > 1) {
314: fprintf(stderr, "SEND ARP %u: ", op);
315: fprintf(stderr, "%-17s -> ", ether_ntoa(&se_addr)); fprintf(stderr, "%-17s\n ", ether_ntoa(&te_addr));
316: fprintf(stderr, "sdr %-17s %-15s ", ether_ntoa(&sh_addr), inet_ntoa(sp_addr));
317: fprintf(stderr, "trg %-17s %-15s\n", ether_ntoa(&th_addr), inet_ntoa(tp_addr));
318: }
319: if (!read_only)
320: if (libnet_write(ln) == -1) {
321: log_str(ERROR, libnet_geterror(ln), "");
322: exit_ipguard(EXIT_FAILURE);
323: }
324: if (--n <= 0) break; else usleep(fake_time * 1000);
325: }
326:
327: libnet_clear_packet(ln);
328: }
329:
330: void packet_check(void) {
331: struct pair_t *p = NULL;
332: struct pair_t *se_ch = NULL, *te_ch = NULL, *sp_ch = NULL, *tp_ch = NULL;
333: uint32_t fsip, ftip, fmask, swip;
334: int bsdr = 0;
335: char ntoasw[16];
336: register int n;
337:
338: /* count mismatch MACs between ether and ARP headers */
339: if (memcmp(&se_addr, &sh_addr, sizeof(struct ether_addr))) {
340: if (debug > 1) {
341: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
342: fprintf(stderr, "MISMATCH SOURCE: %-17s %-15s %-15s\n", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
343: }
344: mis++;
345: }
346: /* count non-zero target MAC in ARP who-has */
347: if (memcmp(&zh_addr, &th_addr, sizeof(struct ether_addr))) {
348: if (debug > 1) {
349: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
350: fprintf(stderr, "NON-ZERO TARGET: %-17s %-15s %-15s\n", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
351: }
352: nzh++;
353: }
354: /* count non-bcast target ether MAC */
355: if (memcmp(&bh_addr, &te_addr, sizeof(struct ether_addr))) {
356: if (debug > 1) {
357: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
358: fprintf(stderr, "NON-BCAST WHO-HAS: %-17s %-15s %-15s\n", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
359: }
360: nbe++;
361: }
362:
363: /* return if sdr MAC is ours */
364: if (!memcmp(&se_addr, &pairs->mac, sizeof(struct ether_addr))) {
365: if (debug > 2) fprintf(stderr, "MY MAC PASSED: %s\n", ether_ntoa(&se_addr));
366: mymac++; return;
367: }
368: /* return if sdr MAC is our fake MAC */
369: if (!memcmp(&se_addr, &fake_addr, sizeof(struct ether_addr))) {
370: if (debug > 2) fprintf(stderr, "FAKE MAC PASSED: %s\n", ether_ntoa(&se_addr));
371: fake++; return;
372: }
373: /* return if sdr MAC is previous fake MAC */
374: if (fake_regen)
375: if (!memcmp(&se_addr, &pfake_addr, sizeof(struct ether_addr))) {
376: if (debug > 2) fprintf(stderr, "PRE FAKE MAC PASSED: %s\n", ether_ntoa(&se_addr));
377: pfake++; return;
378: }
379: /* fill weird gratuitous ARP sdr IP 0.0.0.0 (Linux/MacOS/Vista) */
380: if (!memcmp(&sp_addr, &zp_addr, sizeof(struct in_addr))) {
381: if (debug > 2) fprintf(stderr, "WEIRD GRATUITOUS FILL: %s\n", inet_ntoa(tp_addr));
382: memcpy(&sp_addr, &tp_addr, sizeof(struct in_addr));
383: wgrat++;
384: }
385:
386: /* check if IP/MAC is listed */
387: for (n = 0, p = pairs; n < pair_num; n++, p++) {
388: memcpy(&fsip, &sp_addr, sizeof(struct in_addr));
389: memcpy(&ftip, &tp_addr, sizeof(struct in_addr));
390: memcpy(&fmask, &p->mask, sizeof(struct in_addr));
391: if (fmask) { fsip &= fmask; ftip &= fmask; }
392: if (!memcmp(&se_addr, &p->mac, sizeof(struct ether_addr))) {
393: if (!se_ch) se_ch = p;
394: if (!memcmp(&fsip, &p->ip, sizeof(struct in_addr))) se_ch = sp_ch = p;
395: }
396: if (!memcmp(&te_addr, &p->mac, sizeof(struct ether_addr))) {
397: if (!te_ch) te_ch = p;
398: if (!memcmp(&ftip, &p->ip, sizeof(struct in_addr))) te_ch = tp_ch = p;
399: }
400: if (!sp_ch && !memcmp(&fsip, &p->ip, sizeof(struct in_addr))) sp_ch = p;
401: if (!tp_ch && !memcmp(&ftip, &p->ip, sizeof(struct in_addr))) tp_ch = p;
402: }
403:
404: if (debug > 2) {
405: if (se_ch) fprintf(stderr, "MATCH MAC SDR: %-18s -> %-18s\n", ether_ntoa(&se_ch->mac), inet_ntoa(se_ch->ip));
406: else fprintf(stderr, "UNKNOWN MAC SDR: %-18s\n", ether_ntoa(&se_addr));
407: if (te_ch) fprintf(stderr, "MATCH MAC TRG: %-18s -> %-18s\n", ether_ntoa(&te_ch->mac), inet_ntoa(te_ch->ip));
408: else {
409: if (!memcmp(&te_addr, &bh_addr, sizeof(struct ether_addr)))
410: fprintf(stderr, "BCAST MAC TRG: %-18s\n", "ff:ff:ff:ff:ff:ff");
411: else
412: fprintf(stderr, "UNKNOWN MAC TRG: %-18s\n", ether_ntoa(&te_addr));
413: }
414: if (sp_ch) fprintf(stderr, "MATCH IP SDR: %-18s -> %-18s\n", inet_ntoa(sp_ch->ip), ether_ntoa(&sp_ch->mac));
415: else fprintf(stderr, "UNKNOWN IP SDR: %-18s\n", inet_ntoa(sp_addr));
416: if (tp_ch) fprintf(stderr, "MATCH IP TRG: %-18s -> %-18s\n", inet_ntoa(tp_ch->ip), ether_ntoa(&tp_ch->mac));
417: else fprintf(stderr, "UNKNOWN IP TRG: %-18s\n", inet_ntoa(tp_addr));
418: }
419:
420: /* gratuitous ARP packets */
421: if (se_ch && (se_ch == tp_ch) &&
422: !memcmp(&sp_addr, &tp_addr, sizeof(struct in_addr))) {
423: if (debug > 2) fprintf(stderr, "GOOD PASSED: grat\n");
424: grat++; return;
425: }
426:
427: /* wildcard trg MAC 00:00:00:00:00:00 */
428: if (sp_ch && !memcmp(&sp_ch->mac, &zh_addr, sizeof(struct ether_addr))) {
429: if (debug > 2) fprintf(stderr, "GOOD PASSED: zmac\n");
430: zmac++; if (!addr_nosubst) return;
431: }
432: /* wildcard sdr IP 0.0.0.0 */
433: if (se_ch && !memcmp(&se_ch->ip, &zp_addr, sizeof(struct in_addr))) {
434: if (debug > 2) fprintf(stderr, "GOOD PASSED: zip\n");
435: zip++; if (!addr_nosubst) return;
436: }
437:
438: /* correct pair - sdr MAC pos == sdr IP pos and listed trg IP pos or not duplex */
439: if (se_ch && (se_ch == sp_ch) && (tp_ch || !duplex)) {
440: if (debug > 2) fprintf(stderr, "GOOD PASSED: good\n");
441: good++; return;
442: }
443:
444: /* sdr MAC and sdr IP are both not listed - new pair */
445: if (!se_ch && (se_ch == sp_ch)) {
446: if (verbose) {
447: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
448: snprintf(s, 128, "%-17s %-15s %-15s", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
449: log_str(NOTICE, "bnew:", s);
450: }
451: bnew++; bsdr++; if (grant) return;
452: }
453:
454: /* sdr MAC is listed but IP is not */
455: if (se_ch && (se_ch != sp_ch)) {
456: if (verbose) {
457: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
458: snprintf(s, 128, "%-17s %-15s %-15s", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
459: log_str(NOTICE, "bsip:", s);
460: }
461: bsip++; bsdr++;
462: }
463: /* sdr IP is listed but MAC is not */
464: if (sp_ch && (se_ch != sp_ch)) {
465: if (verbose) {
466: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
467: snprintf(s, 128, "%-17s %-15s %-15s", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
468: log_str(NOTICE, "bmac:", s);
469: }
470: bmac++; bsdr++;
471: }
472:
473: /* do not block gratuitous ARP in hidden mode */
474: if (!memcmp(&sp_addr, &tp_addr, sizeof(struct in_addr))) {
475: if (verbose) {
476: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
477: snprintf(s, 128, "%-17s %-15s %-15s", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
478: log_str(NOTICE, "bgrt:", s);
479: }
480: bgrat++; if (hidden) return;
481: }
482:
483: /* if duplex and trg IP is not listed then block */
484: if (!tp_ch) {
485: if (verbose) {
486: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
487: snprintf(s, 128, "%-17s %-15s %-15s", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
488: log_str(NOTICE, "btip:", s);
489: }
490: btip++; if (!bsdr && !duplex) return;
491: }
492:
493: /* add pirate pair to bad buffer */
494: if (bsdr && buffer_num) buffer_add();
495:
496: strncpy(ntoasw, inet_ntoa(tp_addr), 16);
497: snprintf(s, 128, "%-17s %-15s %-15s", ether_ntoa(&sh_addr), inet_ntoa(sp_addr), ntoasw);
498: log_str(NOTICE, "xxxx:", s);
499:
500: /* block pirate
501: eth fake MAC -> pirate MAC
502: sdr fake MAC - target IP
503: trg pirate MAC - pirate IP
504: */
505: memcpy(&te_addr, &se_addr, sizeof(struct ether_addr));
506: memcpy(&se_addr, &fake_addr, sizeof(struct ether_addr));
507: memcpy(&th_addr, &sh_addr, sizeof(struct ether_addr));
508: memcpy(&sh_addr, &fake_addr, sizeof(struct ether_addr));
509: memcpy(&swip, &tp_addr, sizeof(struct in_addr));
510: memcpy(&tp_addr, &sp_addr, sizeof(struct in_addr));
511: memcpy(&sp_addr, &swip, sizeof(struct in_addr));
512: packet_send(ARPOP_REPLY, fake_num);
513:
514: if (bsdr) {
515: /* control headshot
516: eth fake MAC -> pirate MAC
517: sdr fake MAC - pirate IP
518: trg pirate MAC - pirate IP
519: */
520: memcpy(&sp_addr, &tp_addr, sizeof(struct in_addr));
521: packet_send(ARPOP_REPLY, 1);
522: }
523:
524: /* and fix broken ARP caches by broadcast */
525: if (bsdr && fixbc) {
526: memcpy(&te_addr, &bh_addr, sizeof(struct ether_addr));
527: memcpy(&th_addr, &zh_addr, sizeof(struct ether_addr));
528: if (sp_ch) {
529: /* sdr IP is valid
530: eth ethers MAC -> broadcast
531: sdr ethers MAC - ethers IP
532: trg zero MAC - ethers IP
533: */
534: memcpy(&se_addr, &sp_ch->mac, sizeof(struct ether_addr));
535: memcpy(&sh_addr, &sp_ch->mac, sizeof(struct ether_addr));
536: memcpy(&sp_addr, &sp_ch->ip, sizeof(struct in_addr));
537: } else if (se_ch) {
538: /* sdr MAC is valid
539: eth ethers MAC -> broadcast
540: sdr ethers MAC - ethers IP
541: trg zero MAC - ethers IP
542: ** disabled as probably useless **
543: memcpy(&se_addr, &se_ch->mac, sizeof(struct ether_addr));
544: memcpy(&sh_addr, &se_ch->mac, sizeof(struct ether_addr));
545: memcpy(&sp_addr, &se_ch->ip, sizeof(struct in_addr));
546: */
547: } else {
548: /* invalid sender
549: eth fake MAC -> broadcast
550: sdr fake MAC - pirate IP
551: trg zero MAC - pirate IP
552: */
553: memcpy(&se_addr, &fake_addr, sizeof(struct ether_addr));
554: memcpy(&sh_addr, &fake_addr, sizeof(struct ether_addr));
555: }
556: memcpy(&tp_addr, &sp_addr, sizeof(struct in_addr));
557: packet_send(ARPOP_REQUEST, 1);
558: }
559:
560: bad++;
561: if (debug > 2)
562: fprintf(stderr, "STATS: god %-6d new %-6d bmc %-6d bip %-6d btg %-6d all %-6d\n",
563: good+mymac+fake+pfake+grat+wgrat+zmac+zip, bnew, bmac, bsip, btip, all);
564: }
565:
566: void packet_handle(char *blah, struct pcap_pkthdr *blah2, u_char *recv) {
567: struct ether_header *eth_h = NULL;
568: struct ether_arp *arp_h = NULL;
569: int op;
570:
571: sig_catch();
572: if (ethers_update) ethers_stat();
573: if (fake_regen) packet_fmacs(2);
574:
575: eth_h = (struct ether_header *) recv;
576: if (htons(eth_h->ether_type) != ETHERTYPE_ARP) {
577: snprintf(s, 8, "0x%x", eth_h->ether_type);
578: log_str(WARNING, "wrong ethertype:", s); return;
579: }
580:
581: memcpy(&se_addr, ð_h->ether_shost, sizeof(struct ether_addr));
582: memcpy(&te_addr, ð_h->ether_dhost, sizeof(struct ether_addr));
583:
584: arp_h = (struct ether_arp *) ((char *) eth_h + ETHER_HDR_LEN);
585: if (htons(arp_h->ea_hdr.ar_hrd) != ARPHRD_ETHER) {
586: snprintf(s, 8, "0x%x", arp_h->ea_hdr.ar_hrd);
587: log_str(WARNING, "wrong hw address:", s); return;
588: }
589: if (htons(arp_h->ea_hdr.ar_pro) != ETHERTYPE_IP) {
590: snprintf(s, 8, "0x%x", arp_h->ea_hdr.ar_pro);
591: log_str(WARNING, "wrong proto address:", s); return;
592: }
593: op = htons(arp_h->ea_hdr.ar_op);
594:
595: memcpy(&sh_addr, &arp_h->arp_sha, sizeof(struct ether_addr));
596: memcpy(&sp_addr, &arp_h->arp_spa, sizeof(struct in_addr));
597: memcpy(&th_addr, &arp_h->arp_tha, sizeof(struct ether_addr));
598: memcpy(&tp_addr, &arp_h->arp_tpa, sizeof(struct in_addr));
599:
600: if (debug > 1) {
601: fprintf(stderr, "RECV ARP %u: ", op);
602: fprintf(stderr, "%-17s -> ", ether_ntoa(&se_addr)); fprintf(stderr, "%-17s\n ", ether_ntoa(&te_addr));
603: fprintf(stderr, "sdr %-17s %-15s ", ether_ntoa(&sh_addr), inet_ntoa(sp_addr));
604: fprintf(stderr, "trg %-17s %-15s\n", ether_ntoa(&th_addr), inet_ntoa(tp_addr));
605: }
606:
607: if (op == ARPOP_REPLY) return;
608: if (op != ARPOP_REQUEST) {
609: snprintf(s, 8, "0x%x", op);
610: log_str(WARNING, "wrong arp op:", s);
611: return;
612: }
613:
614: all++;
615: packet_check();
616: }
617:
618: void packet_recv(void) {
619: if (pcap_loop(pcap, -1, (pcap_handler) packet_handle, NULL) == -1) {
620: log_str(ERROR, "pcap_loop()", "failed");
621: exit_ipguard(EXIT_FAILURE);
622: }
623: }
624:
625: void stat_dump(void) {
626: struct pcap_stat ps;
627:
628: snprintf(s, 64, "ARP statistics:");
629: log_str(INFO, s, "");
630: snprintf(s, 64, "Total ARP who-has packets %u", all);
631: log_str(INFO, s, "");
632: snprintf(s, 64, "Good MAC-IP pairs %u", good);
633: log_str(INFO, s, "");
634: snprintf(s, 64, "Gratuitous MAC-IP/weird %u/%u", grat, wgrat);
635: log_str(INFO, s, "");
636: snprintf(s, 64, "Zero MAC/IP %u/%u", zmac, zip);
637: log_str(INFO, s, "");
638: snprintf(s, 64, "New MAC-IP pairs %u", bnew);
639: log_str(INFO, s, "");
640: snprintf(s, 64, "Bad MAC-IP pairs %u", bad);
641: log_str(INFO, s, "");
642: snprintf(s, 64, "Bad MAC/IP %u/%u", bmac, bsip);
643: log_str(INFO, s, "");
644: if (duplex) {
645: snprintf(s, 64, "Bad target IP %u", btip);
646: log_str(INFO, s, "");
647: }
648: snprintf(s, 64, "Bad gratuitous MAC-IP %u", bgrat);
649: log_str(INFO, s, "");
650: snprintf(s, 64, "My/Fake/PreFake MAC %u/%u/%u", mymac, fake, pfake);
651: log_str(INFO, s, "");
652: snprintf(s, 64, "Mismatch sender Ether/ARP MAC %u", mis);
653: log_str(INFO, s, "");
654: snprintf(s, 64, "Non-zero target ARP MAC %u", nzh);
655: log_str(INFO, s, "");
656: snprintf(s, 64, "Non-bcast target Ether MAC %u", nbe);
657: log_str(INFO, s, "");
658:
659: if (pcap_stats(pcap, &ps) == -1) {
660: log_str(WARNING, "pcap_stat()", "failed"); return;
661: }
662: snprintf(s, 64, "PCAP statistics:");
663: log_str(INFO, s, "");
664: snprintf(s, 64, "Received/Dropped packets %u/%u", ps.ps_recv, ps.ps_drop);
665: log_str(INFO, s, "");
666: }
667:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>