📄 addresstranslator.cc
字号:
mpi = ipi; } else //inward packet { _v[i]._mai = mai; iai = _v[i]._iai; ipi = mpi; } _v[i]._binding = true; //_v[i]._t = time(NULL); //_v[i]._t = MyEWMA2::now(); return (true); } } } return false; } //dynamic address and port mapping look up IP6FlowID fd; // create flowid & lookup in the _out_map or _in_map if (lookup_direction ==0) // outward lookup { fd = IP6FlowID(iai, ipi, ea, ep); Mapping *m = _out_map.find(fd); if (m) { mai = m->flow_id().saddr(); mpi = m->flow_id().sport(); return true; } } else //inward lookup { fd = IP6FlowID(ea, ep, mai, mpi); Mapping *m = _in_map.find(fd); if (m) { iai = m->flow_id().daddr(); ipi = m->flow_id().dport(); return true; } } if (lookup_direction != _dynamic_mapping_allocation_direction ) return false; // if lookup is not successful, create a new mapping if the lookup_direction is the same as the addressAllocationDirection // first find the freeport and its corresponding map address, create new flowid // then add to in_map and out_map unsigned short new_mport = 0; new_mport = find_mport(); // //click_chatter("***********new port is %x", new_mport); if (!new_mport) { click_chatter("AddressTranslator ran out of ports"); return false; } if (lookup_direction == 0) { mpi = new_mport; mai = _maddr; } else { ipi = new_mport; iai = _maddr; } IP6FlowID orig_out_flow = IP6FlowID(iai, ipi, ea, ep); IP6FlowID orig_in_flow = IP6FlowID(ea, ep, mai, mpi); IP6FlowID new_out_flow = IP6FlowID(mai, mpi, ea, ep); IP6FlowID new_in_flow = IP6FlowID(ea, ep, iai, ipi); Mapping *out_mapping = new Mapping; out_mapping->initialize(new_out_flow); Mapping *in_mapping = new Mapping; in_mapping->initialize(new_in_flow); if (lookup_direction == 0) { if (mpi==_mportl) //the first port mapping { _rover = out_mapping; _rover->set_next(_rover); _rover2= in_mapping; _rover2->set_next(_rover2); } else { out_mapping->set_next(_rover->get_next()); _rover->set_next(out_mapping); _rover = out_mapping; in_mapping->set_next(_rover2->get_next()); _rover2->set_next(in_mapping); _rover2 = in_mapping; } } else { if (ipi == _mportl) { _rover = in_mapping; _rover->set_next(_rover); _rover2 = out_mapping; _rover2->set_next(_rover2); } else { in_mapping->set_next(_rover->get_next()); _rover->set_next(in_mapping); _rover = in_mapping; out_mapping->set_next(_rover2->get_next()); _rover2->set_next(out_mapping); _rover2 = out_mapping; } } _out_map.insert(orig_out_flow, out_mapping); _in_map.insert(orig_in_flow, in_mapping); _nmappings++; _nmappings2++; return true;}voidAddressTranslator::push(int port, Packet *p){ if (port == 0) handle_outward(p); else handle_inward(p);}voidAddressTranslator::handle_outward(Packet *p){ click_ip6 *ip6 = (click_ip6 *)p->data(); unsigned char *start = (unsigned char *)p->data(); IP6Address ip6_src = IP6Address(ip6->ip6_src); IP6Address ip6_msrc; IP6Address ip6_dst = IP6Address(ip6->ip6_dst); uint16_t sport; uint16_t dport; uint16_t mport; WritablePacket *q= Packet::make(p->length()); if (q==0) { click_chatter("can not make packet!"); assert(0); } // create the new packet // replace src IP6, src port, and tcp checksum fields in the packet unsigned char *start_new = (unsigned char *)q->data(); memset(q->data(), '\0', q->length()); memcpy(start_new, start, p->length()); click_ip6 *ip6_new = (click_ip6 * )q->data(); if (ip6_new->ip6_nxt ==0x3a) //the upper layer is an icmp6 packet { unsigned char * icmp6_start = (unsigned char *)(ip6_new +1); if (lookup(ip6_src, dport, ip6_msrc, mport, ip6_dst, sport, 0)) { ip6_new->ip6_src = ip6_msrc; switch (icmp6_start[0]) { case 1 : ; case 3 : ; case 128: ; case 129: { click_icmp6_echo * icmp6 = (click_icmp6_echo *) (ip6_new+1); icmp6->icmp6_cksum=0; icmp6->icmp6_cksum= htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, 0x3a, 0, (unsigned char *)icmp6, ip6_new->ip6_plen)); } break; case 2: { click_icmp6_pkttoobig * icmp6 = (click_icmp6_pkttoobig *)(ip6_new +1); icmp6->icmp6_cksum=0; icmp6->icmp6_cksum= htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, 0x3a, 0, (unsigned char *)icmp6, ip6_new->ip6_plen)); } break; case 4: { click_icmp6_paramprob * icmp6 = (click_icmp6_paramprob *)(ip6_new +1); icmp6->icmp6_cksum=0; icmp6->icmp6_cksum= htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, 0x3a, 0, (unsigned char *)icmp6, ip6_new->ip6_plen)); } break; default: ; break; } p->kill(); output(0).push(q); } else { //click_chatter(" failed for mapping the ip6 address and port for an icmpv6 packet "); p->kill(); } } else if (ip6_new->ip6_nxt ==0x6) //the upper layer is a tcp packet { click_tcp *tcp_new = (click_tcp *)(ip6_new+1); sport = ntohs(tcp_new->th_sport); dport = ntohs(tcp_new->th_dport); if (lookup(ip6_src, sport, ip6_msrc, mport, ip6_dst, dport, 0)) { ip6_new->ip6_src = ip6_msrc; tcp_new->th_sport = htons(mport); //recalculate the checksum for TCP, deal with fragment later tcp_new->th_sum = 0; tcp_new->th_sum = htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, ip6_new->ip6_nxt, tcp_new->th_sum, (unsigned char *)tcp_new, ip6_new->ip6_plen)); p->kill(); output(0).push(q); } else { //click_chatter(" failed to map the ip6 address and port for a tcp packet"); p->kill(); } } else if (ip6_new->ip6_nxt ==0x11) //the upper layer is a udp packet { click_udp *udp_new = (click_udp *)(ip6_new+1); sport = ntohs(udp_new->uh_sport); dport = ntohs(udp_new->uh_dport); if (lookup(ip6_src, sport, ip6_msrc, mport, ip6_dst, dport, 0)) { ip6_new->ip6_src = ip6_msrc; udp_new->uh_sport = htons(mport); //recalculate the checksum for UDP, deal with fragment later udp_new->uh_sum = 0; udp_new->uh_sum = htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, ip6_new->ip6_nxt, udp_new->uh_sum, (unsigned char *)udp_new, ip6_new->ip6_plen)); p->kill(); output(0).push(q); } else { //click_chatter(" failed to map the ip6 address and port for a udp packet"); p->kill(); } } else //discard other packets { click_chatter(" discard the packet, protocol unrecognized"); p->kill(); }}voidAddressTranslator::handle_inward(Packet *p){click_ip6 *ip6 = (click_ip6 *)p->data(); unsigned char *start = (unsigned char *)p->data(); IP6Address ip6_src = IP6Address(ip6->ip6_src); IP6Address ip6_mdst = IP6Address(ip6->ip6_dst); IP6Address ip6_dst ; uint16_t sport; uint16_t mport; uint16_t dport; WritablePacket *q= Packet::make(p->length()); if (q==0) { click_chatter("can not make packet!"); assert(0); } // create the new packet // replace src ip6, src port, and tcp checksum fields in the packet unsigned char *start_new = (unsigned char *)q->data(); memset(q->data(), '\0', q->length()); memcpy(start_new, start, p->length()); click_ip6 *ip6_new = (click_ip6 * )q->data(); if (ip6_new->ip6_nxt ==0x3a) //the upper layer is an icmp6 packet { unsigned char * icmp6_start = (unsigned char *)(ip6_new +1); //unsigned char *ip6_new2 = 0; if (lookup(ip6_dst, dport, ip6_mdst, mport, ip6_src, sport, 1)) { ip6_new->ip6_dst = ip6_dst; switch (icmp6_start[0]) { case 1 : ; //need to change case 3 : ; //need to change case 128: ; case 129: { click_icmp6_echo * icmp6 = (click_icmp6_echo *)(ip6_new +1); icmp6->icmp6_cksum = 0; icmp6->icmp6_cksum = htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, 0x3a, 0, (unsigned char *)icmp6, ip6_new->ip6_plen)); } break; case 2: { click_icmp6_pkttoobig * icmp6 = (click_icmp6_pkttoobig *)(ip6_new +1); icmp6->icmp6_cksum = 0; icmp6->icmp6_cksum = htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, 0x3a, 0, (unsigned char *)icmp6, ip6_new->ip6_plen)); } break; case 4: { click_icmp6_paramprob * icmp6 = (click_icmp6_paramprob *)(ip6_new +1); icmp6->icmp6_cksum = 0; icmp6->icmp6_cksum = htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, 0x3a, 0, (unsigned char *)icmp6, ip6_new->ip6_plen)); } break; default: ; } p->kill(); output(1).push(q); } else { //click_chatter(" failed for mapping the dst ip6 address and port for an icmpv6 packet -inward"); p->kill(); } } else if (ip6_new->ip6_nxt ==0x6) //the upper layer is a tcp packet { click_tcp *tcp_new = (click_tcp *)(ip6_new+1); sport = ntohs(tcp_new->th_sport); mport = ntohs(tcp_new->th_dport); if (lookup(ip6_dst, dport,ip6_mdst, mport, ip6_src, sport, 1)) { ip6_new->ip6_dst = ip6_dst; tcp_new->th_dport = htons(dport); //recalculate the checksum for TCP, deal with fragment later tcp_new->th_sum = 0; tcp_new->th_sum = htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, ip6_new->ip6_nxt, tcp_new->th_sum, (unsigned char *)tcp_new, ip6_new->ip6_plen)); p->kill(); output(1).push(q); } else { //click_chatter(" failed for mapping the dst ip6 address and port for a tcp packet -inward"); p->kill(); } } else if (ip6_new->ip6_nxt ==0x11) //the upper layer is a udp packet { click_udp *udp_new = (click_udp *)(ip6_new+1); sport = ntohs(udp_new->uh_sport); mport = ntohs(udp_new->uh_dport); if (lookup(ip6_dst, dport,ip6_mdst, mport, ip6_src, sport, 1)) { ip6_new->ip6_dst = ip6_dst; udp_new->uh_dport = htons(dport); //recalculate the checksum for TCP, deal with fragment later udp_new->uh_sum = 0; udp_new->uh_sum = htons(in6_fast_cksum(&ip6_new->ip6_src, &ip6_new->ip6_dst, ip6_new->ip6_plen, ip6_new->ip6_nxt, udp_new->uh_sum, (unsigned char *)udp_new, ip6_new->ip6_plen)); p->kill(); output(1).push(q); } else { //click_chatter(" failed for mapping the dst ip6 address and port for a udp packet - inward"); p->kill(); } } else //discard other packets { click_chatter(" discard the packet, protocol unrecognized"); p->kill(); }}EXPORT_ELEMENT(AddressTranslator)CLICK_ENDDECLS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -