|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.