arp.c
ubixos/types.h
lib/kprintf.h
net/debug.h
net/ipv4/inet.h
netif/arp.h
net/ipv4/ip.h
net/ipv4/ip.h
arch/lib.h
net/netif.h
arch/cpu.h
netif/arp.h
ubixos/types.h
sys/_types.h
net/arch.h
src/sys/net/netif/arp.c
net/lwipopts.h
net/def.h
lib/kprintf.h
net/ipv4/ip_addr.h
net/err.h
net/opt.h
net/pbuf.h
net/debug.h
net/ipv4/inet.h
arch/cc.h
arp_entry
arp_hdr
ethip_hdr
ARP_MAXAGE
2
arp_tmr
ARP_REPLY
2
arp_arp_input
ARP_REQUEST
1
arp_arp_input
arp_query
ARPH_HWLEN
hdr
(NTOHS((hdr)->_hwlen_protolen) >> 8)
ARPH_HWLEN_SET
hdr
len
(hdr)->_hwlen_protolen = HTONS(ARPH_PROTOLEN(hdr) | ((len) << 8))
arp_arp_input
arp_query
ARPH_PROTOLEN
hdr
(NTOHS((hdr)->_hwlen_protolen) & 0xff)
ARPH_PROTOLEN_SET
hdr
len
(hdr)->_hwlen_protolen = HTONS((len) | (ARPH_HWLEN(hdr) << 8))
arp_arp_input
arp_query
HWTYPE_ETHERNET
1
arp_arp_input
arp_query
void static void add_arp_entry (struct ip_addr *ipaddr, struct eth_addr *ethaddr) add_arp_entry struct ip_addr * ipaddr struct eth_addr * ethaddr arp_table ARP_TABLE_SIZE ctime arp_entry::ctime arp_entry::ethaddr ip_addr_cmp ip_addr_isany ip_addr_set arp_entry::ipaddr arp_arp_input arp_ip_input
pbuf * struct pbuf* arp_arp_input (struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) arp_arp_input struct netif * netif struct eth_addr * ethaddr struct pbuf * p add_arp_entry ARP_REPLY ARP_REQUEST ARPH_HWLEN_SET ARPH_PROTOLEN_SET ETHTYPE_ARP ETHTYPE_IP htons HWTYPE_ETHERNET netif::ip_addr ip_addr_cmp ip_addr_set kprintf NULL pbuf::payload pbuf_free pbuf::tot_len ethernetif_input
void void arp_init (void) arp_init void arp_table ARP_TABLE_SIZE IP_ADDR_ANY ip_addr_set arp_entry::ipaddr ethernetif_init
void void arp_ip_input (struct netif *netif, struct pbuf *p) arp_ip_input struct netif * netif struct pbuf * p add_arp_entry ARP_DEBUG DEBUGF netif::ip_addr ip_addr_maskcmp netif::netmask pbuf::payload ethernetif_input
eth_addr * struct eth_addr* arp_lookup (struct ip_addr *ipaddr) arp_lookup struct ip_addr * ipaddr arp_table ARP_TABLE_SIZE ip_addr_cmp NULL ethernetif_output
pbuf * struct pbuf* arp_query (struct netif *netif, struct eth_addr *ethaddr, struct ip_addr *ipaddr) arp_query struct netif * netif struct eth_addr * ethaddr struct ip_addr * ipaddr ARP_REQUEST ARPH_HWLEN_SET ARPH_PROTOLEN_SET ETHTYPE_ARP ETHTYPE_IP htons HWTYPE_ETHERNET netif::ip_addr ip_addr_set NULL pbuf::payload pbuf_alloc PBUF_LINK PBUF_RAM ethernetif_output
void void arp_tmr (void) arp_tmr void ARP_DEBUG ARP_MAXAGE arp_table ARP_TABLE_SIZE ctime DEBUGF IP_ADDR_ANY ip_addr_isany ip_addr_set arp_entry::ipaddr arp_timer
struct arp_entry struct arp_entry arp_table[ARP_TABLE_SIZE] [ARP_TABLE_SIZE] arp_table add_arp_entry arp_init arp_lookup arp_tmr
uInt8 uInt8 ctime ctime add_arp_entry arp_tmr
PACK_STRUCT_BEGIN struct arp_hdr PACK_STRUCT_BEGIN struct arp_hdr PACK_STRUCT_STRUCT PACK_STRUCT_STRUCT

    /*
    *Copyright(c)2001,SwedishInstituteofComputerScience.
    *Allrightsreserved.
    *
    *Redistributionanduseinsourceandbinaryforms,withorwithout
    *modification,arepermittedprovidedthatthefollowingconditions
    *aremet:
    *1.Redistributionsofsourcecodemustretaintheabovecopyright
    *notice,thislistofconditionsandthefollowingdisclaimer.
    *2.Redistributionsinbinaryformmustreproducetheabovecopyright
    *notice,thislistofconditionsandthefollowingdisclaimerinthe
    *documentationand/orothermaterialsprovidedwiththedistribution.
    *3.NeitherthenameoftheInstitutenorthenamesofitscontributors
    *maybeusedtoendorseorpromoteproductsderivedfromthissoftware
    *withoutspecificpriorwrittenpermission.
    *
    *THISSOFTWAREISPROVIDEDBYTHEINSTITUTEANDCONTRIBUTORS``ASIS''AND
    *ANYEXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THE
    *IMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSE
    *AREDISCLAIMED.INNOEVENTSHALLTHEINSTITUTEORCONTRIBUTORSBELIABLE
    *FORANYDIRECT,INDIRECT,INCIDENTAL,SPECIAL,EXEMPLARY,ORCONSEQUENTIAL
    *DAMAGES(INCLUDING,BUTNOTLIMITEDTO,PROCUREMENTOFSUBSTITUTEGOODS
    *ORSERVICES;LOSSOFUSE,DATA,ORPROFITS;ORBUSINESSINTERRUPTION)
    *HOWEVERCAUSEDANDONANYTHEORYOFLIABILITY,WHETHERINCONTRACT,STRICT
    *LIABILITY,ORTORT(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAY
    *OUTOFTHEUSEOFTHISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOF
    *SUCHDAMAGE.
    *
    *ThisfileispartofthelwIPTCP/IPstack.
    *
    *Author:AdamDunkels<adam@sics.se>
    *
    *$Id: arp_8c.xml 88 2016-01-12 00:11:29Z reddawg $
    *
    */

    #include<ubixos/types.h>
    #include<lib/kprintf.h>

    #include"net/debug.h"
    #include"net/ipv4/inet.h"
    #include"netif/arp.h"
    #include"net/ipv4/ip.h"

    #defineARP_MAXAGE2/*120*10seconds=20minutes.*/

    #defineHWTYPE_ETHERNET1

    #defineARP_REQUEST1
    #defineARP_REPLY2

    /*MUSTbecompiledwith"packstructs"orequivalent!*/
    PACK_STRUCT_BEGIN
    structarp_hdr{
    PACK_STRUCT_FIELD(structeth_hdrethhdr);
    PACK_STRUCT_FIELD(uInt16hwtype);
    PACK_STRUCT_FIELD(uInt16proto);
    PACK_STRUCT_FIELD(uInt16_hwlen_protolen);
    PACK_STRUCT_FIELD(uInt16opcode);
    PACK_STRUCT_FIELD(structeth_addrshwaddr);
    PACK_STRUCT_FIELD(structip_addrsipaddr);
    PACK_STRUCT_FIELD(structeth_addrdhwaddr);
    PACK_STRUCT_FIELD(structip_addrdipaddr);
    }PACK_STRUCT_STRUCT;
    PACK_STRUCT_END

    #defineARPH_HWLEN(hdr)(NTOHS((hdr)->_hwlen_protolen)>>8)
    #defineARPH_PROTOLEN(hdr)(NTOHS((hdr)->_hwlen_protolen)&0xff)

    #defineARPH_HWLEN_SET(hdr,len)(hdr)->_hwlen_protolen=HTONS(ARPH_PROTOLEN(hdr)|((len)<<8))
    #defineARPH_PROTOLEN_SET(hdr,len)(hdr)->_hwlen_protolen=HTONS((len)|(ARPH_HWLEN(hdr)<<8))

    PACK_STRUCT_BEGIN
    structethip_hdr{
    PACK_STRUCT_FIELD(structeth_hdreth);
    PACK_STRUCT_FIELD(structip_hdrip);
    };
    PACK_STRUCT_END

    structarp_entry{
    structip_addripaddr;
    structeth_addrethaddr;
    uInt8ctime;
    };

    staticstructarp_entryarp_table[ARP_TABLE_SIZE];
    staticuInt8ctime;

    /*-----------------------------------------------------------------------------------*/
    void
    arp_init(void)
    {
    uInt8i;

    for(i=0;i<ARP_TABLE_SIZE;++i){
    ip_addr_set(&(arp_table[i].ipaddr),
    IP_ADDR_ANY);
    }
    }
    /*-----------------------------------------------------------------------------------*/
    void
    arp_tmr(void)
    {
    uInt8i;

    ++ctime;
    for(i=0;i<ARP_TABLE_SIZE;++i){
    if(!ip_addr_isany(&arp_table[i].ipaddr)&&
    ctime-arp_table[i].ctime>=ARP_MAXAGE){
    DEBUGF(ARP_DEBUG,("arp_timer:expiredentry%d.\n",i));
    ip_addr_set(&(arp_table[i].ipaddr),
    IP_ADDR_ANY);
    }
    }
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    add_arp_entry(structip_addr*ipaddr,structeth_addr*ethaddr)
    {
    uInt8i,j,k;
    uInt8maxtime;

    /*WalkthroughtheARPmappingtableandtrytofindanentryto
    update.Ifnoneisfound,theIP->MACaddressmappingis
    insertedintheARPtable.*/
    for(i=0;i<ARP_TABLE_SIZE;++i){

    /*Onlycheckthoseentriesthatareactuallyinuse.*/
    if(!ip_addr_isany(&arp_table[i].ipaddr)){
    /*CheckifthesourceIPaddressoftheincomingpacketmatches
    theIPaddressinthisARPtableentry.*/
    if(ip_addr_cmp(ipaddr,&arp_table[i].ipaddr)){
    /*Anoldentryfound,updatethisandreturn.*/
    for(k=0;k<6;++k){
    arp_table[i].ethaddr.addr[k]=ethaddr->addr[k];
    }
    arp_table[i].ctime=ctime;
    return;
    }
    }
    }

    /*Ifwegethere,noexistingARPtableentrywasfound,sowe
    createone.*/

    /*First,wetrytofindanunusedentryintheARPtable.*/
    for(i=0;i<ARP_TABLE_SIZE;++i){
    if(ip_addr_isany(&arp_table[i].ipaddr)){
    break;
    }
    }

    /*Ifnounusedentryisfound,wetrytofindtheoldestentryand
    throwitaway.*/
    if(i==ARP_TABLE_SIZE){
    maxtime=0;
    j=0;
    for(i=0;i<ARP_TABLE_SIZE;++i){
    if(ctime-arp_table[i].ctime>maxtime){
    maxtime=ctime-arp_table[i].ctime;
    j=i;
    }
    }
    i=j;
    }

    /*Now,iistheARPtableentrywhichwewillfillwiththenew
    information.*/
    ip_addr_set(&arp_table[i].ipaddr,ipaddr);
    for(k=0;k<6;++k){
    arp_table[i].ethaddr.addr[k]=ethaddr->addr[k];
    }
    arp_table[i].ctime=ctime;
    return;

    }
    /*-----------------------------------------------------------------------------------*/
    void
    arp_ip_input(structnetif*netif,structpbuf*p)
    {
    structethip_hdr*hdr;

    hdr=p->payload;

    /*Onlyinsert/updateanentryifthesourceIPaddressofthe
    incomingIPpacketcomesfromahostonthelocalnetwork.*/
    if(!ip_addr_maskcmp(&(hdr->ip.src),&(netif->ip_addr),&(netif->netmask))){
    return;
    }
    DEBUGF(ARP_DEBUG,("arp_ip_input:updatingARPtable.\n"));
    add_arp_entry(&(hdr->ip.src),&(hdr->eth.src));
    }
    /*-----------------------------------------------------------------------------------*/
    structpbuf*
    arp_arp_input(structnetif*netif,structeth_addr*ethaddr,structpbuf*p)
    {
    structarp_hdr*hdr;
    uInt8i;

    if(p->tot_len<sizeof(structarp_hdr)){
    kprintf("arp_arp_input:packettooshort(%d/%d)\n",p->tot_len,sizeof(structarp_hdr));
    pbuf_free(p);
    returnNULL;
    }

    hdr=p->payload;

    switch(htons(hdr->opcode)){
    caseARP_REQUEST:
    /*ARPrequest.Ifitaskedforouraddress,wesendouta
    reply.*/
    if(ip_addr_cmp(&(hdr->dipaddr),&(netif->ip_addr))){
    hdr->opcode=htons(ARP_REPLY);

    ip_addr_set(&(hdr->dipaddr),&(hdr->sipaddr));
    ip_addr_set(&(hdr->sipaddr),&(netif->ip_addr));

    for(i=0;i<6;++i){
    hdr->dhwaddr.addr[i]=hdr->shwaddr.addr[i];
    hdr->shwaddr.addr[i]=ethaddr->addr[i];
    hdr->ethhdr.dest.addr[i]=hdr->dhwaddr.addr[i];
    hdr->ethhdr.src.addr[i]=ethaddr->addr[i];
    }

    hdr->hwtype=htons(HWTYPE_ETHERNET);
    ARPH_HWLEN_SET(hdr,6);

    hdr->proto=htons(ETHTYPE_IP);
    ARPH_PROTOLEN_SET(hdr,sizeof(structip_addr));

    hdr->ethhdr.type=htons(ETHTYPE_ARP);
    returnp;
    }
    break;
    caseARP_REPLY:
    /*ARPreply.WeinsertorupdatetheARPtable.*/
    if(ip_addr_cmp(&(hdr->dipaddr),&(netif->ip_addr))){
    add_arp_entry(&(hdr->sipaddr),&(hdr->shwaddr));
    }
    break;
    default:
    kprintf("arp_arp_input:unknowntype%d\n",htons(hdr->opcode));
    break;
    }

    pbuf_free(p);
    returnNULL;
    }
    /*-----------------------------------------------------------------------------------*/
    structeth_addr*
    arp_lookup(structip_addr*ipaddr)
    {
    uInt8i;

    for(i=0;i<ARP_TABLE_SIZE;++i){
    if(ip_addr_cmp(ipaddr,&arp_table[i].ipaddr)){
    return&arp_table[i].ethaddr;
    }
    }
    returnNULL;
    }
    /*-----------------------------------------------------------------------------------*/
    structpbuf*
    arp_query(structnetif*netif,structeth_addr*ethaddr,structip_addr*ipaddr)
    {
    structarp_hdr*hdr;
    structpbuf*p;
    uInt8i;

    p=pbuf_alloc(PBUF_LINK,sizeof(structarp_hdr),PBUF_RAM);
    if(p==NULL){
    returnNULL;
    }

    hdr=p->payload;

    hdr->opcode=htons(ARP_REQUEST);

    for(i=0;i<6;++i){
    hdr->dhwaddr.addr[i]=0x00;
    hdr->shwaddr.addr[i]=ethaddr->addr[i];
    }

    ip_addr_set(&(hdr->dipaddr),ipaddr);
    ip_addr_set(&(hdr->sipaddr),&(netif->ip_addr));

    hdr->hwtype=htons(HWTYPE_ETHERNET);
    ARPH_HWLEN_SET(hdr,6);

    hdr->proto=htons(ETHTYPE_IP);
    ARPH_PROTOLEN_SET(hdr,sizeof(structip_addr));

    for(i=0;i<6;++i){
    hdr->ethhdr.dest.addr[i]=0xff;
    hdr->ethhdr.src.addr[i]=ethaddr->addr[i];
    }

    hdr->ethhdr.type=htons(ETHTYPE_ARP);
    returnp;
    }
    /*-----------------------------------------------------------------------------------*/