lwip-users
[Top][All Lists]
Advanced

[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.]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]