V8/usr/sys/inet/ip_arp.c

Compare this file to the similar file:
Show the results in this format:

#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