/*------------------------------------------------------------------------ * netiface_init - initialize the network interface data structures *------------------------------------------------------------------------ */ void netiface_init (void) { struct ifentry *ifptr = &if_tab[0]; /* ptr to interface table entry */ /* Initialize interface data structures */ ifptr->if_state = IF_DOWN; /* interface is down */ ifptr->if_ip6valid = FALSE; /* IP fields are invalid*/ /* radio address */ memcpy(ifptr->if_macucast, radiotab[0].radio_long_addr, 8); /* ULA prefix */ memcpy(ifptr->if_ip6prefix, ula_prefix, 16); /* Build global address from ULA prefix */ memcpy(ifptr->if_ip6ucast[0], ifptr->if_ip6prefix, 8); memcpy(&ifptr->if_ip6ucast[0][8], radiotab[0].radio_long_addr, 8); /* Build link-scoped address */ memcpy(ifptr->if_ip6ucast[1], ll_prefix, 8); memcpy(&ifptr->if_ip6ucast[1][8], radiotab[0].radio_long_addr, 8); /* No default router */ memcpy(ifptr->if_ip6router, unspec, 16); /* create the input buffer queue synchronization semaphore */ ifptr->if_isem = semcreate(0); /* no packets in buffer */ if (ifptr->if_isem == SYSERR) { panic("netiface_init: cannot create interface input queue semaphore"); } /* head and tail of queue are at 0 */ ifptr->if_ihead = ifptr->if_itail = 0; /* buffer holds a netpacket */ ifptr->if_ipool = mkbufpool(sizeof(struct netpacket), 3); /* create the buffer synchronization semaphore */ ifptr->if_osem = semcreate(0); /* no packets in buffer */ if (ifptr->if_osem == SYSERR) { panic("netiface_init: cannot create semaphore"); } /* head and tail of queue are at 0 */ ifptr->if_ohead = ifptr->if_otail = 0; /* buffer holds a netpacket */ ifptr->if_opool = mkbufpool(sizeof(struct netpacket), 3); /* Enable radio interface */ ifptr->if_state = IF_UP; ifptr->if_ip6valid = TRUE; return; }
void net_init (void) { int32 nbufs; /* Total no of buffers */ /* Initialize the network data structure */ memset((char *)&NetData, NULLCH, sizeof(struct network)); /* Obtain the Ethernet MAC address */ control(ETHER0, ETH_CTRL_GET_MAC, (int32)NetData.ethucast, 0); memset((char *)NetData.ethbcast, 0xFF, ETH_ADDR_LEN); /* Initialize the random port seed */ netportseed = getticks(); /* Create the network buffer pool */ nbufs = UDP_SLOTS * UDP_QSIZ + ICMP_SLOTS * ICMP_QSIZ + 1; netbufpool = mkbufpool(PACKLEN, nbufs); /* Initialize the ARP cache */ arp_init(); /* Initialize UDP */ udp_init(); /* Initialize ICMP */ icmp_init(); /* Initialize the IP output queue */ ipoqueue.iqhead = 0; ipoqueue.iqtail = 0; ipoqueue.iqsem = semcreate(0); if((int32)ipoqueue.iqsem == SYSERR) { panic("Cannot create ip output queue semaphore"); return; } /* Create the IP output process */ resume(create(ipout, NETSTK, NETPRIO, "ipout", 0, NULL)); /* Create a network input process */ resume(create(netin, NETSTK, NETPRIO, "netin", 0, NULL)); }
process rawin (void) { status retval; /* return value from function */ struct netpacket *pkt; /* packet buffer being used now */ int32 nbufs; /* total number of buffers */ struct ifentry *ifptr; /* ptr to interface table entry */ int32 iface; /* index into interface table */ /* Global buffer pool shared by all interfaces */ nbufs = UDP_SLOTS * UDP_QSIZ + ICMP_SLOTS * ICMP_QSIZ + NIFACES * IF_QUEUESIZE + 1; netbufpool = mkbufpool(PACKLEN, nbufs); if (netbufpool == SYSERR) { kprintf("Cannot allocate network buffer pool\n"); kill(getpid()); } open(ETHER0, NULL, NULL); pkt = (struct netpacket *)getbuf(netbufpool); while(1) { retval = read(ETHER0, (char *)pkt, PACKLEN); if (retval == SYSERR) { panic("Ethernet read error"); } /* Demultiplex on MAC address */ for (iface=0; iface<=NIFACES; iface++) { ifptr = &if_tab[iface]; if (ifptr->if_state != IF_UP) { continue; } if ( (memcmp(ifptr->if_macucast, pkt->net_ethdst, ETH_ADDR_LEN) == 0) || (memcmp(ifptr->if_macbcast, pkt->net_ethdst, ETH_ADDR_LEN) == 0)) { /* packet goes to this interface */ /* Check interface queue; drop packet if full */ if (semcount(ifptr->if_sem) >= IF_QUEUESIZE) { kprintf("rawin: queue overflow on %d\n", iface); break; } /* Enqueue packet and signal semaphore */ ifptr->if_queue[ifptr->if_tail++] = pkt; if (ifptr->if_tail >= IF_QUEUESIZE) { ifptr->if_tail = 0; } signal(ifptr->if_sem); /* Obtain a buffer for the next packet */ pkt = (struct netpacket *)getbuf(netbufpool); break; } } } }
process netin(void) { status retval; /* return value from function */ recv_packets = 0; /* initialize */ netbufpool = mkbufpool(PACKLEN, UDP_SLOTS * UDP_QSIZ + ICMP_SLOTS * ICMP_QSIZ + ICMP_OQSIZ + 1); if (netbufpool == SYSERR) { kprintf("Cannot allocate network buffer pool"); kill(getpid()); } /* Copy Ethernet address to global variable */ control(ETHER0, ETH_CTRL_GET_MAC, (int32)NetData.ethaddr, 0); /* Indicate that IP address, mask, and router are not yet valid */ NetData.ipvalid = FALSE; NetData.ipaddr = 0; NetData.addrmask = 0; NetData.routeraddr = 0; /* Initialize ARP cache */ arp_init(); /* Initialize UDP table */ udp_init(); currpkt = (struct netpacket *)getbuf(netbufpool); /* Do forever: read packets from the network and process */ //kprintf("[netin]: start to read packets\r\n"); while(1) { retval = read(ETHER0, (char *)currpkt, PACKLEN); if (retval == SYSERR) { panic("Ethernet read error"); } /* Convert Ethernet Type to host order */ eth_ntoh(currpkt); /* Demultiplex on Ethernet type */ switch (currpkt->net_ethtype) { case ETH_ARP: arp_in(); /* Handle an ARP packet */ continue; case ETH_IP: /* Convert IP packet to host order */ if (ipcksum(currpkt) != 0) { kprintf("checksum failed\n\r"); continue; } if (currpkt->net_ipvh != 0x45) { kprintf("version failed\n\r"); continue; } /* Convert IP packet to host byte order */ ip_ntoh(currpkt); if ( (currpkt->net_ipdst != IP_BCAST) && (NetData.ipvalid) && (currpkt->net_ipdst != NetData.ipaddr) ) { continue; } /* Demultiplex UDP and ignore others */ if (currpkt->net_ipproto == IP_UDP) { //kprintf("[netin]: UDP# %d\r\n", ++recv_packets); udp_in();/* Handle a UDP packet */ } continue; default: /* Ignore all other Ethernet types */ kprintf("\n"); continue; } } }
process netin(void) { status retval; /* return value from function */ int i=0; struct ipv4_packet* ippkt = NULL; /* * FIXME : This might now work */ netbufpool = mkbufpool(PACKLEN, UDP_SLOTS * UDP_QSIZ + ICMP_SLOTS * ICMP_QSIZ + ICMP_OQSIZ + 1); if (netbufpool == SYSERR) { kprintf("Cannot allocate network buffer pool"); kill(getpid()); } /* Copy Ethernet address to global variable */ control(ETHER0, ETH_CTRL_GET_MAC, (int32)NetData.ethaddr, 0); /* Indicate that IP address, mask, and router are not yet valid */ NetData.ipvalid = FALSE; NetData.ipaddr = 0; NetData.addrmask = 0; NetData.routeraddr = 0; kprintf("My Mac is : %06x\r\n", *(NetData.ethaddr+4)); /* Initialize ARP cache */ arp_init(); /* Initialize UDP table */ udp_init(); currpkt = (struct eth_packet *)getbuf(netbufpool); /* Do forever: read packets from the network and process */ while(1) { retval = read(ETHER0, (char *)currpkt, PACKLEN); if (retval == SYSERR) { panic("Ethernet read error"); } /* Convert Ethernet Type to host order */ eth_ntoh(currpkt); /* Demultiplex on Ethernet type */ switch (currpkt->net_ethtype) { case ETH_ARP: arp_in(); /* Handle an ARP packet */ continue; case ETH_IP: //kprintf("Ip packet received \r\n"); ippkt = (struct ipv4_packet *)(currpkt->net_ethdata); if (ipcksum(ippkt) != 0) { kprintf("checksum failed\n\r"); continue; } if (ippkt->net_ipvh != 0x45) { kprintf("version failed\n\r"); continue; } /* Convert IP packet to host order */ ip_ntoh(ippkt); if ( (ippkt->net_ipdst != IP_BCAST) && (NetData.ipvalid) && (ippkt->net_ipdst != NetData.ipaddr) ) { continue; } /* Demultiplex UDP and ignore others */ if (ippkt->net_ipproto == IP_UDP) { udp_in();/* Handle a UDP packet */ }else if (ippkt->net_ipproto == IP_ICMP){ kprintf("ICMP Packet \r\n"); icmp_in();/* Handle ICMP packet */ } continue; case 0x1000: #ifdef DEBUG kprintf("Received a simulator packet\r\n"); #endif wait(rpl_sim_write_sem); memcpy((char *)&sim_queue[i], currpkt->net_ethdata, sizeof(struct rpl_sim_packet)); #ifdef DEBUG kprintf("Netin working with iter [%d] message type : %d dest : %04x source : %04x\r\n",i, sim_queue[i].msg_type, *((uint32 *)(sim_queue[i].dest_node)), *((uint32 *)(sim_queue[i].src_node))); #endif signal(rpl_sim_read_sem); i = (i+1)%RPL_SIM_RECV_QUEUE_LEN; continue; default: /* Ignore all other Ethernet types */ continue; } } }