// 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) { if (nf_tid() != 0) { while (1) {} } nf_lock(LOCK_INIT); nf_pktout_init(); nf_pktin_init(); nf_unlock(LOCK_INIT); t_addr *pkt = nf_pktout_alloc(SIZE); fill_ioq((struct ioq_header *)pkt, 0, SIZE-sizeof(struct ioq_header)); nf_pktout_send(pkt, pkt + SIZE); nf_pktout_send(pkt, pkt + SIZE); nf_pktout_send(pkt, pkt + SIZE); nf_pktout_send(pkt, pkt + SIZE); while (1) {} 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]; //u_int16_t ethtype; //#ifndef DEBUG // t_addr* next_packet; // int i=nf_tid(); // // if(i== 0) // { // nf_lock(LOCK_INIT); // should get it on the first attempt // nf_pktout_init(); // nf_pktin_init(); // } // else // { // nf_stall_a_bit(); // nf_lock(LOCK_INIT); // should not get it // } // nf_unlock(LOCK_INIT); // //#endif //test_this(); // 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] = 0x70; //dest_mac[1] = 0x56; //dest_mac[2] = 0x81; //dest_mac[3] = 0xa9; //dest_mac[4] = 0x2c; //dest_mac[5] = 0x39; 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; //ethtype = ETHERTYPE_ARP; //only run this program on thread 0 if (nf_tid() != 0) { while (1) {} } // initialize nf_pktout_init(); nf_pktin_init(); // allocate an output buffer 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); //free //nf_pktin_free(pkt); // 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); //} //memcpy(reply.data, pkt->head, pkt->len); //struct ioq_header *reply_ioq = pkt_pull(&reply, sizeof(struct ioq_header)); //fill_ioq(reply_ioq, ioq->src_port, reply.len); //struct ether_header *reply_ether = pkt_pull(&reply, sizeof(struct ether_header)); //struct ether_arp *reply_arp = pkt_pull(&reply, sizeof(struct ether_arp)); // copy source ip and mac to target //memcpy(reply_arp->arp_tha, reply_arp->arp_sha, ETH_ALEN); //memcpy(reply_arp->arp_tpa, reply_arp->arp_spa, 4); // copy this interface's mac and ip to source //memcpy(reply_arp->arp_sha, iface->mac, ETH_ALEN); //memcpy(reply_arp->arp_spa, iface->ip, 4); //reply_arp->ea_hdr.ar_op = htons(ARPOP_REPLY); //memcpy(reply_ether->ether_shost, iface->mac, ETH_ALEN); //memcpy(reply_ether->ether_dhost, reply_arp->arp_tha, ETH_ALEN); //pkt_push_all(&reply); //send_pkt(reply.data, reply.len); 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; }
int main() { 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 on the first attempt nf_pktout_init(); nf_pktin_init(); } nf_unlock(LOCK_INIT); //only run this program on thread 0 //if (nf_tid() != 0) //{ // while (1) {} //} //// initialize //nf_pktout_init(); //nf_pktin_init(); // allocate an output buffer t_addr *pkt = nf_pktout_alloc(PKT_SIZE); // setup the ioq_header fill_ioq((struct ioq_header*)pkt, 2, sizeof(struct netfpga_to_driver)); // get a pointer to the payload struct struct netfpga_to_driver* n2d = (struct netfpga_to_driver*) (pkt + sizeof(struct ioq_header)); // initialize the message memset(n2d->str, 0, STR_SIZE); memcpy(n2d->str, mystr, strlen(mystr)); //n2d->str[strlen(mystr)+1] = nf_tid() + 0x30; //thread id in ascii n2d->str[strlen(mystr)+1] = mytid + 0x30; //thread id in ascii // send it nf_pktout_send(pkt, pkt + PKT_SIZE); //int i = 0; //int mytid; //struct netfpga_to_driver* n2d; //t_addr *pkt; //while(i <= 1) //{ // 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 on the first attempt // nf_pktout_init(); // nf_pktin_init(); // } // nf_unlock(LOCK_INIT); // // allocate an output buffer // pkt = nf_pktout_alloc(PKT_SIZE); // // setup the ioq_header // fill_ioq((struct ioq_header*)pkt, 2, sizeof(struct netfpga_to_driver)); // // get a pointer to the payload struct // n2d = // (struct netfpga_to_driver*) (pkt + sizeof(struct ioq_header)); // // initialize the message // memset(n2d->str, 0, STR_SIZE); // memcpy(n2d->str, mystr, strlen(mystr)); // //n2d->str[strlen(mystr)+1] = nf_tid() + 0x30; //thread id in ascii // n2d->str[strlen(mystr)+1] = mytid + 0x30; //thread id in ascii // // send it // nf_pktout_send(pkt, pkt + PKT_SIZE); // i = i + 1; //} //#else // 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 on the first attempt // nf_pktout_init(); // nf_pktin_init(); // } // nf_unlock(LOCK_INIT); // t_addr *pkt = nf_pktout_alloc(PKT_SIZE); // // // setup the ioq_header // fill_ioq((struct ioq_header*)pkt, 2, sizeof(struct netfpga_to_driver)); // // // get a pointer to the payload struct // struct netfpga_to_driver* n2d = // (struct netfpga_to_driver*) (pkt + sizeof(struct ioq_header)); // // // initialize the message // memset(n2d->str, 0, STR_SIZE); // memcpy(n2d->str, mystr, strlen(mystr)); // //n2d->str[strlen(mystr)+1] = nf_tid() + 0x30; //thread id in ascii // n2d->str[strlen(mystr)+1] = mytid + 0x30; //thread id in ascii // nf_pktout_send(pkt, pkt + PKT_SIZE); //#endif return 0; }