File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipguard / packet.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 21:59:41 2012 UTC (12 years, 3 months ago) by misho
Branches: ipguard, MAIN
CVS tags: v1_04p3, v1_04p0, v1_04, HEAD
ipguard

    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.1.1.1 2012/02/21 21:59:41 misho 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>