📄 dsrroutetable.cc
字号:
dsr_source->dsr_len = sizeof(DSRHop) * hop_count + 2; dsr_source->dsr_segsleft = hop_count; for (i=0; i<hop_count; i++) { dsr_source->addr[i]._ip.s_addr = source_route[i+1].addr(); dsr_source->addr[i]._metric = 0; // to be filled in along the way } // set the ip dest annotation to the next hop p->set_dst_ip_anno(source_route[hop_count].addr()); DEBUG_CHATTER(" * added source route header"); return p;}// removes all DSR headers, leaving an ordinary IP packetPacket *DSRRouteTable::strip_headers(Packet *p_in){ WritablePacket *p = p_in->uniqueify(); click_ip *ip = reinterpret_cast<click_ip *>(p->data()); click_dsr *dsr = (click_dsr *)(p->data() + sizeof(click_ip)); assert(ip->ip_p == IP_PROTO_DSR); // get the length of the DSR headers from the fixed header unsigned dsr_len = sizeof(click_dsr) + ntohs(dsr->dsr_len); // save the IP header click_ip new_ip; memcpy(&new_ip, ip, sizeof(click_ip)); new_ip.ip_p = dsr->dsr_next_header; // remove the headers p->pull(dsr_len); memcpy(p->data(), &new_ip, sizeof(click_ip)); ip=reinterpret_cast<click_ip *>(p->data()); ip->ip_len=htons(p->length()); ip->ip_sum=0; ip->ip_sum=click_in_cksum((unsigned char *)ip,sizeof(click_ip)); p->set_ip_header((click_ip*)p->data(),sizeof(click_ip)); DEBUG_CHATTER(" * stripping headers; removed %d bytes\n"); return p;}// takes a RREQ packet, and returns the route which that request has// so far accumulated. (we then take this route and add it to the// link cache)DSRRouteDSRRouteTable::extract_request_route(const Packet *p_in){ const click_ip *ip = p_in->ip_header(); // address of the node originating the rreq unsigned src = ip->ip_src.s_addr; IPAddress src_addr(src); const click_dsr_rreq *dsr_rreq = (const click_dsr_rreq *)(p_in->data()+ sizeof(click_ip)+ sizeof(click_dsr)); assert(dsr_rreq->dsr_type == DSR_TYPE_RREQ); int num_addr = dsr_rreq->num_addrs(); // DEBUG_CHATTER(" * hop count in RREQ so far is %d\n", num_addr); // route is { ip src, addr[0], addr[1], ..., ip dst } DSRRoute route; route.push_back(DSRHop(src_addr)); for (int i=0; i<num_addr; i++) { route.push_back(dsr_rreq->addr[i]); } // IPAddress dst_addr(dsr_rreq->target.s_addr); // route.push_back(dst_addr); return route;}voidDSRRouteTable::issue_rrep(IPAddress src, IPAddress dst, DSRRoute reply_route, DSRRoute source_route){ // exclude src and dst in source route for hop count unsigned char src_hop_count = source_route.size() - 2; // however the reply route has to include the destination. the // source is in the IP dest field unsigned char reply_hop_count = reply_route.size() - 1; // creating the payload int payload = (sizeof(click_ip) + sizeof(click_dsr) + sizeof(click_dsr_rrep) + sizeof(DSRHop) * reply_hop_count + sizeof(click_dsr_source) + sizeof(DSRHop) * src_hop_count); int i; // XXX? unsigned ttl=255; WritablePacket *p = Packet::make(payload); if (!p) { DEBUG_CHATTER(" * issue_rrep: couldn't make packet of %d bytes\n", payload); return; } // getting pointers to the headers click_ip *ip = reinterpret_cast<click_ip *>(p->data()); click_dsr *dsr = (click_dsr *)(p->data() + sizeof(click_ip)); click_dsr_rrep *dsr_rrep = (click_dsr_rrep *)( p->data() + sizeof(click_ip) + sizeof(click_dsr)); click_dsr_source *dsr_source = (click_dsr_source *)( p->data() + sizeof(click_ip) + sizeof(click_dsr) + sizeof(click_dsr_rrep) + sizeof(DSRHop) * reply_hop_count); p->set_ip_header(ip, sizeof(click_ip)); /* fill the source route header */ dsr_source->dsr_type = DSR_TYPE_SOURCE_ROUTE; dsr_source->dsr_len = sizeof(DSRHop) * src_hop_count + 2; dsr_source->dsr_segsleft = src_hop_count; if (src_hop_count != 0) { // fill up the source route header using the source_route // addresses, omitting first and last addresses for (i=1; i<source_route.size()-1; i++) { dsr_source->addr[i-1]._ip = source_route[i]._ip; dsr_source->addr[i-1]._metric = 0; // to be filled in along the way } } // fill the route reply header dsr_rrep->dsr_type = DSR_TYPE_RREP; dsr_rrep->dsr_len = sizeof(DSRHop)*reply_hop_count+1; dsr_rrep->dsr_flags = 0; // dsr_rrep->dsr_id = htons(id); // fill the route reply addrs for (i=1; i<reply_route.size(); i++) { // skip first address, which goes in the dest field of the ip // header. dsr_rrep->addr[i-1]._ip = reply_route[i]._ip; dsr_rrep->addr[i-1]._metric = reply_route[i]._metric; } // make the IP Header ip->ip_v = 4; ip->ip_hl = sizeof(click_ip) >> 2; ip->ip_len = htons(p->length()); // ip->ip_id = htons(id); // XXXXX ip->ip_p = IP_PROTO_DSR; ip->ip_src.s_addr = src.addr(); ip->ip_dst.s_addr = dst.addr(); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = ttl; ip->ip_sum = 0; ip->ip_sum = click_in_cksum((unsigned char *)ip, sizeof(click_ip)); // fill the dsr header dsr->dsr_next_header = ip->ip_p; dsr->dsr_len = htons(payload - sizeof(click_dsr) - sizeof(click_ip)); dsr->dsr_reserved = 0; // setting the next hop annotation p->set_dst_ip_anno(source_route[1]._ip); IPAddress dst_anno_address(p->dst_ip_anno()); DEBUG_CHATTER(" * created RREP packet with next hop %s\n", dst_anno_address.unparse().c_str()); output(1).push(p);}// takes info about a bad link from bad_src -> bad_dst, and the// originator of the packet which failed on this link, and sends a// route error along the provided source_routevoidDSRRouteTable::issue_rerr(IPAddress bad_src, IPAddress bad_dst, IPAddress src, DSRRoute source_route){ WritablePacket *p = NULL; // exclude src and dst in source route for hop count int src_hop_count = source_route.size()-2; assert(src_hop_count >= 0); // creating the payload int payload = (sizeof(click_ip) + sizeof(click_dsr) + sizeof(click_dsr_rerr) + sizeof(in_addr)); // if the src_hop_count is 0, then no need for a source route option // XXX handling of rerrs with no SR option is broken; always insert SR option // if (src_hop_count > 0) payload += (sizeof(click_dsr_source) + sizeof(DSRHop) * (src_hop_count)); int i; // XXX? unsigned ttl=255; // make the packet p = Packet::make(payload); if (!p) { DEBUG_CHATTER(" * issue_rerr: couldn't make packet of %d bytes\n", payload); return; } // getting pointers to the headers click_ip *ip = reinterpret_cast<click_ip *>(p->data()); click_dsr *dsr = (click_dsr *)(p->data() + sizeof(click_ip)); click_dsr_rerr *dsr_rerr = (click_dsr_rerr *)(p->data() + sizeof(click_ip) + sizeof(click_dsr)); in_addr *dsr_unreach_addr=(in_addr *)(p->data() + sizeof(click_ip) + sizeof(click_dsr) + sizeof(click_dsr_rerr)); click_dsr_source *dsr_source = (click_dsr_source *)(p->data() + sizeof(click_ip) + sizeof(click_dsr) + sizeof(click_dsr_rerr) + sizeof(in_addr)); p->set_ip_header(ip, sizeof(click_ip)); // fill in the route error dsr_rerr->dsr_type = DSR_TYPE_RERR; dsr_rerr->dsr_len = 14; dsr_rerr->dsr_error = DSR_RERR_TYPE_NODE_UNREACHABLE; dsr_rerr->dsr_flags = 0; dsr_rerr->dsr_err_src.s_addr = bad_src.addr(); dsr_rerr->dsr_err_dst.s_addr = src.addr(); // add unreachable destination dsr_unreach_addr->s_addr = bad_dst.addr(); // make the IP header ip->ip_v = 4; ip->ip_hl = sizeof(click_ip) >> 2; ip->ip_len = htons(p->length()); // XXX what does the following comment mean? // id is set to 1..check what value exactly ip->ip_id = htons(1); ip->ip_p = IP_PROTO_DSR; ip->ip_src.s_addr = bad_src.addr(); ip->ip_dst.s_addr = src.addr(); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = ttl; ip->ip_sum = 0; ip->ip_sum = click_in_cksum((unsigned char *)ip, sizeof(click_ip)); // fill the dsr header dsr->dsr_next_header = ip->ip_p; dsr->dsr_len = htons(payload - sizeof(click_dsr)-sizeof(click_ip)); dsr->dsr_reserved = 0; // fill in the source route header // if (src_hop_count > 0) { // don't need to do this if the target is one hop away dsr_source->dsr_type = DSR_TYPE_SOURCE_ROUTE; dsr_source->dsr_len = sizeof(DSRHop) * src_hop_count + 2; dsr_source->dsr_segsleft = src_hop_count; // get a pointer to the addresses and fill them up using // source_route addresses for (i=1; i < source_route.size()-1; i++) { dsr_source->addr[i-1]._ip = source_route[i]._ip; dsr_source->addr[i-1]._metric = 0; } // } // setting the next hop annotation p->set_dst_ip_anno(source_route[1]._ip); IPAddress dst_anno_address(p->dst_ip_anno()); DEBUG_CHATTER(" * created RERR packet with next hop as %s\n", dst_anno_address.unparse().c_str() ); output(1).push(p);}// takes an RREP packet, copies out the reply route and returns it// as a Vector<IPAddress>DSRRouteDSRRouteTable::extract_reply_route(const Packet *p){ const click_ip *ip = p->ip_header(); const click_dsr_rrep *dsr_rrep = (const click_dsr_rrep *)(p->data()+ sizeof(click_ip)+ sizeof(click_dsr)); IPAddress dest_ip(ip->ip_dst.s_addr); assert(dsr_rrep->dsr_type == DSR_TYPE_RREP); int hop_count = dsr_rrep->num_addrs(); // DEBUG_CHATTER(" * extracting route from %d-hop route reply\n", hop_count); DSRRoute route; // construct the route from the reply addresses. // // if the route reply is the result of "reply from cache", then the // address in the source field of the IP header may differ from the // destination of the route listed. so the last hop of the route is // explicitly specified in the route. // // the first hop, however, comes from the destination field of the // IP header (the intended recipient of this route reply). so we // have to put this (dest_ip) first. route.push_back(DSRHop(dest_ip)); for (int i=0; i < hop_count; i++) { route.push_back(dsr_rrep->addr[i]); } return route;}// returns the source route from this packet; used for producing route// error messages (extract route, truncate at my address, reverse, and// use that as the source route for the route error)DSRRouteDSRRouteTable::extract_source_route(const Packet *p_in, unsigned int offset){ // obtain the pointers to the source route headers assert(offset < p_in->length()); const click_ip *ip = p_in->ip_header(); const click_dsr_source *dsr_source = (const click_dsr_source *)(p_in->data()+ offset); assert(dsr_source->dsr_type == DSR_TYPE_SOURCE_ROUTE); int source_hops = dsr_source->num_addrs(); DSRRoute route; // get the source and the destination from the IP Header IPAddress src(ip->ip_src.s_addr); IPAddress dst(ip->ip_dst.s_addr); route.push_back(DSRHop(src)); // append the intermediate nodes to the route for (int i=0; i<source_hops; i++) { route.push_back(dsr_source->addr[i]); } route.push_back(DSRHop(dst)); return route;}// p_in is a route reply which we received because we're on its source// route; return the packet after setting the IP dest annotationvoidDSRRouteTable::forward_rrep(Packet * p_in){ WritablePacket *p=p_in->uniqueify(); // get pointer to the rrep header click_dsr_rrep *dsr_rrep=(click_dsr_rrep *)(p->data()+ sizeof(click_ip) + sizeof(click_dsr)); // again, from the draft int num_addr = dsr_rrep->num_addrs(); // DEBUG_CHATTER(" * RREP contains %d addresses\n", num_addr); // XXX originally it seemed there was code here to check if there // was an additional, "optional" header between the RREP option and // the source route. but I don't see any code to actually insert // this optional header, so I'm leaving this check out for now; // perhaps the idea is to include some data with the route requests // and replies? unsigned int dsr_source_offset = (sizeof(click_ip) + sizeof(click_dsr) + sizeof(click_dsr_rrep) + num_addr * sizeof(DSRHop)); forward_sr(p, dsr_source_offset, 1);}// forwarding a data packet based on the source route option; set the// destination IP anno and return.voidDSRRouteTable::forward_data(Packet *p_in){ forward_sr(p_in, sizeof(click_ip) + sizeof(click_dsr), 2);}// take a wild guess.voidDSRRouteTable::forward_rerr(Packet * p_in){ /* Get the source route pointer */ unsigned int dsr_source_offset = (sizeof(click_ip) + sizeof(click_dsr) + sizeof(click_dsr_rerr) + sizeof(in_addr)); forward_sr(p_in, dsr_source_offset, 1);}IPAddressDSRRouteTable::next_hop(Packet *p){ const click_ip *ip = (const click_ip*)(p->data() + sizeof(click_ether)); click_dsr *dsr = (click_dsr *)(p->data() + sizeof(click_ip)); const unsigned int dsr_len = dsr->dsr_len; click_dsr_option *dsr_option = (click_dsr_option *)(p->data() + sizeof(click_ip) + sizeof(click_dsr)); if (dsr_option->dsr_type == DSR_TYPE_RREQ) { click_chatter("next_hop called on a RREQ?\n"); IPAddress src_addr(0xffffffff); return (src_addr); } else if (dsr_option->dsr_type == DSR_TYPE_RREP) { const click_dsr_rrep *dsr_rrep = (const click_dsr_rrep*)dsr_option; // DEBUG_CHATTER(" * extracting IP from route reply; num_addr is %d\n", num_addr); if (dsr_rrep->length() == dsr_len) { // if this RREP option is the only option in the header IPAddress dst_addr(ip->ip_dst.s_addr); return (dst_addr); } else { dsr_option = (click_dsr_option *)(dsr_rrep->next_option()); if (dsr_option->dsr_type != DSR_TYPE_SOURCE_ROUTE) { click_chatter(" * DSRArpTable::last_hop: source route option did not follow route reply option\n"); IPAddress zeros; return zeros; } } } else if (dsr_option->dsr_type == DSR_TYPE_RERR) { // XXX we might have multiple RERRs. const click_dsr_rerr *dsr_rerr = (click_dsr_rerr *)dsr_option; if (dsr_rerr->length() == dsr_len) { // if this RERR option is the only option in the header IPAddress dst_addr(ip->ip_dst.s_addr); return (dst_addr); } else { dsr_option = (click_dsr_option *)(dsr_rerr->next_option()); if (dsr_option->dsr_type != DSR_TYPE_SOURCE_ROUTE) { click_chatter(" * source route option did not follow route error option\n"); IPAddress zeros; return zeros; } } } if (dsr_option->dsr_type == DSR_TYPE_SOURCE_ROUTE) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -