|
|
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/stream.h" ! 8: #include "../h/conf.h" ! 9: #include "../h/ioctl.h" ! 10: #include "../h/ethernet.h" ! 11: #include "../h/inet/in.h" ! 12: #include "../h/inet/ip_var.h" ! 13: ! 14: /* ! 15: * Address resolution code. ip_ldout() calls arp_resolve if IFF_ARP ! 16: * is set to map an internet address into a 48 bit ethernet address. ! 17: * If arp_resolve finds the address in its tables, it prepends an ! 18: * ethernet header to the packet and returns it. Otherwise, it sends ! 19: * a message to the ipconfig waiting on the specified queue asking ! 20: * it to do all the hard work. The user process at some point will use ! 21: * the IPIORESOLVE ioctl to update the tabes. ! 22: */ ! 23: ! 24: /* temporary. soon to be hashed. */ ! 25: #define NARP 50 ! 26: struct ip_arp ip_arps[NARP]; /* this table should never have holes in it */ ! 27: ! 28: int Nip_arp = NARP; /* number of address translations for netstat */ ! 29: ! 30: arp_install(in, en) ! 31: unsigned long in; ! 32: unsigned char *en; ! 33: { ! 34: register struct ip_arp *ap; ! 35: ! 36: for(ap = &ip_arps[0]; ap < &ip_arps[NARP]; ap++){ ! 37: if(ap->inaddr == in) ! 38: break; ! 39: if(ap->inaddr == 0) ! 40: break; ! 41: } ! 42: if(ap >= &ip_arps[NARP]) ! 43: return(1); ! 44: ap->inaddr = in; ! 45: bcopy((caddr_t)en, (caddr_t)(ap->enaddr), 6); ! 46: return(0); ! 47: } ! 48: ! 49: struct block * ! 50: arp_resolve(q, bp, dst) ! 51: struct queue *q; ! 52: register struct block *bp; ! 53: unsigned long dst; ! 54: { ! 55: register struct ip_arp *ap; ! 56: register struct block *bp1; ! 57: struct ether_in *hp; ! 58: ! 59: for(ap = &ip_arps[0]; ap < &ip_arps[NARP]; ap++) ! 60: if(ap->inaddr == dst || ap->inaddr == 0) ! 61: break; ! 62: if(ap->inaddr == 0 || ap >= &ip_arps[NARP]){ ! 63: arp_request(q, dst); ! 64: bp_free(bp); ! 65: return(0); ! 66: } ! 67: bp1 = allocb(sizeof(struct ether_in)); ! 68: if(bp1 == 0){ ! 69: printf("no bp for arp_resolve\n"); ! 70: bp_free(bp); ! 71: return(0); ! 72: } ! 73: bp1->type = M_DATA; ! 74: bp1->wptr = bp1->rptr + sizeof(struct ether_in); ! 75: bp1->next = bp; ! 76: hp = (struct ether_in *)(bp1->rptr); ! 77: hp->type = htons(ETHERPUP_IPTYPE); ! 78: bcopy((caddr_t)(ap->enaddr), (caddr_t)(hp->dhost), 6); ! 79: return(bp1); ! 80: } ! 81: ! 82: arp_request(q, dst) ! 83: register struct queue *q; ! 84: unsigned long dst; ! 85: { ! 86: struct block *bp; ! 87: ! 88: if(q->next->flag & QFULL){ ! 89: printf("arp q full\n"); ! 90: return; ! 91: } ! 92: bp = allocb(4); ! 93: if(bp == 0) ! 94: return; ! 95: bp->type = M_DATA; ! 96: bp->wptr = bp->rptr + 4; ! 97: *((u_long *)(bp->rptr)) = dst; ! 98: (*q->next->qinfo->putp)(q->next, bp); ! 99: bp = allocb(1); ! 100: if(bp == 0) ! 101: return; ! 102: bp->type = M_DELIM; ! 103: (*q->next->qinfo->putp)(q->next, bp); ! 104: } ! 105: #endif NUARP
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.