|
|
1.1 ! root 1: #include "inet.h" ! 2: #include "uarp.h" ! 3: #if NUARP > 0 && NINET > 0 ! 4: ! 5: #include "../h/param.h" ! 6: #include "../h/systm.h" ! 7: #include "../h/conf.h" ! 8: #include "../h/ioctl.h" ! 9: #include "../h/ethernet.h" ! 10: #include "../h/stream.h" ! 11: #include "../h/ttyld.h" ! 12: #include "../h/inet/in.h" ! 13: #include "../h/inet/ip_var.h" ! 14: ! 15: /* ! 16: * Address resolution code. ip_ldout() calls arp_resolve if IFF_ARP ! 17: * is set to map an internet address into a 48 bit ethernet address. ! 18: * If arp_resolve finds the address in its tables, it prepends an ! 19: * ethernet header to the packet and returns it. Otherwise, it sends ! 20: * a message to the ipconfig waiting on the specified queue asking ! 21: * it to do all the hard work. The user process at some point will use ! 22: * the IPIORESOLVE ioctl to update the tabes. ! 23: * ! 24: * N.B. If we ever get a medium other than ethernet that needs arping, ! 25: * this code will need to be made a bit more general. ! 26: */ ! 27: ! 28: /* ! 29: * Hash table for arp entries. Collision resolution is linear search until ! 30: * encountering a hole. Replacement is LRU. ! 31: */ ! 32: #define NARP 128 /* number of arp entries */ ! 33: struct ip_arp ip_arps[NARP]; /* arping table */ ! 34: #define HASH(x) ((x)%NARP) ! 35: int Nip_arp = NARP; /* number of address translations for netstat */ ! 36: ! 37: arp_install(in, en) ! 38: register unsigned long in; ! 39: unsigned char *en; ! 40: { ! 41: register struct ip_arp *ap, *rp, *op; ! 42: ! 43: /* find matching entry, empty entry, or oldest entry */ ! 44: op = ap = rp = &ip_arps[HASH(in)]; ! 45: do { ! 46: if (ap->inaddr==0 || ap->inaddr==in) { ! 47: op = ap; ! 48: break; ! 49: } ! 50: if (ap->time < op->time) ! 51: op = ap; ! 52: if(++ap==&ip_arps[NARP]) ! 53: ap = ip_arps; ! 54: } while(ap!=rp); ! 55: ! 56: /* fill in new entry */ ! 57: op->time = time; ! 58: op->inaddr = in; ! 59: bcopy((caddr_t)en, (caddr_t)op->enaddr, sizeof(op->enaddr)); ! 60: return(0); ! 61: } ! 62: ! 63: struct block * ! 64: arp_resolve(q, bp, dst) ! 65: struct queue *q; ! 66: register struct block *bp; ! 67: unsigned long dst; ! 68: { ! 69: register struct block *bp1; ! 70: struct etherpup *hp; ! 71: register struct ip_arp *ap, *rp; ! 72: ! 73: /* find matching entry */ ! 74: ap = rp = &ip_arps[HASH(dst)]; ! 75: do { ! 76: if (ap->inaddr==0 || ap->inaddr==dst) ! 77: break; ! 78: if(++ap==&ip_arps[NARP]) ! 79: ap = ip_arps; ! 80: } while(ap!=rp); ! 81: if (ap->inaddr!=dst) { ! 82: arp_request(q, dst); /* request an address resolution */ ! 83: bp_free(bp); /* free the packet */ ! 84: return(0); ! 85: } ! 86: ! 87: /* make a block with the ether info */ ! 88: bp1 = allocb(sizeof(struct etherpup)); ! 89: if(bp1 == 0){ ! 90: printf("no bp for arp_resolve\n"); ! 91: bp_free(bp); ! 92: return(0); ! 93: } ! 94: ap->time = time; ! 95: bp1->type = M_DATA; ! 96: bp1->wptr = bp1->rptr + sizeof(struct etherpup); ! 97: bp1->next = bp; ! 98: hp = (struct etherpup *)(bp1->rptr); ! 99: hp->type = htons(ETHERPUP_IPTYPE); ! 100: bcopy((caddr_t)(ap->enaddr), (caddr_t)(hp->dhost), 6); ! 101: return(bp1); ! 102: } ! 103: ! 104: arp_request(q, dst) ! 105: register struct queue *q; ! 106: unsigned long dst; ! 107: { ! 108: struct block *bp; ! 109: ! 110: if(q->next->flag & QFULL){ ! 111: printf("arp q full\n"); ! 112: return; ! 113: } ! 114: bp = allocb(4); ! 115: if(bp == 0) ! 116: return; ! 117: bp->type = M_DATA; ! 118: bp->wptr = bp->rptr + 4; ! 119: *((u_long *)(bp->rptr)) = dst; ! 120: (*q->next->qinfo->putp)(q->next, bp); ! 121: bp = allocb(1); ! 122: if(bp == 0) ! 123: return; ! 124: bp->type = M_DELIM; ! 125: (*q->next->qinfo->putp)(q->next, bp); ! 126: } ! 127: #endif NUARP
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.