V8/usr/sys/inet/ip_arp.c
#include "inet.h"
#include "uarp.h"
#if NUARP > 0 && NINET > 0
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/stream.h"
#include "../h/conf.h"
#include "../h/ioctl.h"
#include "../h/ethernet.h"
#include "../h/inet/in.h"
#include "../h/inet/ip_var.h"
/*
* Address resolution code. ip_ldout() calls arp_resolve if IFF_ARP
* is set to map an internet address into a 48 bit ethernet address.
* If arp_resolve finds the address in its tables, it prepends an
* ethernet header to the packet and returns it. Otherwise, it sends
* a message to the ipconfig waiting on the specified queue asking
* it to do all the hard work. The user process at some point will use
* the IPIORESOLVE ioctl to update the tabes.
*/
/* temporary. soon to be hashed. */
#define NARP 50
struct ip_arp ip_arps[NARP]; /* this table should never have holes in it */
int Nip_arp = NARP; /* number of address translations for netstat */
arp_install(in, en)
unsigned long in;
unsigned char *en;
{
register struct ip_arp *ap;
for(ap = &ip_arps[0]; ap < &ip_arps[NARP]; ap++){
if(ap->inaddr == in)
break;
if(ap->inaddr == 0)
break;
}
if(ap >= &ip_arps[NARP])
return(1);
ap->inaddr = in;
bcopy((caddr_t)en, (caddr_t)(ap->enaddr), 6);
return(0);
}
struct block *
arp_resolve(q, bp, dst)
struct queue *q;
register struct block *bp;
unsigned long dst;
{
register struct ip_arp *ap;
register struct block *bp1;
struct ether_in *hp;
for(ap = &ip_arps[0]; ap < &ip_arps[NARP]; ap++)
if(ap->inaddr == dst || ap->inaddr == 0)
break;
if(ap->inaddr == 0 || ap >= &ip_arps[NARP]){
arp_request(q, dst);
bp_free(bp);
return(0);
}
bp1 = allocb(sizeof(struct ether_in));
if(bp1 == 0){
printf("no bp for arp_resolve\n");
bp_free(bp);
return(0);
}
bp1->type = M_DATA;
bp1->wptr = bp1->rptr + sizeof(struct ether_in);
bp1->next = bp;
hp = (struct ether_in *)(bp1->rptr);
hp->type = htons(ETHERPUP_IPTYPE);
bcopy((caddr_t)(ap->enaddr), (caddr_t)(hp->dhost), 6);
return(bp1);
}
arp_request(q, dst)
register struct queue *q;
unsigned long dst;
{
struct block *bp;
if(q->next->flag & QFULL){
printf("arp q full\n");
return;
}
bp = allocb(4);
if(bp == 0)
return;
bp->type = M_DATA;
bp->wptr = bp->rptr + 4;
*((u_long *)(bp->rptr)) = dst;
(*q->next->qinfo->putp)(q->next, bp);
bp = allocb(1);
if(bp == 0)
return;
bp->type = M_DELIM;
(*q->next->qinfo->putp)(q->next, bp);
}
#endif NUARP