// all threads start here, NetThreads 1.0 has 8 threads (4 per CPU) // instructions from the 4 thread on a CPU are interleaved in a // round-robin fashion. use compiler/bin/mips-mips-elf-objdump -h to // see the memory layout of your compiled application and support.h to // see where some controls are memory-mapped. int main(void) { int mytid = nf_tid(); if(mytid != 0) { nf_stall_a_bit(); nf_lock(LOCK_INIT); // should not get it } else { #ifndef DEBUG nf_lock(LOCK_INIT); // should get it on the first attempt nf_pktout_init(); nf_pktin_init(); #endif sp_init_mem_single(); // initialize the multithreaded memory allocator // perform memory allocation for initialization purposes // only use sp_free() and sp_malloc() // two implementations of these functions exists. If you prefer the STANDARD_MALLOC // from ../common/memory.c, you should not perform sp_init_mem_single() nor sp_init_mem_pool(). // finalize the initialization of the multithreaded memory allocator // since each thread allocates from its private head and adds to its heap // upon memory free, the heaps can get unbalanced if care is not taken sp_init_mem_pool(); } nf_unlock(LOCK_INIT); while(1) { // get the time if you need it uint t = nf_time(); // 32-bit unsigned wrap-around time nf_lock(LOCK_DS0); // valid lock identifiers are integers from 0 to 15 inclusively // do some synchronized action here nf_unlock(LOCK_DS0); t_addr* next_packet = nf_pktin_pop(); // get the next available packet, this is non-blocking call if (nf_pktin_is_valid(next_packet)) { // test if we have a packet // process the packet nf_pktin_free(next_packet); // free this packet from the input memory } } // rever reached return 0; }
int main(void) { t_addr* next_packet; int i = 0; int mytid = nf_tid(); if(mytid != 0) { nf_stall_a_bit(); nf_lock(LOCK_INIT); // should not get it } else { nf_lock(LOCK_INIT); // should get it immediately nf_pktout_init(); nf_pktin_init(); } nf_unlock(LOCK_INIT); while(1) { next_packet = nf_pktin_pop(); if (nf_pktin_is_valid(next_packet)) { i++; iddle_time(NUMBER_OF_LOOPS); log("thread %d sending packet %d from %p\n", nf_tid(), i, next_packet); process_pkt(next_packet); } } while(1); return 0; }
int main(void) { t_addr *pkt; struct net_iface iface; struct ether_header *reth; struct ether_arp *rarp; unsigned char dest_mac[6]; unsigned char dest_ip[4]; // iface is not shared, it's on the stack arp_init(&iface.arp); iface.mac[0] = 0x00; iface.mac[1] = 0x43; iface.mac[2] = 0x32; iface.mac[3] = 0x46; iface.mac[4] = 0x4e; iface.mac[5] = 0x00; iface.ip[0] = 192; iface.ip[1] = 168; iface.ip[2] = 0; iface.ip[3] = 100; dest_mac[0] = 0xff; dest_mac[1] = 0xff; dest_mac[2] = 0xff; dest_mac[3] = 0xff; dest_mac[4] = 0xff; dest_mac[5] = 0xff; dest_ip[0] = 192; dest_ip[1] = 168; dest_ip[2] = 0; dest_ip[3] = 185; //only run this program on thread 0 if (nf_tid() != 0) { while (1) {} } // initialize nf_pktout_init(); nf_pktin_init(); // This is to just send an ARP request start uncommenting to play // allocate an output buffer //t_addr *pkt = nf_pktout_alloc(PKT_SIZE); pkt = nf_pktout_alloc(PKT_SIZE); // setup the ioq_header fill_ioq((struct ioq_header*) pkt, 2, PKT_SIZE); // setup the ethernet header //struct ether_header *reth = (struct ether_header*) (pkt + sizeof(struct ioq_header)); reth = (struct ether_header*) (pkt + sizeof(struct ioq_header)); // setup the ethernet arp //struct ether_arp *rarp = (struct ether_arp*) (pkt + sizeof(struct ioq_header) + sizeof(struct ether_header)); rarp = (struct ether_arp*) (pkt + sizeof(struct ioq_header) + sizeof(struct ether_header)); // start putting things into the packet // ethernet memcpy(reth->ether_shost, &iface.mac, ETH_ALEN); memcpy(reth->ether_dhost, &dest_mac, ETH_ALEN); //memcpy(reth->ether_type, htons(ethtype), sizeof(u_int16_t)); //memcpy(reth->ether_type, ðtype, 2); //memcpy(reth->ether_type, &mytype, 2); reth->ether_type = ETHERTYPE_ARP; // arp header rarp->ea_hdr.ar_hrd = htons(ARPHRD_ETHER); rarp->ea_hdr.ar_pro = htons(ETHERTYPE_IP); //rarp->ea_hdr.ar_pro = htons(0x0800); rarp->ea_hdr.ar_hln = 6; rarp->ea_hdr.ar_pln = 4; rarp->ea_hdr.ar_op = htons(ARPOP_REQUEST); // arp ethernet // source memcpy(rarp->arp_sha, &iface.mac, ETH_ALEN); memcpy(rarp->arp_spa, &iface.ip, 4); // target memcpy(rarp->arp_tha, dest_mac, ETH_ALEN); memcpy(rarp->arp_tpa, dest_ip, 4); // send it nf_pktout_send(pkt, pkt + PKT_SIZE); nf_pktout_send(pkt, pkt + PKT_SIZE); nf_pktout_send(pkt, pkt + PKT_SIZE); nf_pktout_send(pkt, pkt + PKT_SIZE); //end uncomment // start in on replying while(1) { pkt = nf_pktin_pop(); // test for next_packet if(!nf_pktin_is_valid(pkt)) continue; process_eth(&iface, pkt); nf_pktin_free(pkt); } return 0; }