📄 arp.c
字号:
} /* end arp_reply */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* arp_request */
/* */
/* DESCRIPTION */
/* */
/* Put out an ARP request packet, doesn't wait for response */
/* */
/* CALLED BY */
/* netarpme Send an ARP to myself */
/* cachelook looks up information in the cache */
/* netsetgate Assign an IP number to use as a gateway */
/* */
/* CALLS */
/* */
/* arp_prepare_pkt */
/* NET_Send */
/* */
/*************************************************************************/
int16 arp_request(uint8 *tipnum)
{
struct pqueue HUGE *buf_ptr;
buf_ptr = arp_prepare_pkt(tipnum, broadaddr, ARPREQ);
if(buf_ptr == NU_NULL)
return (-1);
NET_Send(buf_ptr, sizeof(ARPKT), OTHER_PKT);
return(NU_SUCCESS);
} /* end arp_request */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* arpinterpret */
/* */
/* DESCRIPTION */
/* */
/* interpret ARP packets */
/* Look at incoming ARP packet and make required assessment of */
/* usefulness, check to see if we requested this packet, clear */
/* all appropriate flags. */
/* */
/* CALLED BY */
/* demux Demux incoming packets */
/* */
/* CALLS */
/* */
/* intswap Byte swap an integer */
/* arp_reply Address resolution */
/* cacheupdate Update the ARP cache */
/* */
/*************************************************************************/
int16 arpinterpret(ARPKT *p)
{
ARP_RESOLVE_ENTRY *ar_entry;
/*
* check packet's desired IP address translation to see if it wants
* me to answer.
*/
if ( (p->op == intswap (ARPREQ)) &&
(comparen (p->tpa, nnipnum, 4)))
{
cacheupdate (p->spa, p->sha); /* keep her address for me */
arp_reply(p->sha, p->spa); /* proper reply */
return (NU_SUCCESS);
}
/*
* Check for a RARP reply. If present, call netsetip()
*/
else if (p->op == intswap (RARPR)
&& (comparen (p->tha, nnmyaddr, DADDLEN)))
{
/* Search the ARP_Res_List for a match. */
for(ar_entry = ARP_Res_List.ar_head;
ar_entry != NU_NULL;
ar_entry = ar_entry->ar_next)
{
/* A match is found when we find an entry for a RARP request. */
if (ar_entry->ar_pkt_type == RARPQ)
break;
}
/* Was a match found. */
if (ar_entry)
{
/* Get the IP address. */
netsetip(p->tpa);
/* Clear the timer event. */
Stimerunset(CONCLASS, RARP_REQUEST, ar_entry->ar_id, 1);
/* Resume the task. */
NU_Resume_Task(ar_entry->ar_task);
}
return (NU_SUCCESS);
}
/*
* Check for a reply that I probably asked for.
*/
if (comparen (p->tpa, nnipnum, 4)
&& (p->op == intswap (ARPREP))
&& (p->hrd == intswap (HARDWARE_TYPE))
&& (p->hln == DADDLEN) && (p->pln == 4))
{
cacheupdate (p->spa, p->sha);
return (NU_SUCCESS);
}
return (1);
} /* end arpinterpret */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* cacheupdate */
/* */
/* DESCRIPTION */
/* */
/* We just received an ARP, or reply to ARP and need to add the */
/* information to the cache. */
/* Reset arptime so that another machine may be ARPed. This timer keeps*/
/* ARPs from going out more than one a second unless we receive a reply.*/
/* */
/* CALLED BY */
/* arp_request Send out an arp request packet */
/* arpinterpret Interpret ARP Packets */
/* */
/* CALLS */
/* n_clicks */
/* */
/* HISTORY */
/* NAME DATE REMARKS */
/* */
/* MQ. Qian 12/05/95 Fixed a bug that prevented the */
/* correct entry in the arp cache */
/* from always being found. */
/* */
/*************************************************************************/
int16 cacheupdate(uint8 *ipn,uint8 *hrdn)
{
int16 i, found=-1;
int32 timer;
/*
* linear search to see if we already have this entry
*/
for (i=0; i<CACHELEN; i++)
if (comparen (ipn, arpc[i].ip, 4))
{
found = i;
break;
}
/*
* if that IP number is not already here, take the oldest
* entry.
* If it is already here, update the info and reset the timer.
* These were pre-initialized to 0, so if any are blank, they
* will be
* taken first because they are faked to be oldest.
*/
if (found<0)
{
timer = arpc[0].tm;
found = 0;
for (i=1; i<CACHELEN; i++)
{
if ((INT32_CMP(arpc[i].tm, timer) < 0) && (!arpc[i].gate))
{ /* exclude gateways */
found = i;
timer = arpc[i].tm;
} /* end if arpc check */
} /* end for CACHELEN */
} /* end if found < 0 */
/*
* do the update to the cache
*/
memcpy ((void *)arpc[found].hrd, (const void *)hrdn, DADDLEN);
memcpy ((void *)arpc[found].ip, (const void *)ipn, 4);
arpc[found].tm = n_clicks();
arpc[found].valid_entry = 1;
arptime = 0L; /* reset, allow more arps */
return (found);
} /* end cacheupdate */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* cachelook */
/* */
/* DESCRIPTION */
/* */
/* Look up information in the cache */
/* returns the cache entry number for the IP number given. */
/* Returns -1 on no valid entry, also if the entry present is too old. */
/* doarp is a flag for non-gateway requests which determines whether an*/
/* arp will be sent or not. */
/* */
/* CALLED BY */
/* getdlayer */
/* */
/* CALLS */
/* */
/* n_clicks */
/* arp_request Send out an arp request packet */
/* */
/*************************************************************************/
int16 cachelook(uint8 *ipn, int16 gate, int16 doarp)
{
int16 i,haveg;
/*
* First option, we are not looking for a gateway, but a host on our
* local network.
*/
if (!gate)
{
for (i = 0; i < CACHELEN; i++)
{
if ((comparen (ipn, arpc[i].ip, 4))
&& (INT32_CMP((arpc[i].tm + CACHETO), n_clicks()) > 0)
&& arpc[i].valid_entry)
{
return (i);
}
} /* end for CACHELEN */
/*
* no valid entry, send an ARP
*/
if ((INT32_CMP(n_clicks(), arptime) >= 0) && doarp)
{ /* check time limit */
arp_request (ipn); /* put out a broadcast request */
arptime = n_clicks () + ARPTO;
}
} /* if !gate */
else
{
/*
* Second option, we need a gateway.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -