[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-users] [lwip] modified arp.c filr
From: |
Mumtaz Ahmad |
Subject: |
[lwip-users] [lwip] modified arp.c filr |
Date: |
Wed, 08 Jan 2003 22:43:32 -0000 |
Hi
A modified arp.c file. Hopefully this file wont have any structure packing
problems .This file is running successfully on Trimedia .
Regards
Mumtaz Ahmad
#include "lwip/debug.h"
#include "lwip/inet.h"
#include "netif/arp.h"
#include "lwip/ip.h"
#if LWIP_DHCP
# include "lwip/dhcp.h"
#endif
#define ARP_MAXAGE 2 /* 120 * 10 seconds = 20 minutes. */
#define HWTYPE_ETHERNET 1
#define ARP_REQUEST 1
#define ARP_REPLY 2
struct arp_hdr {
u8_t ethhdr_dest[6];
u8_t ethhdr_src[6];
u8_t ethhdr_type[2];
u8_t hwtype[2];
u8_t proto[2];
u8_t _hwlen_protolen[2];
u8_t opcode[2];
u8_t shwaddr[6];
u8_t sipaddr[4];
u8_t dhwaddr[6];
u8_t dipaddr[4];
};
struct ethip_hdr {
u8_t ethhdr_dest[6];
u8_t ethhdr_src[6];
u8_t ethhdr_type[2];
u16_t _v_hl_tos; /* version / header length / type of service
*/
u16_t _len; /* total length */
u16_t _id; /* identification */
u16_t _offset; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u16_t _ttl_proto; /* time to live / protocol*/
u16_t _chksum; /* checksum */
u8_t iphdr_src[4], iphdr_dest[4]; /* source and destination IP addresses
*/
};
struct arp_entry {
u8_t ipaddr[4];
u8_t ethaddr[6];
u8_t time;
};
static struct arp_entry arp_table[ARP_TABLE_SIZE];
static u8_t time;
/*--------------------------------------------------------------------------
---------*/
void
arp_init(void)
{
u8_t i, j;
for(i = 0; i < ARP_TABLE_SIZE; i++)
for(j=0; j<4; j++)
arp_table[i].ipaddr[j]=0;
}
/*--------------------------------------------------------------------------
---------*/
void
arp_tmr(void)
{
u8_t i, j;
++time;
for(i = 0; i < ARP_TABLE_SIZE; ++i) {
if((arp_table[i].ipaddr[0]!=0) && (time-arp_table[i].time >=
ARP_MAXAGE))
{
DEBUGF(ARP_DEBUG, ("arp_timer: expired entry %d.\n", i));
/*initialize ip addr to 0*/
for(j=0; j<4; j++) arp_table[i].ipaddr[j]=0;
}
}
}
/*--------------------------------------------------------------------------
---------*/
static void
add_arp_entry(u8_t *ipaddr, u8_t *ethaddr)
{
u8_t i, j, k, go=0;
u8_t maxtime;
/*Walk thru the ARP mapping table and try to find an entry to
update. If none is found, the IP->MAC address mapping is
inserted in the ARPtable*/
for(i=0; i<ARP_TABLE_SIZE; ++i)
{
/*only check those entries that are actually in use*/
if(arp_table[i].ipaddr[0] != 0)
{
/*check if the soruce IP addr of the incoming packet matches
the IP addr in this ARP table entry*/
for(j=0; j<4; j++)
{
if(*(ipaddr+j)==arp_table[i].ipaddr[j]) go=1;
else go=0;
}
if(go==1)
{
/*An old entry found, update this and return*/
for(k=0; k<6; ++k) arp_table[i].ethaddr[k]=*(ethaddr+k);
arp_table[i].time=time;
return;
}//end of if
}//end of if
}//end of for
/*If we get here, no existing ARTP table entry was found, so we create
one*/
/*First we try to find an unused entry in the ARP table*/
for(i=0; i<ARP_TABLE_SIZE; ++i) {
if(arp_table[i].ipaddr[0]==0) break;
}
/*if no unused entry is found, we try to find the oldest entry and
throw it away*/
if(i==ARP_TABLE_SIZE) {
maxtime=0;
j=0;
for(i=0; i<ARP_TABLE_SIZE; ++i)
if(time-arp_table[i].time > maxtime) {
maxtime=time-arp_table[i].time;
j=i;
}//end of if
i=j;
}//end of outer if
/*Now, i is the ARP Table entry which we will fill with
the new information*/
for(j=0; j<4; j++)
arp_table[i].ipaddr[j]=*(ipaddr+j);
for(k=0; k<6; ++k)
arp_table[i].ethaddr[k]=*(ethaddr+k);
arp_table[i].time=time;
/*checking*/
return;
}
/*--------------------------------------------------------------------------
---------*/
void
arp_ip_input(struct netif *netif, struct pbuf *p)
{
struct ethip_hdr *hdr;
u32_t temp, netmsk, netip;
hdr = p->payload;
temp=hdr->iphdr_src[3];
temp=(temp<<8);
temp= temp | hdr->iphdr_src[2];
temp=(temp<<8);
temp= temp | hdr->iphdr_src[1];
temp=(temp<<8);
temp= temp | hdr->iphdr_src[0];
netmsk=(&(netif->netmask))->addr;
netip=(&(netif->ip_addr))->addr;
/*only insert/update an entry if the source IP address of the
incoming Ip packet comes from a host on the local network.*/
if((temp & netmsk)!=(netip & netmsk)) return;
DEBUGF(ARP_DEBUG, ("arp_ip_input: updating ARP table.\n"));
add_arp_entry(hdr->iphdr_src, hdr->ethhdr_src);
}
/*--------------------------------------------------------------------------
---------*/
struct pbuf *
arp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
struct arp_hdr *hdr;
u8_t i, temp[4], j;
u16_t code=0, type=0;
u32_t k;
int a;
if(p->tot_len < sizeof(struct arp_hdr)) {
DEBUGF(ARP_DEBUG, ("arp_arp_input: packet too short (%d/%d)\n",
p->tot_len, sizeof(struct arp_hdr)));
pbuf_free(p);
return NULL;
}
hdr = p->payload;
code=hdr->opcode[1];
code=code<<8;
code=code | hdr->opcode[0];
switch(htons(code)) {
case ARP_REQUEST:
/*ARP request, if it asked for our addr, we sent out a reply*/
DEBUGF(ARP_DEBUG, ("arp_arp_input: ARP request\n"));
/*compare dipaddr in arp hdr to netif ipaddr*/
k=(&(netif->ip_addr))->addr;
temp[0]=k;
temp[1]=k >> 8;
temp[2]=k >> 16;
temp[3]=k >> 24;
for(j=0; j<4; j++)
if(hdr->dipaddr[j]==temp[j]){
hdr->opcode[1]=ARP_REPLY;
hdr->opcode[0]=0;
/*set dipaddr, sipaddr in arp hdr*/
for(j=0; j<4; j++) {
hdr->dipaddr[j]=hdr->sipaddr[j];
hdr->sipaddr[j]=temp[j];
}
for(i=0; i<6; ++i) {
hdr->dhwaddr[i]=hdr->shwaddr[i];
hdr->shwaddr[i]=ethaddr->addr[i];
hdr->ethhdr_dest[i]=hdr->dhwaddr[i];
hdr->ethhdr_src[i]=ethaddr->addr[i];
}
type=htons(HWTYPE_ETHERNET);
hdr->hwtype[1]=type;
hdr->hwtype[0]=type>>8;
hdr->_hwlen_protolen[0]=sizeof(struct ip_addr);
hdr->_hwlen_protolen[1]=6;
a=ETHTYPE_ARP;
hdr->ethhdr_type[1]=a;
hdr->ethhdr_type[0]=a>>8;
return p;
}//end of if
break;
case ARP_REPLY:
/*ARP reply. We insert or update the ARP table*/
DEBUGF(ARP_DEBUG, ("arp_arp_input: ARP reply\n"));
/*compare dipaddr in arp hdr to netif ipaddr*/
k=(&(netif->ip_addr))->addr;
temp[0]=k;
temp[1]=k >> 8;
temp[2]=k >> 16;
temp[3]=k >> 24;
for(j=0; j<4; j++)
if(hdr->dipaddr[j]==temp[j])
add_arp_entry(hdr->sipaddr, hdr->shwaddr);
break;
default:
DEBUGF(ARP_DEBUG, ("arp_arp_input: unknown type %d\n",
htons(hdr->opcode[0])));
break;
}
pbuf_free(p);
return NULL;
}
/*--------------------------------------------------------------------------
---------*/
struct eth_addr *arp_lookup(struct ip_addr *ipaddr)
{
u8_t i, temp[4], j;
u32_t k;
k=ipaddr->addr;
temp[0]=k;
temp[1]=k >> 8;
temp[2]=k >> 16;
temp[3]=k >> 24;
for(i=0; i<ARP_TABLE_SIZE; ++i)
for(j=0; j<4; j++)
if(arp_table[i].ipaddr[j]==temp[j])
return (struct eth_addr *)arp_table[i].ethaddr;
return NULL;
}
/*--------------------------------------------------------------------------
---------*/
struct pbuf *
arp_query(struct netif *netif, struct eth_addr *ethaddr, struct ip_addr
*ipaddr)
{
struct arp_hdr *hdr;
struct pbuf *p;
u8_t i,j, temp[4];
u32_t k;
int a;
p=pbuf_alloc(PBUF_LINK, sizeof(struct arp_hdr), PBUF_RAM);
if(p==NULL) {
return NULL;
}
hdr=p->payload;
hdr->opcode[1]=ARP_REQUEST;
hdr->opcode[0]=0;
for(i=0; i<6; ++i) {
hdr->dhwaddr[i]=0xff;
hdr->shwaddr[i]=ethaddr->addr[i];
}
/*set dipaddr in arp hdr equal to the parameter ipaddr*/
k=ipaddr->addr;
temp[0]=k;
temp[1]=k >> 8;
temp[2]=k >> 16;
temp[3]=k >> 24;
for(j=0; j<4; j++)
hdr->dipaddr[j]=temp[j];
/*set sipaddr in arp hdr equal to the parameter netif ipaddr*/
k=(&(netif->ip_addr))->addr;
temp[0]=k;
temp[1]=k >> 8;
temp[2]=k >> 16;
temp[3]=k >> 24;
for(j=0; j<4; j++)
hdr->sipaddr[j]=temp[j];
hdr->hwtype[0]=HWTYPE_ETHERNET;
hdr->_hwlen_protolen[0]=6;
hdr->_hwlen_protolen[1]=sizeof(struct ip_addr);
for(i=0; i<6; ++i) {
hdr->ethhdr_dest[i]=0xff;
hdr->ethhdr_src[i]=ethaddr->addr[i];
}
a=ETHTYPE_ARP;
hdr->ethhdr_type[1]=a;
hdr->ethhdr_type[0]=a>>8;
return p;
}
/*--------------------------------------------------------------------------
---------*/
[This message was sent through the lwip discussion list.]
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lwip-users] [lwip] modified arp.c filr,
Mumtaz Ahmad <=