Untitled
unknown
plain_text
4 years ago
10 kB
7
No Index
def handle_incoming_external_msg(self, of_packet, data_packet): '''Handles a packet with destination MAC equal to external side of NAT router.''' # TODO Implement this function print('handle_incoming_external_msg') print('\n') switch = of_packet.datapath parser = switch.ofproto_parser in_port = of_packet.match['in_port'] match = parser.OFPMatch(in_port=in_port) # Drops the packet actions = [] self.add_flow(switch, match, actions, 0) return def handle_incoming_internal_msg(self, of_packet, data_packet): '''Handles a packet with destination MAC equal to internal side of NAT router.''' print('--==arp table==--') print(self.arp_table) print('--==switch table==--') print(self.switch_table) # TODO Implement this function self.debug('handle_incoming_internal_msg') switch = of_packet.datapath ofproto = switch.ofproto parser = switch.ofproto_parser eth_packet = data_packet.get_protocol(ethernet.ethernet) ip_packet = data_packet.get_protocol(ipv4.ipv4) tcp_packet = data_packet.get_protocol(tcp.tcp) udp_packet = data_packet.get_protocol(udp.udp) icmp_packet = data_packet.get_protocol(icmp.icmp) in_port = of_packet.match['in_port'] udp_set = 0 # replaced self.is_tcp since, the else case cannot work for an external # note udp sends multiple packets to the switch for some reason # Internal -> Internal if self.is_internal_network(data_packet[1].dst) and data_packet[1].dst != config.nat_internal_ip: if (self.is_tcp(data_packet) or self.is_udp(data_packet)): if eth_packet.dst in self.switch_table: out_port = self.switch_table[eth_packet.dst] else: # If no destination port can be determined, need to request this self.handle_internal_host_requests(of_packet, data_packet) return # Match + Action actions = [parser.OFPActionOutput(out_port)] match = parser.OFPMatch(in_port=in_port, eth_dst=eth_packet.dst) if self.is_udp(data_packet): udp_set = 1 self.add_flow(switch, match, actions, 1) data = None if of_packet.buffer_id == ofproto.OFP_NO_BUFFER: data = of_packet.data self.send_packet(data, of_packet, out_port) elif (self.is_icmp(data_packet)): if eth_packet.dst in self.switch_table: out_port = self.switch_table[eth_packet.dst] else: # If no destination port can be determined, need to request this self.handle_internal_host_requests(of_packet, data_packet) return match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_ICMP, ipv4_src=ip_packet.src, ipv4_dst=ip_packet.dst, icmpv4_type=icmp.ICMP_ECHO_REQUEST) actions = [parser.OFPActionSetField(eth_dst=self.arp_table[ip_packet.dst]), parser.OFPActionOutput(out_port)] self.add_flow(switch, match, actions,1) data = None if of_packet.buffer_id == ofproto.OFP_NO_BUFFER: data = of_packet.data self.send_packet(data, of_packet, out_port) # Internal -> External else: if ip_packet.src not in self.ip_to_ephem: self.ip_to_ephem[ip_packet.src] = self.get_port() ephem_port = self.ip_to_ephem[ip_packet.src] if not self.is_icmp(data_packet): if self.is_tcp(data_packet): srcport = tcp_packet.src_port dstport = tcp_packet.dst_port match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IP, ip_proto=ip_packet.proto, ipv4_src=ip_packet.src, ipv4_dst=ip_packet.dst, tcp_src=srcport, tcp_dst=dstport) actions = [parser.OFPActionSetField(ipv4_src=config.nat_external_ip), parser.OFPActionSetField(tcp_src=ephem_port)] match_reply = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_TCP, ipv4_src=ip_packet.dst, ipv4_dst=config.nat_external_ip, tcp_src=dstport, tcp_dst=ephem_port) actions_reply = [parser.OFPActionSetField(eth_dst=eth_packet.src), parser.OFPActionSetField(ipv4_dst=ip_packet.src), parser.OFPActionSetField(tcp_dst=srcport), parser.OFPActionOutput(in_port)] else: srcport = udp_packet.src_port dstport = udp_packet.dst_port udp_set = 1 match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IP, ip_proto=ip_packet.proto, ipv4_src=ip_packet.src, ipv4_dst=ip_packet.dst, udp_src=srcport, udp_dst=dstport) actions = [parser.OFPActionSetField(ipv4_src=config.nat_external_ip), parser.OFPActionSetField(udp_src=ephem_port)] match_reply = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, ipv4_src=ip_packet.dst, ipv4_dst=config.nat_external_ip, udp_src=dstport, udp_dst=ephem_port) actions_reply = [parser.OFPActionSetField(eth_dst=eth_packet.src), parser.OFPActionSetField(ipv4_dst=ip_packet.src), parser.OFPActionSetField(udp_dst=srcport), parser.OFPActionOutput(in_port)] print('sending int->ext ...') # do a match+action, where we change src_ip to external nat ip and add to table self.router_forward(of_packet, data_packet, config.nat_gateway_ip) # matching unique inport and internal mac self.add_flow(switch, match_reply, actions_reply, 1) if config.nat_gateway_ip in self.arp_table: self.router_forward(of_packet, data_packet, config.nat_gateway_ip, match, actions) elif (self.is_icmp(data_packet)): print('got here') # self.router_forward(of_packet, data_packet, config.nat_gateway_ip) # if config.nat_gateway_ip in self.arp_table: # lol why does this work print("icmp_packet %s" % icmp_packet) match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_ICMP, ipv4_src=ip_packet.src, ipv4_dst=ip_packet.dst, icmpv4_type=icmp.ICMP_ECHO_REQUEST) actions = [parser.OFPActionSetField(ipv4_src=config.nat_external_ip)] match_reply = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_ICMP, ipv4_src=ip_packet.dst, ipv4_dst=config.nat_external_ip, icmpv4_type=icmp.ICMP_ECHO_REPLY) actions_reply = [parser.OFPActionSetField(eth_dst=eth_packet.src), parser.OFPActionSetField(ipv4_dst=ip_packet.src), parser.OFPActionOutput(in_port)] self.add_flow(switch, match_reply, actions_reply,1) self.router_forward(of_packet, data_packet, config.nat_gateway_ip, match, actions) return def get_port(self): """Getting port number sequential increase.""" next_ephem = 49152 count = 65535 - 49152 + 1 while count > 0: if (next_ephem == 65535): next_ephem = 49152 ephem_port = next_ephem if ephem_port not in self.ports_in_use: self.ports_in_use.append(ephem_port) return ephem_port else: next_ephem = next_ephem + 1 count = count - 1 # how to return error? return -1
Editor is loading...