Untitled
unknown
plain_text
4 years ago
10 kB
9
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 -1Editor is loading...