ethernetif.c
ubixos/types.h
ubixos/sched.h
lib/kmalloc.h
lib/kprintf.h
sys/device.old.h
isa/ne2k.h
net/debug.h
net/opt.h
net/def.h
net/mem.h
net/pbuf.h
net/sys.h
netif/arp.h
sys/thread.h
arch/lib.h
ubixos/sched.h
net/netif.h
sys/device.old.h
isa/ne2k.h
arch/cpu.h
netif/arp.h
arch/sys_arch.h
ubixos/types.h
sys/_types.h
src/sys/net/netif/ethernetif.c
net/arch.h
vfs/file.h
sys/tss.h
lib/kmalloc.h
net/lwipopts.h
net/def.h
net/mem.h
vfs/vfs.h
vfs/mount.h
lib/kprintf.h
net/ipv4/ip_addr.h
net/err.h
ubixfs/dirCache.h
net/opt.h
sys/sysproto.h
ubixos/elf.h
sys/signal.h
net/sys.h
ubixos/tty.h
net/pbuf.h
net/debug.h
net/ipv4/inet.h
arch/cc.h
ethernetif
IFNAME0
'e'
ethernetif_init
IFNAME1
'd'
ethernetif_init
void static void arp_timer (void *arg) arp_timer void * arg arp_tmr ARP_TMR_INTERVAL NULL sys_timeout ethernetif_init
void void ethernetif_init (struct netif *netif) ethernetif_init struct netif * netif arp_init arp_timer ARP_TMR_INTERVAL ethernetif_output netif::hwaddr IFNAME0 IFNAME1 netif::linkoutput low_level_init low_level_output mem_malloc netif::name NULL netif::output netif::state sys_timeout netMainThread
void static void ethernetif_input (struct netif *netif) ethernetif_input struct netif * netif arp_arp_input arp_ip_input ethernetif::ethaddr ETHTYPE_ARP ETHTYPE_IP htons netif::input low_level_input low_level_output NULL pbuf::payload pbuf_free pbuf_header netif::state ethernetif_thread
err_t static err_t ethernetif_output (struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) ethernetif_output struct netif * netif struct pbuf * p struct ip_addr * ipaddr arp_lookup arp_query ERR_MEM ethernetif::ethaddr ethbroadcast ETHTYPE_IP netif::gw htons ip4_addr2 ip4_addr3 ip4_addr4 netif::ip_addr ip_addr_isany ip_addr_isbroadcast ip_addr_ismulticast ip_addr_maskcmp low_level_output netif::netmask NULL pbuf::payload pbuf_alloc pbuf_chain pbuf_free pbuf_header PBUF_LINK PBUF_RAM netif::state ethernetif_init
void void ethernetif_thread (void *arg) ethernetif_thread void * arg ethernetif_input nicBuffer::length ne2kFreeBuffer ne2kGetBuffer tmpBuf
void static void ethernetif_thread () ethernetif_thread low_level_init
void static void low_level_init (struct netif *netif) low_level_init struct netif * netif dev ethernetif::ethaddr ethernetif_thread device::ioAddr device::irq kmalloc kprintf netif::state sys_thread_new ethernetif_init
struct pbuf * static struct pbuf* low_level_input (struct ethernetif *ethernetif) low_level_input struct ethernetif * ethernetif bcopy nicBuffer::buffer pbuf::len nicBuffer::length pbuf::next NULL pbuf::payload pbuf_alloc PBUF_LINK PBUF_POOL tmpBuf ethernetif_input
err_t static err_t low_level_output (struct ethernetif *ethernetif, struct pbuf *p) low_level_output struct ethernetif * ethernetif struct pbuf * p bcopy dev ERR_OK device::ioAddr device::irq pbuf::len pbuf::next NULL pbuf::payload PCtoNIC pbuf::tot_len ethernetif_init ethernetif_input ethernetif_output
device * struct device* dev dev 0x0 dp_pkt2user dp_recv fdcInit2 getblock hdInit low_level_init low_level_output NICtoPC pci_init PCtoNIC
struct eth_addr struct eth_addr ethbroadcast ethbroadcast {{0xff,0xff,0xff,0xff,0xff,0xff}} ethernetif_output
nicBuffer * struct nicBuffer* tmpBuf tmpBuf 0x0 dp_pkt2user ethernetif_thread low_level_input ne2kAllocBuffer ne2kGetBuffer

    /*
    *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: ethernetif_8c.xml 88 2016-01-12 00:11:29Z reddawg $
    */

    /*
    *ThisfileisaskeletonfordevelopingEthernetnetworkinterface
    *driversforlwIP.Addcodetothelow_levelfunctionsanddoa
    *search-and-replacefortheword"ethernetif"toreplaceitwith
    *somethingthatbetterdescribesyournetworkinterface.
    */

    #include<ubixos/types.h>
    #include<ubixos/sched.h>
    #include<lib/kmalloc.h>
    #include<lib/kprintf.h>
    #include<sys/device.old.h>
    #include<isa/ne2k.h>

    #include"net/debug.h"

    #include"net/opt.h"
    #include"net/def.h"
    #include"net/mem.h"
    #include"net/pbuf.h"
    #include"net/sys.h"

    #include"netif/arp.h"

    /*Definethosetobetterdescribeyournetworkinterface.*/
    #defineIFNAME0'e'
    #defineIFNAME1'd'

    structnicBuffer*tmpBuf=0x0;

    structethernetif{
    structeth_addr*ethaddr;
    /*Addwhateverper-interfacestatethatisneededhere.*/
    };

    staticconststructeth_addrethbroadcast={{0xff,0xff,0xff,0xff,0xff,0xff}};

    /*Forwarddeclarations.*/
    staticvoidethernetif_input(structnetif*netif);
    staticerr_tethernetif_output(structnetif*netif,structpbuf*p,structip_addr*ipaddr);
    staticvoidethernetif_thread();
    structdevice*dev=0x0;

    /*-----------------------------------------------------------------------------------*/
    staticvoidlow_level_init(structnetif*netif){
    structethernetif*ethernetif;

    ethernetif=netif->state;
    dev=(structdevice*)kmalloc(sizeof(structdevice));
    dev->ioAddr=0x280;
    dev->irq=0x10;

    /*ObtainMACaddressfromnetworkinterface.*/
    ethernetif->ethaddr->addr[0]=0x00;
    ethernetif->ethaddr->addr[1]=0x00;
    ethernetif->ethaddr->addr[2]=0xC0;
    ethernetif->ethaddr->addr[3]=0x97;
    ethernetif->ethaddr->addr[4]=0xC6;
    ethernetif->ethaddr->addr[5]=0x93;

    /*Dowhateverelseisneededtoinitializeinterface.*/
    kprintf("NETIF:[0x%X:0x%X]\n",netif,ethernetif_thread);
    sys_thread_new(ethernetif_thread,netif);

    }
    /*-----------------------------------------------------------------------------------*/
    /*
    *low_level_output():
    *
    *Shoulddotheactualtransmissionofthepacket.Thepacketis
    *containedinthepbufthatispassedtothefunction.Thispbuf
    *mightbechained.
    *
    */
    /*-----------------------------------------------------------------------------------*/

    staticerr_tlow_level_output(structethernetif*ethernetif,structpbuf*p){
    structpbuf*q;
    charbuf[1500];
    char*bufptr=0x0;

    dev->ioAddr=0x280;
    dev->irq=10;

    bufptr=&buf[0];

    for(q=p;q!=NULL;q=q->next){
    bcopy(q->payload,bufptr,q->len);
    bufptr+=q->len;
    }
    PCtoNIC(dev,buf,p->tot_len);
    //kprintf("SendingData[%i]\n",p->tot_len);
    returnERR_OK;
    }

    /*-----------------------------------------------------------------------------------*/
    /*
    *low_level_input():
    *
    *Shouldallocateapbufandtransferthebytesoftheincoming
    *packetfromtheinterfaceintothepbuf.
    *
    */
    /*-----------------------------------------------------------------------------------*/
    staticstructpbuf*low_level_input(structethernetif*ethernetif){
    structpbuf*p,*q;
    uInt16len;
    char*bufptr;
    char*buf;

    len=tmpBuf->length;
    bufptr=tmpBuf->buffer;

    /*Weallocateapbufchainofpbufsfromthepool.*/
    p=pbuf_alloc(PBUF_LINK,len,PBUF_POOL);

    if(p!=NULL){
    /*Weiterateoverthepbufchainuntilwehavereadtheentire
    packetintothepbuf.*/
    //bufptr=&buf[0];
    for(q=p;q!=NULL;q=q->next){
    /*Readenoughbytestofillthispbufinthechain.The
    avaliabledatainthepbufisgivenbytheq->len
    variable.*/
    /*readdatainto(q->payload,q->len);*/
    bcopy(bufptr,q->payload,q->len);
    buf=q->payload;
    bufptr+=q->len;
    }
    /*acknowledgethatpackethasbeenread();*/
    }else{
    /*droppacket();*/
    }
    returnp;
    }

    /*-----------------------------------------------------------------------------------*/
    /*
    *ethernetif_output():
    *
    *ThisfunctioniscalledbytheTCP/IPstackwhenanIPpacket
    *shouldbesent.Itcallsthefunctioncalledlow_level_output()to
    *dotheactualltransmissionofthepacket.
    *
    */
    /*-----------------------------------------------------------------------------------*/
    staticerr_tethernetif_output(structnetif*netif,structpbuf*p,structip_addr*ipaddr){
    structethernetif*ethernetif;
    structpbuf*q;
    structeth_hdr*ethhdr;
    structeth_addr*dest,mcastaddr;
    structip_addr*queryaddr;
    err_terr;
    uInt8i;

    ethernetif=netif->state;

    /*MakeroomforEthernetheader.*/
    if(pbuf_header(p,sizeof(structeth_hdr))!=0){
    /*Thepbuf_header()callshouldn'tfail,butweallocateanextra
    pbufjustincase.*/
    q=pbuf_alloc(PBUF_LINK,sizeof(structeth_hdr),PBUF_RAM);
    if(q==NULL){
    returnERR_MEM;
    }
    pbuf_chain(q,p);
    p=q;
    }

    /*ConstructEthernetheader.Startwithlookingupdecidingwhich
    MACaddresstouseasadestinationaddress.Broadcastsand
    multicastsarespecial,allotheraddressesarelookedupinthe
    ARPtable.*/
    queryaddr=ipaddr;
    if(ip_addr_isany(ipaddr)||
    ip_addr_isbroadcast(ipaddr,&(netif->netmask))){
    dest=(structeth_addr*)&ethbroadcast;
    }elseif(ip_addr_ismulticast(ipaddr)){
    /*HashIPmulticastaddresstoMACaddress.*/
    mcastaddr.addr[0]=0x01;
    mcastaddr.addr[1]=0x0;
    mcastaddr.addr[2]=0x5e;
    mcastaddr.addr[3]=ip4_addr2(ipaddr)&0x7f;
    mcastaddr.addr[4]=ip4_addr3(ipaddr);
    mcastaddr.addr[5]=ip4_addr4(ipaddr);
    dest=&mcastaddr;
    }else{
    if(ip_addr_maskcmp(ipaddr,&(netif->ip_addr),&(netif->netmask))){
    /*UsedestinationIPaddressifthedestinationisonthesame
    subnetasweare.*/
    queryaddr=ipaddr;
    }else{
    /*Otherwiseweusethedefaultrouterastheaddresstosend
    theEthernetframeto.*/
    queryaddr=&(netif->gw);
    }
    dest=arp_lookup(queryaddr);
    }

    /*Ifthearp_lookup()didn'tfindanaddress,wesendoutanARP
    queryfortheIPaddress.*/
    if(dest==NULL){
    q=arp_query(netif,ethernetif->ethaddr,queryaddr);
    if(q!=NULL){
    err=low_level_output(ethernetif,q);
    pbuf_free(q);
    returnerr;
    }
    returnERR_MEM;
    }
    ethhdr=p->payload;

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

    ethhdr->type=htons(ETHTYPE_IP);

    returnlow_level_output(ethernetif,p);

    }
    /*-----------------------------------------------------------------------------------*/
    /*
    *ethernetif_input():
    *
    *Thisfunctionshouldbecalledwhenapacketisreadytoberead
    *fromtheinterface.Itusesthefunctionlow_level_input()that
    *shouldhandletheactualreceptionofbytesfromthenetwork
    *interface.
    *
    */
    /*-----------------------------------------------------------------------------------*/
    staticvoidethernetif_input(structnetif*netif){
    structethernetif*ethernetif=0x0;
    structeth_hdr*ethhdr=0x0;
    structpbuf*p=0x0;

    ethernetif=netif->state;

    p=low_level_input(ethernetif);

    if(p!=NULL){

    ethhdr=p->payload;

    switch(htons(ethhdr->type)){
    caseETHTYPE_IP:
    arp_ip_input(netif,p);
    pbuf_header(p,-14);
    netif->input(p,netif);
    break;
    caseETHTYPE_ARP:
    p=arp_arp_input(netif,ethernetif->ethaddr,p);
    if(p!=NULL){
    low_level_output(ethernetif,p);
    pbuf_free(p);
    }
    break;
    default:
    pbuf_free(p);
    break;
    }
    }
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    arp_timer(void*arg)
    {
    arp_tmr();
    sys_timeout(ARP_TMR_INTERVAL,(sys_timeout_handler)arp_timer,NULL);
    }

    /*-----------------------------------------------------------------------------------*/
    /*
    *ethernetif_init():
    *
    *Shouldbecalledatthebeginningoftheprogramtosetupthe
    *networkinterface.Itcallsthefunctionlow_level_init()todothe
    *actualsetupofthehardware.
    *
    */
    /*-----------------------------------------------------------------------------------*/
    voidethernetif_init(structnetif*netif){
    structethernetif*ethernetif;

    ethernetif=mem_malloc(sizeof(structethernetif));
    netif->state=ethernetif;
    netif->name[0]=IFNAME0;
    netif->name[1]=IFNAME1;
    netif->output=ethernetif_output;
    netif->linkoutput=(void*)low_level_output;

    ethernetif->ethaddr=(structeth_addr*)&(netif->hwaddr[0]);

    low_level_init(netif);
    arp_init();

    sys_timeout(ARP_TMR_INTERVAL,(sys_timeout_handler)arp_timer,NULL);
    }

    /*-----------------------------------------------------------------------------------*/

    voidethernetif_thread(void*arg){
    structnetif*netif=0x0;

    netif=arg;

    while(1){
    tmpBuf=ne2kGetBuffer();
    if(tmpBuf&&tmpBuf->length>0x0){
    ethernetif_input(netif);
    }
    }
    ne2kFreeBuffer(tmpBuf);
    }