|
|
Xinu for VAX
/* arp_in.c - arp_in */
#include <conf.h>
#include <kernel.h>
#include <proc.h>
#include <network.h>
/*------------------------------------------------------------------------
* arp_in - handle ARP packet coming in from Ethernet network
*------------------------------------------------------------------------
*/
arp_in(packet, device)
struct epacket *packet;
int device;
{
PStype ps;
int arop;
int pid;
struct arppak *apacptr;
struct arpent *atabptr;
struct etblk *etptr;
etptr = (struct etblk *) devtab[device].dvioblk;
apacptr = (struct arppak *) packet->ep_data;
atabptr = &Arp.arptab[arpfind(apacptr->ar_spa)];
if (atabptr->arp_state != AR_RSLVD) {
blkcopy(atabptr->arp_Ead, apacptr->ar_sha, EPADLEN);
atabptr->arp_dev = device;
atabptr->arp_state = AR_RSLVD;
}
arop = net2hs(apacptr->ar_op) & LOW16;
switch (arop) {
case AR_REQ: /* request - answer if for me */
if (! blkequ(Net.myaddr, apacptr->ar_tpa, IPLEN)) {
freebuf(packet);
return(OK);
}
apacptr->ar_op = hs2net(AR_RPLY);
blkcopy(apacptr->ar_tpa, apacptr->ar_spa, IPLEN);
blkcopy(apacptr->ar_tha, packet->ep_hdr.e_src, EPADLEN);
blkcopy(packet->ep_hdr.e_dest, apacptr->ar_tha, EPADLEN);
blkcopy(apacptr->ar_sha, etptr->etpaddr, EPADLEN);
blkcopy(apacptr->ar_spa, Net.myaddr, IPLEN);
write(device, packet, EMINPAK);
return(OK);
case AR_RPLY: /* reply - awaken requestor if any */
disable(ps);
pid = Arp.arppid;
if (!isbadpid(pid)
&& blkequ(Arp.arpwant, apacptr->ar_spa, IPLEN)) {
Arp.arppid = BADPID;
send(pid, OK);
}
freebuf(packet);
restore(ps);
return(OK);
default:
Net.ndrop++;
freebuf(packet);
return(SYSERR);
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.