void icmp_get_FF(struct finsFrame *ff) { do { sem_wait (&Switch_to_ICMP_Qsem); ff = read_queue(Switch_to_ICMP_Queue); sem_post (&Switch_to_ICMP_Qsem); } while (ff == NULL); if(ff->dataOrCtrl == CONTROL){ // send to something to deal with FCF PRINT_DEBUG("send to CONTROL HANDLER !"); } if( (ff->dataOrCtrl == DATA) && ( (ff->dataFrame).directionFlag == UP) ) { icmp_in(ff); } if( (ff->dataOrCtrl == DATA) && ( (ff->dataFrame).directionFlag == DOWN)) { icmp_out(ff); } }
//------------------------------------------------------------------------ // ip_in - handle IP packet coming in from the network //------------------------------------------------------------------------ int ip_in(struct epacket *packet, int icmpp, int lim) { struct udp *udpptr; struct ip *ipptr; struct netq *nqptr; int dport; int i; int to; int ps; ipptr = (struct ip *)packet->ep_data; switch (ipptr->i_proto) { case IPRO_ICMP: // ICMP: pass to icmp input routine return icmp_in(packet, icmpp, lim); case IPRO_UDP: // UDP: demultiplex based on UDP "port" udpptr = (struct udp *)ipptr->i_data; dport = net2hs(udpptr->u_dport); for (i = 0; i < NETQS; i++) { nqptr = &Net.netqs[i]; if (nqptr->uport == dport) { // drop instead of blocking on psend if (pcount(nqptr->xport) >= NETQLEN) { Net.ndrop++; Net.nover++; freebuf(packet); return SYSERR; } psend(nqptr->xport, (uword)packet); ps = disable(); to = nqptr->pid; if (!isbadpid(to)) { nqptr->pid = BADPID; send(to, OK); } restore(ps); return OK; } } break; default: break; } Net.ndrop++; freebuf(packet); return OK; }
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; } } }