bool tcp_mote::send (tcp_message msg, const int destination) { msg.next = next_hop (destination); msg.prev = uuid (); msg.dest = destination; if (msg.next == -1) { // cant calculate path std::cout << "no path to destination\n"; } else { std::cout << msg.source << " -> (" << uuid () << "," << next_hop(msg.dest) << ") -> " << msg.dest << "\n"; bytes_sent += sizeof (tcp_header) - sizeof (transmission); msgs_sent ++; publish (msg); } return (msg.next != -1); }
// returns the number of steps used in a decentralied search: // S searcher (with next_hop function) // N network (with dist function + graph G) // s start node // t goal node // p probability at each step of dropped message int DecentralizedSearch::search(HNetwork& N, int s, int t, double p) { int steps = 0; while (s != t) { s = next_hop(N, s, t); steps++; if (1.0*rand()/RAND_MAX < p) return INF; } return steps; }
/** * @brief Get the next "intent unit" in the DAG starting at the supplied XID * * This method is the same as Graph::next_hop(const Node& n) except it takes an * XID string instead of a Node object. * * @param xid_string The XID of the intent node from which to find the next * intent unit. * * @return The next intent unit (as a Graph) */ Graph Graph::next_hop(const std::string xid_string) { std::string xid_str = xid_string; // if the string includes the "<type>:", cut it off if (xid_string.find(":") != std::string::npos) { xid_str = split(xid_string, ':')[1]; } for (std::size_t i = 0; i < nodes_.size(); i++) { if (nodes_[i].id_string() == xid_str) return next_hop(nodes_[i]); } printf("Warning: next_hop: supplied node not found in DAG: %s\n", xid_str.c_str()); return Graph(); }
void parse_msg(char tokens[MAX_MSG_TOKENS][MAX_MSG_LEN+1], int length, char *sendbuf, int fd) { // app_error("Not Implemented"); // int i = ERR_UNKNOWNCOMMAND; if(!strcmp(tokens[0],"ADDUSER")) { add_user(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"ADDCHAN")) { add_channel(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"REMOVEUSER")) { remove_user(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"REMOVECHAN")) { remove_channel(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"NEXTHOP")) { next_hop(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"NEXTHOPS")) { next_hops(fd, atol(tokens[1]), tokens[2], sendbuf); } else if(!strcmp(tokens[0],"USERTABLE")) { user_table(fd, sendbuf); } else if(!strcmp(tokens[0],"CHANTABLE")) { channel_table(fd, sendbuf); } else { } return; }
void handle_timer() { time_t crnt = time(NULL); struct sr_arp_request *reqs = sr_handle->cache->requests; struct sr_arp_request *prev = NULL; while (reqs) { if (difftime(crnt, reqs->time) > 1) { if(reqs->repeated > MAX_REPEAT) { printf("IP Unreachable\n"); ip_unreachable(sr_handle, reqs->messages->packet, reqs->messages->length, reqs->messages->interface); if (!prev) { sr_handle->cache->requests = reqs->next; free(reqs); reqs = reqs->next; } else { prev->next = reqs->next; free(reqs); reqs = prev->next; } } else { // resend message printf("Resending ARP\n"); arp_request(sr_handle, reqs->ip, next_hop(sr_handle, reqs->ip)); reqs->repeated++; reqs->time = time(NULL); } } else { prev = reqs; reqs = reqs->next; } } }
void sr_handlepacket(struct sr_instance* sr, uint8_t * packet/* lent */, unsigned int len, char* interface/* lent */) { /* Function implemented by g1izzyw and gustan50404 */ /* REQUIRES */ assert(sr); assert(packet); assert(interface); struct sr_if *ether_interface = (struct sr_if *) sr_get_interface(sr, interface); /* Check if it an ethernet interface. */ if (ether_interface) { /* Now we deal with the ethernet header */ struct sr_ethernet_hdr *ether_hdr = (struct sr_ethernet_hdr *) packet; /* Check to see if we are dealing with an ARP request/reply */ if (ether_hdr->ether_type == htons(ethertype_arp)) { fprintf(stderr, "We Got an ARP Packet\n"); /* Handle ARP for ethernet */ struct sr_arp_hdr * arp_hdr = (struct sr_arp_hdr *)(packet + sizeof(struct sr_ethernet_hdr)); if (arp_hdr->ar_hrd == htons(arp_hrd_ethernet)) { if (arp_hdr->ar_op == htons(arp_op_request)) { /* arp request */ struct sr_if *interface_for_ip = get_interface_for_ip(sr, arp_hdr->ar_tip); if (interface_for_ip) { /* Target ip is one of the router interfaces */ fprintf(stderr, "ARP req for one of our interfaces\n"); /* Now we want to make an arp reply and send it back */ uint8_t *buf = (uint8_t *) malloc(len); memcpy(buf, packet, len); /*Make Arp Header*/ make_arprply_hdr(interface_for_ip->addr, arp_hdr->ar_sha, interface_for_ip->ip, arp_hdr->ar_sip, buf); /*Make Ethernet Header*/ make_ether_hdr(interface_for_ip->addr, ether_hdr->ether_shost, ethertype_arp, buf); /* Now we send the packet */ sr_send_packet(sr, buf, len, interface_for_ip->name); free(buf); fprintf(stderr, "ARP reply sent\n"); } } else if (arp_hdr->ar_op == htons(arp_op_reply)) { fprintf(stderr, "We got an ARP Reply, need to check for intfc tho \n"); /* arp reply */ struct sr_if *interface_for_ip = get_interface_for_ip(sr, arp_hdr->ar_tip); if (interface_for_ip) { fprintf(stderr, "We got an ARP Reply for one of our interfaces\n"); /*We first want to insert into Arp cache*/ struct sr_arpreq *request = sr_arpcache_insert(&(sr->cache), arp_hdr->ar_sha, arp_hdr->ar_sip); fprintf(stderr, "Signalling all waiting packets\n"); if (request) { struct sr_packet *cur_packet = request->packets; while(cur_packet) { fprintf(stderr, "About to forward \n"); print_hdrs(cur_packet->buf, cur_packet->len); forward_packet(sr, cur_packet->iface, arp_hdr->ar_sha, cur_packet->len, cur_packet->buf); fprintf(stderr, "Packet Forwarded\n"); cur_packet = cur_packet->next; } } } } } } else if (ether_hdr->ether_type == htons(ethertype_ip)) { /* Get the ip header from the ethernet header*/ sr_ip_hdr_t *ip_hdr = (sr_ip_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t)); /*IP Checksum Stuff*/ uint16_t temp_ip_sum = ip_hdr->ip_sum; ip_hdr->ip_sum = 0; ip_hdr->ip_sum = cksum(packet + sizeof(sr_ethernet_hdr_t), sizeof(sr_ip_hdr_t)); if (temp_ip_sum == ip_hdr->ip_sum) { /*We got here means IP Cheksum is alright, so we extract the interface*/ struct sr_if *interface_for_ip = get_interface_for_ip(sr, ip_hdr->ip_dst); /*Check to make sure interface is one of ours*/ if (interface_for_ip) { fprintf(stderr, "IP Packet destined towards our interface\n"); /*Check if our IP packet is UDP or TCP*/ if (ip_hdr->ip_p == 6 || ip_hdr->ip_p == 17) { fprintf(stderr, "We Got TCP or UDP, sending ICMP error msg\n"); send_icmp_error(3, 3, sr, interface, len, packet); } else { /* Get the ICMP header */ sr_icmp_hdr_t *icmp_hdr = (struct sr_icmp_hdr *) (packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)); /*Now we do the ICMP checksum chek*/ /*This covers the ICMP echo case*/ uint16_t temp_icmp_sum = icmp_hdr->icmp_sum; temp_icmp_sum = icmp_hdr->icmp_sum; icmp_hdr->icmp_sum = 0; if (temp_icmp_sum == cksum(packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t), len - sizeof(sr_ethernet_hdr_t) - sizeof(sr_ip_hdr_t))) { /*Everything is fine so we send an ICMP echo back*/ fprintf(stderr, "Sending ICMP echo reply\n"); send_icmp_echo(sr, interface, len, packet); } } } else { /*IP Packet not destined towards one of our interfaces*/ fprintf(stderr, "IP packet not destined to our interface\n"); /*Decremenrt TTL by 1*/ fprintf(stderr, "TTL modified \n"); print_hdrs(packet, len); if (ip_hdr->ip_ttl <= 1) { fprintf(stderr, "Packte with TTL < 0 found, sending ICMP error \n"); /*TTL is less than 0 so send an ICMP ERROR*/ send_icmp_error(11, 0, sr, interface, len, packet); } else { /*Recompute Checksum over new header TTL is fine*/ /*Check if it exists in the routing table*/ ip_hdr->ip_ttl = ip_hdr->ip_ttl - 1; fprintf(stderr, "Recomputing Checksum after modifying TTl\n"); ip_hdr->ip_sum = 0; ip_hdr->ip_sum = cksum(packet + sizeof(sr_ethernet_hdr_t), sizeof(sr_ip_hdr_t)); struct sr_if *dst_if = (struct sr_if *)malloc(sizeof(struct sr_if)); dst_if = next_hop(sr, interface, ip_hdr->ip_dst); if (!(dst_if)) { fprintf(stderr, "IP packet has no longest matching prefix sending ICMP error\n"); /*dst ip has no longest macthing prefix*/ /*So we send a type 3 code 0 ICMP error*/ send_icmp_error(3, 0, sr, interface, len, packet); } else { /*This is the case where we do have a longest macthing prefix*/ fprintf(stderr, "Found Longest mathcing prefix in RT\n"); struct sr_arpcache *cache = &(sr->cache); struct sr_arpentry *in_cache = sr_arpcache_lookup(cache, ip_hdr->ip_dst); if (in_cache) { fprintf(stderr, "Found IP->MAC mapping in ARP cache forwarding packet \n"); /*this is the case where ip->mac maping is already in cache*/ forward_packet(sr, dst_if->name, in_cache->mac, len, packet); free(in_cache); } else { fprintf(stderr, "IP->MAC mapping not in ARP cache %u \n", ip_hdr->ip_dst); /*Case where ip->mapping is not in cache*/ sr_arpcache_queuereq(cache, ip_hdr->ip_dst, packet, len, dst_if->name); fprintf(stderr, "Added Arp Req to queu \n"); } } } } } } } } /* end sr_ForwardPacket */
/** * @brief Get the first "intent unit" in the DAG * * Get the first "intent unit" in the DAG. Calling this method is equivalent to * calling g.next_hope(Node()). * * @return The DAG's first intent unit (as a Graph) */ Graph Graph::first_hop() { return next_hop(Node()); }