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, &eth_h->ether_shost, sizeof(struct ether_addr));
                    582:     memcpy(&te_addr, &eth_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>