Annotation of researchv9/sys/net/arpld.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *             A R P  L D
                      3:  *
                      4:  * Generic (ethernet) address-resolution line discipline.
                      5:  * Implements an LRU cache of protocol address to ethernet address mappings.
                      6:  *
                      7:  *
                      8:  * Written by Kurt Gollhardt  (Nirvonics, Inc.)
                      9:  * Last update Wed Feb 12 20:43:28 1986
                     10:  *
                     11:  */
                     12: 
                     13: #include "../h/param.h"
                     14: #include "../h/systm.h"
                     15: #include "../h/stream.h"
                     16: #include "../h/conf.h"
                     17: #include "../h/ioctl.h"
                     18: #include "../h/ttyld.h"
                     19: #include "../h/ethernet.h"
                     20: #include "../h/order.h"
                     21: #include "../net/arpld.h"
                     22: 
                     23: #include "arp.h"
                     24: #if NARP > 0
                     25: 
                     26: #define NARPROTO  (NARP * NPROTO)
                     27: 
                     28: struct arp_dev Arp_dev[NARP];
                     29: struct proto   Arp_proto[NARPROTO];
                     30: 
                     31: static int     hd_size = MAX_HARDSIZE,
                     32:                pr_size, pr_hfirst;
                     33: 
                     34: static u_char  hd_sender[MAX_HARDSIZE],
                     35:                hd_target[MAX_HARDSIZE],
                     36:               pr_sender[MAX_PRSIZE],
                     37:               pr_target[MAX_PRSIZE];
                     38: 
                     39: static unsigned            arp_clock;
                     40: 
                     41: static int install(), request();
                     42: static int pack(), unpack();
                     43: static int bcmp();
                     44: 
                     45: struct block *packet_pullup();
                     46: 
                     47: #define DEBUG
                     48: 
                     49: #ifdef DEBUG
                     50:      int  Arpdebug = 0;
                     51: #    define debug(x)     if (Arpdebug) x
                     52: #else
                     53: #    define debug(x)
                     54: #endif
                     55: 
                     56: 
                     57: #define order(x,size,hfirst) ((hfirst) ? order_hfirst(x,size) \
                     58:                                        : order_lfirst(x,size))
                     59: 
                     60: 
                     61: arp_enable(dev, type, psize, phfirst, paddr)
                     62:      dev_t     dev;
                     63:      u_char    *paddr;
                     64: {
                     65:      register struct proto    *pr, *pr2;
                     66:      register struct arp_dev  *arpd;
                     67:      register struct arp      *arp;
                     68:      register int        i;
                     69:      int       ps = spl6();
                     70: 
                     71:      dev = physical(dev);
                     72: 
                     73:           /* Find the per-device structure for the desired device */
                     74:      for (arpd = Arp_dev, i = 0; i < NARP; ++i, ++arpd) {
                     75:           if (arpd->pdev == dev)
                     76:               break;
                     77:      }
                     78:      if (i == NARP) {
                     79:           printf("ARP: no arp for dev (%d,%d)\n", major(dev), minor(dev));
                     80:          goto bad;
                     81:      }
                     82:      if (bcmp(arpd->hdaddr, hzero, MAX_HARDSIZE)) {
                     83:          printf("ARP: hardware address not set for dev (%d,%d)\n",
                     84:                         major(dev), minor(dev));
                     85:          goto bad;
                     86:      }
                     87: 
                     88:           /* Find a free protocol structure for this device */
                     89:      pr = 0;
                     90:      for (pr2 = &Arp_proto[NPROTO * i], i = 0; i < NPROTO; ++i, ++pr2) {
                     91:           if (pr2->psize == 0)
                     92:               pr = pr2;
                     93:           else if (pr2->type == type) {
                     94:               printf("ARP: duplicate enable - dev (%d,%d) type 0x%x\n",
                     95:                         major(dev), minor(dev), type);
                     96:                goto bad;
                     97:           }
                     98:      }
                     99:      if (pr == 0) {
                    100:           printf("ARP: too many protocols on dev (%d,%d)\n",
                    101:                    major(dev), minor(dev));
                    102:           goto bad;
                    103:      }
                    104: 
                    105:      if (psize < 1 || psize > MAX_PRSIZE) {
                    106:           printf("ARP: protocol address size (%d) out of range\n", psize);
                    107:          goto bad;
                    108:      }
                    109:      pr->ptr = arpd;
                    110:      pr->type = type;
                    111:      pr->psize = psize;
                    112:      pr->phfirst = phfirst;
                    113: 
                    114:           /* Clear out the arp pairs */
                    115:      for (arp = pr->pair; arp < &pr->pair[NPAIR]; ++arp)
                    116:           bcopy(pzero, arp->paddr, psize);
                    117: 
                    118:           /* Add our address as arp pair 0 */
                    119:      bcopy(paddr, pr->pair[0].paddr, pr->psize);
                    120:      bcopy(arpd->hdaddr, pr->pair[0].hdaddr, hd_size);
                    121: 
                    122:      splx(ps);
                    123: 
                    124:      debug(printf("ARP: enabled protocol 0x%x on dev (%d,%d), channel %d\n",
                    125:                type, major(dev), minor(dev), pr - Arp_proto));
                    126:      debug(printf("     my addr is"));
                    127:      debug(print_addr(paddr, pr->psize));
                    128:      debug(printf(" at ethernet"));
                    129:      debug(print_addr(arpd->hdaddr, hd_size));
                    130:      debug(printf("  order is %s-byte first\n", phfirst? "high" : "low"));
                    131: 
                    132:      return pr - Arp_proto;
                    133: 
                    134: bad:
                    135:      splx(ps);
                    136:      return -1;
                    137: }
                    138: 
                    139: arp_getaddr(i, paddr, hdaddr)
                    140:      u_short   i;
                    141:      u_char    *paddr, *hdaddr;
                    142: {
                    143:      register struct proto    *pr = &Arp_proto[i];
                    144:      register struct arp      *arp;
                    145:      int       ps;
                    146: 
                    147:      if (i >= NARPROTO || pr->psize == 0) {
                    148:           printf("ARP: getaddr on un-enabled channel %d\n", i);
                    149:          return -1;
                    150:      }
                    151: 
                    152:      debug(printf("ARP: getaddr for"));
                    153:      debug(print_addr(paddr, pr->psize));
                    154:      debug(printf(" on channel %d\n", i));
                    155: 
                    156:      ps = spl6();
                    157: 
                    158:      for (arp = pr->pair; arp < &pr->pair[NPAIR]; ++arp) {
                    159:           if (bcmp(arp->paddr, paddr, pr->psize)) {
                    160:               bcopy(arp->hdaddr, hdaddr, hd_size);
                    161:               arp->time = ++arp_clock;
                    162:               splx(ps);
                    163:               return 0;
                    164:           }
                    165:      }
                    166: 
                    167:      request(pr, paddr);
                    168:      splx(ps);
                    169:      return -1;
                    170: }
                    171: 
                    172: struct block *
                    173: arp_resolve(i, bp, paddr)
                    174:      struct block   *bp;
                    175:      u_char    *paddr;
                    176: {
                    177:      register struct block    *bp1;
                    178:      register struct etherpup     *ep;
                    179: 
                    180:      if ((bp1 = allocb(sizeof(struct etherpup))) == 0) {
                    181:          printf("ARP: can't alloc block for resolve\n");
                    182: bad:
                    183:          while (bp != 0) {
                    184:               bp1 = bp->next;
                    185:               freeb(bp);
                    186:               bp = bp1;
                    187:          }
                    188:          return 0;
                    189:      }
                    190: 
                    191:      ep = (struct etherpup *)bp1->wptr;
                    192:      bp1->wptr += sizeof(struct etherpup);
                    193:      if (arp_getaddr(i, paddr, ep->dhost) < 0) {
                    194:          freeb(bp1);
                    195:          goto bad;
                    196:      }
                    197: 
                    198:      ep->type = hfirst_short(Arp_proto[i].type);
                    199:      bp1->next = bp;
                    200:      return bp1;
                    201: }
                    202: 
                    203: arp_disable(i)
                    204:      u_short   i;
                    205: {
                    206:      register struct proto    *pr = &Arp_proto[i];
                    207:      register struct arp      *arp;
                    208: 
                    209:      if (i >= NARPROTO || pr->psize == 0) {
                    210:           printf("ARP: disable on un-enabled channel %d\n", i);
                    211:          return;
                    212:      }
                    213: 
                    214:      debug(printf("ARP: disabled channel %d\n", i));
                    215: 
                    216:      pr->psize = 0;
                    217: }
                    218: 
                    219: arp_broadcast(hdaddr)
                    220:      u_char    *hdaddr;
                    221: {
                    222:      bcopy(broadaddr, hdaddr, hd_size);
                    223: }
                    224: 
                    225: 
                    226: static install(pr, paddr, hdaddr)
                    227:      register struct proto    *pr;
                    228:      u_char    *paddr, *hdaddr;
                    229: {
                    230:      register struct arp      *arp, *empty;
                    231: 
                    232:      debug(printf("ARP: install()\n"));
                    233: 
                    234:           /* Look for an arp pair for this address, or a free one, or LRU */
                    235:      for (empty = arp = pr->pair; arp < &pr->pair[NPAIR]; ++arp) {
                    236:           if (bcmp(arp->paddr, paddr, pr->psize))
                    237:               break;
                    238:           if (bcmp(arp->paddr, pzero, pr->psize))
                    239:               (empty = arp)->time = arp_clock + 1;
                    240:          else if (arp_clock - arp->time > arp_clock - empty->time)
                    241:               empty = arp;
                    242:      }
                    243: 
                    244:      if (arp == &pr->pair[NPAIR])
                    245:          (arp = empty)->time = ++arp_clock;
                    246: 
                    247:      bcopy(paddr, arp->paddr, pr->psize);
                    248:      bcopy(hdaddr, arp->hdaddr, hd_size);
                    249: 
                    250:      debug(printf("ARP: installed paddr"));
                    251:      debug(print_addr(paddr, pr->psize));
                    252:      debug(printf(" at ethernet"));
                    253:      debug(print_addr(hdaddr, hd_size));
                    254:      debug(printf(" on channel %d\n", pr - Arp_proto));
                    255: 
                    256:      return 0;
                    257: }
                    258: 
                    259: #define OUT_SIZE    (sizeof(struct etherpup) + sizeof(struct ether_arp) \
                    260:                      - 2*(MAX_HARDSIZE + MAX_PRSIZE) + 2*(hd_size + pr_size))
                    261: 
                    262: static request(pr, paddr)
                    263:      register struct proto    *pr;
                    264:      u_char    *paddr;
                    265: {
                    266:      register struct queue    *q;
                    267:      register struct block    *bp;
                    268:      struct ether_arp         *arpkt;
                    269:      struct etherpup         *ep;
                    270:      long      my_paddr, his_paddr;
                    271: 
                    272:      debug(printf("ARP: request()\n"));
                    273: 
                    274:      pr_size = pr->psize;
                    275:      pr_hfirst = pr->phfirst;
                    276: 
                    277:      q = WR(pr->ptr->rdq);
                    278:      if ((bp = allocb(OUT_SIZE)) == 0) {
                    279:           printf("ARP: can't alloc block for request\n");
                    280:           return;
                    281:      }
                    282:      if (bp->lim - bp->wptr < OUT_SIZE) {
                    283:           freeb(bp);
                    284:          printf("ARP: block too small for request\n");
                    285:          return;
                    286:      }
                    287: 
                    288:      ep = (struct etherpup *)bp->wptr;
                    289:      arpkt = (struct ether_arp *)(bp->wptr + sizeof(struct etherpup));
                    290:      bp->wptr += OUT_SIZE;
                    291: 
                    292:      bcopy(broadaddr, ep->dhost, hd_size);
                    293:      ep->type = hfirst_short(ETHERPUP_ARPTYPE);
                    294: 
                    295:      arpkt->arp_hrd = hfirst_short(ARPHRD_ETHER);
                    296:      arpkt->arp_pro = hfirst_short(pr->type);
                    297:      arpkt->arp_hln = hd_size;
                    298:      arpkt->arp_pln = pr_size;
                    299:      arpkt->arp_op = hfirst_short(ARPOP_REQUEST);
                    300: 
                    301:      bcopy(pr->pair[0].hdaddr, hd_sender, hd_size);
                    302:      bcopy(pr->pair[0].paddr, pr_sender, pr_size);
                    303:      bcopy(paddr, pr_target, pr_size);
                    304:      bcopy(hzero, hd_target, hd_size);
                    305:      pack(arpkt);
                    306: 
                    307:      debug(printf("ARP: sending a request for address"));
                    308:      debug(print_addr(paddr, pr->psize));
                    309:      debug(printf(" on channel %d\n", pr - Arp_proto));
                    310: 
                    311:      if (q->next->flag & QFULL) {
                    312:           freeb(bp);
                    313:           debug(printf("ARP: QFULL in request()\n"));
                    314:      } else {
                    315:           (*q->next->qinfo->putp)(q->next, bp);
                    316:          putctl(q->next, M_DELIM);
                    317:      }
                    318: }
                    319: 
                    320: 
                    321: int arp_open(), arp_close(), arp_iput(), arp_srv(), arp_bypass(), arp_rcvpkt();
                    322: static struct qinit arp_rinit = {
                    323:           arp_iput, arp_srv, arp_open, arp_close, 750, 250
                    324: };
                    325: static struct qinit arp_winit = {
                    326:           arp_bypass, NULL, arp_open, arp_close, 0, 0
                    327: };
                    328: struct streamtab arpinfo = { &arp_rinit, &arp_winit };
                    329: 
                    330: 
                    331: arp_open(q, dev)
                    332:      register struct queue    *q;
                    333:      dev_t     dev;
                    334: {
                    335:      register int   i;
                    336:      register struct arp_dev  *arpd, *narp;
                    337: 
                    338:      if (q->ptr)    /* If this stream is already open, don't do anything */
                    339:           return 1;
                    340: 
                    341:      dev = physical(dev);
                    342: 
                    343:      /* Look for a free per-device structure */
                    344:      narp = 0;
                    345:      for (arpd = Arp_dev; arpd < &Arp_dev[NARP]; ++arpd) {
                    346:           if (arpd->pdev == dev) {
                    347:               printf("ARP: multiple arps on device (%d,%d)\n",
                    348:                         major(dev), minor(dev));
                    349:                return 0;
                    350:           }
                    351:          if (arpd->pdev == 0)
                    352:               narp = arpd;
                    353:      }
                    354:      if (narp == 0)
                    355:           return 0;   /* Open fails: no more line disciplines */
                    356: 
                    357:      narp->pdev = dev;
                    358:      narp->delim_count = 0;
                    359:      bcopy(hzero, narp->hdaddr, MAX_HARDSIZE);
                    360:      narp->rdq = q;
                    361: 
                    362:      q->flag |= QDELIM|QNOENB;
                    363:      q->ptr = (caddr_t)narp;
                    364:      return 1;
                    365: }
                    366: 
                    367: arp_close(q)
                    368:      register struct queue    *q;
                    369: {
                    370:      register struct arp_dev  *arpd;
                    371:      int       n, i;
                    372: 
                    373:      arpd = (struct arp_dev *)q->ptr;
                    374:      arpd->pdev = 0;
                    375:      q->ptr = 0;
                    376:      n = (arpd - Arp_dev) * NPROTO;
                    377:      for (i = n; i < n + NPROTO; ++i)
                    378:           Arp_proto[i].psize = 0;
                    379: }
                    380: 
                    381: arp_bypass(q, bp)
                    382:      register struct queue    *q;
                    383:      register struct block    *bp;
                    384: {
                    385:      (*q->next->qinfo->putp)(q->next, bp);
                    386: }
                    387: 
                    388: arp_misc(q, bp)
                    389:      struct queue    *q;
                    390:      struct block    *bp;
                    391: {
                    392:      register union stmsg *sp;
                    393: 
                    394:      if (bp->type == M_IOCACK) {
                    395:          sp = (union stmsg *)bp->rptr;
                    396:          if (sp->iocx.com == ENIOADDR)
                    397:               bcopy(sp->iocx.xxx, ((struct arp_dev *)q->ptr)->hdaddr,
                    398:                         MAX_HARDSIZE);
                    399:      }
                    400:      /* Anything else, just pass on to the next guy */
                    401:      (*q->next->qinfo->putp)(q->next, bp);
                    402: }
                    403: 
                    404: arp_iput(q, bp)
                    405:      struct queue    *q;
                    406:      struct block    *bp;
                    407: {
                    408:      packet_putp(q, bp, &((struct arp_dev *)q->ptr)->delim_count, 0, arp_misc);
                    409: }
                    410: 
                    411: arp_false(q)
                    412:      struct queue   *q;
                    413: {
                    414:      return 0;
                    415: }
                    416: 
                    417: arp_srv(q)
                    418:      struct queue   *q;
                    419: {
                    420:      packet_srvp(q, &((struct arp_dev *)q->ptr)->delim_count,
                    421:                    arp_false, arp_false, arp_rcvpkt, 0);
                    422: }
                    423: 
                    424: arp_rcvpkt(q, bp, partial)
                    425:      register struct queue    *q;
                    426:      register struct block    *bp;
                    427: {
                    428:      register struct ether_arp *arpkt;
                    429:      register struct proto    *pr;
                    430:      register struct etherpup *ep;
                    431:      register int        i, type;
                    432:      short     op;
                    433:      int       ps;
                    434: 
                    435:      if (partial || bp == NULL) {
                    436:          free_blocks(bp);
                    437:          return;
                    438:      }
                    439:      i = sizeof(struct etherpup) + sizeof(struct ether_arp);
                    440:      if ((bp = packet_pullup(bp, i)) == 0) {
                    441:          printf("ARP: bad packet\n");
                    442:          return;
                    443:      }
                    444:      if (bp->next)
                    445:          free_blocks(bp);
                    446: 
                    447:      pr = &Arp_proto[((struct arp_dev *)q->ptr - Arp_dev) * NPROTO];
                    448:      arpkt = (struct ether_arp *)(bp->rptr + sizeof(struct etherpup));
                    449:      type = hfirst_short(arpkt->arp_pro);
                    450:      op = hfirst_short(arpkt->arp_op);
                    451: 
                    452:      debug(printf("ARP: rcvd arp %s for protocol 0x%x\n",
                    453:                     (op == ARPOP_REQUEST ? "request" :
                    454:                         (op == ARPOP_REPLY ? "reply" : "(BAD)")), type));
                    455: 
                    456:      ps = spl6();
                    457: 
                    458:      for (i = 0; i < NPROTO; ++i, ++pr) {
                    459:           if (pr->psize != 0 && pr->type == type)
                    460:               break;
                    461:      }
                    462:      if (i == NPROTO)
                    463:           goto out; /* Not one of the types we recognize */
                    464: 
                    465:      pr_size = pr->psize;
                    466:      pr_hfirst = pr->phfirst;
                    467:      unpack(arpkt);
                    468: 
                    469:      if (!bcmp(pr_target, pr->pair[0].paddr, pr_size)) {
                    470: out:
                    471:           splx(ps);
                    472:           freeb(bp);
                    473:          return;
                    474:      }
                    475:      if (bcmp(pr_sender, pr->pair[0].paddr, pr_size)) {
                    476:           printf("ARP: someone is pretending to be me!!!\n");
                    477:           goto out;
                    478:      }
                    479:      if (op == ARPOP_REPLY && !bcmp(hd_target, pr->pair[0].hdaddr, hd_size))
                    480:           goto out;
                    481: 
                    482:      install(pr, pr_sender, hd_sender);
                    483:      if (op != ARPOP_REQUEST)
                    484:           goto out;
                    485: 
                    486:      arpkt->arp_hrd = hfirst_short(ARPHRD_ETHER);
                    487:      arpkt->arp_op = hfirst_short(ARPOP_REPLY);
                    488: 
                    489:      debug(printf("ARP: sending reply to"));
                    490:      debug(print_addr(pr_sender, pr_size));
                    491:      debug(printf(" at ethernet"));
                    492:      debug(print_addr(hd_sender, hd_size));
                    493:      debug(printf(" on channel %d\n", pr - Arp_proto));
                    494: 
                    495:      bcopy(pr_sender, pr_target, pr_size);
                    496:      bcopy(hd_sender, hd_target, hd_size);
                    497:      bcopy(pr->pair[0].paddr, pr_sender, pr_size);
                    498:      bcopy(pr->pair[0].hdaddr, hd_sender, hd_size);
                    499:      pack(arpkt);
                    500: 
                    501:      ep = (struct etherpup *)(bp->rptr += sizeof(struct etherpup)
                    502:                                              - sizeof(struct etherpup));
                    503:      bcopy(hd_target, ep->dhost, hd_size);
                    504:      ep->type = hfirst_short(ETHERPUP_ARPTYPE);
                    505: 
                    506:      splx(ps);
                    507: 
                    508:      q = WR(q);
                    509:      if (q->next->flag & QFULL) {
                    510:           freeb(bp);
                    511:           debug(printf("ARP: QFULL on reply\n"));
                    512:      } else {
                    513:           (*q->next->qinfo->putp) (q->next, bp);
                    514:           putctl(q->next, M_DELIM);
                    515:      }
                    516: }
                    517: 
                    518: 
                    519: static pack(arpkt)
                    520:      struct ether_arp    *arpkt;
                    521: {
                    522:      register u_char     *p = arpkt->arp_addr;
                    523:      long      paddr;
                    524: 
                    525:      debug(printf("ARP: packing arp from"));
                    526:      debug(print_addr(pr_sender, pr_size));
                    527:      debug(printf(" at"));
                    528:      debug(print_addr(hd_sender, hd_size));
                    529:      debug(printf(", target is"));
                    530:      debug(print_addr(pr_target, pr_size));
                    531:      debug(printf(" (at"));
                    532:      debug(print_addr(hd_target, hd_size));
                    533:      debug(printf(")\n"));
                    534: 
                    535:      bcopy(hd_sender, p, hd_size);
                    536:      paddr = order(*(long *)pr_sender, pr_size, pr_hfirst);
                    537:      bcopy(&paddr, p += hd_size, pr_size);
                    538:      bcopy(hd_target, p += pr_size, hd_size);
                    539:      paddr = order(*(long *)pr_target, pr_size, pr_hfirst);
                    540:      bcopy(&paddr, p += hd_size, pr_size);
                    541: }
                    542: 
                    543: static unpack(arpkt)
                    544:      struct ether_arp    *arpkt;
                    545: {
                    546:      register u_char     *p = arpkt->arp_addr;
                    547:      long      paddr;
                    548: 
                    549:      bcopy(p, hd_sender, hd_size);
                    550:      paddr = order(*(long *)(p += hd_size), pr_size, pr_hfirst);
                    551:      bcopy(&paddr, pr_sender, pr_size);
                    552:      bcopy(p += pr_size, hd_target, hd_size);
                    553:      paddr = order(*(long *)(p += hd_size), pr_size, pr_hfirst);
                    554:      bcopy(&paddr, pr_target, pr_size);
                    555: 
                    556:      debug(printf("ARP: unpacked arp from"));
                    557:      debug(print_addr(pr_sender, pr_size));
                    558:      debug(printf(" at"));
                    559:      debug(print_addr(hd_sender, hd_size));
                    560:      debug(printf(", target is"));
                    561:      debug(print_addr(pr_target, pr_size));
                    562:      debug(printf(" (at"));
                    563:      debug(print_addr(hd_target, hd_size));
                    564:      debug(printf(")\n"));
                    565: }
                    566: 
                    567: 
                    568: static bcmp(a, b, n)
                    569:      register u_char     *a, *b;
                    570:      register int        n;
                    571: {
                    572:      while (n-- > 0)
                    573:           if(*a++ != *b++)
                    574:                return 0;
                    575:      return 1;
                    576: }
                    577: 
                    578: 
                    579: #ifdef DEBUG
                    580: 
                    581: print_addr(addr, size)
                    582:      register u_char     *addr;
                    583:      register u_short    size;
                    584: {
                    585:      while (size-- > 0)
                    586:           printf(" %x", *addr++);
                    587: }
                    588: 
                    589: #endif DEBUG
                    590: 
                    591: #endif NARP

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.