def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, self.nd_type, self.nd_length, nd_opt) prev = ipv6(6, 0, 0, 32, 64, 255, self.src_ipv6, self.dst_ipv6) nd_csum = icmpv6_csum(prev, self.buf + self.data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (res, dst) = struct.unpack_from(nd._PACK_STR, buf, icmp._MIN_LEN) (nd_type, nd_length, nd_hw_src) = struct.unpack_from('!BB6s', buf, icmp._MIN_LEN + nd._MIN_LEN) data = buf[(icmp._MIN_LEN + nd._MIN_LEN + 8):] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, nd_csum) eq_(res >> 29, self.res) eq_(dst, self.dst) eq_(nd_type, self.nd_type) eq_(nd_length, self.nd_length) eq_(nd_hw_src, self.nd_hw_src)
def test_to_string(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) rs = icmpv6.nd_router_solicit( self.res, self.nd_type, self.nd_length, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, rs) nd_opt_values = {'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_la.__name__, _nd_opt_str) rs_values = {'res': repr(rs.res), 'type_': repr(self.nd_type), 'length': repr(self.nd_length), 'data': nd_opt_str} _rs_str = ','.join(['%s=%s' % (k, rs_values[k]) for k, v in inspect.getmembers(rs) if k in rs_values]) rs_str = '%s(%s)' % (icmpv6.nd_router_solicit.__name__, _rs_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': rs_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
def test_to_string(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) nd = icmpv6.nd_neighbor( self.res, self.dst, self.nd_type, self.nd_length, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, nd) nd_opt_values = {'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_la.__name__, _nd_opt_str) nd_values = {'res': repr(nd.res), 'dst': repr(self.dst), 'type_': repr(self.nd_type), 'length': repr(self.nd_length), 'data': nd_opt_str} _nd_str = ','.join(['%s=%s' % (k, nd_values[k]) for k, v in inspect.getmembers(nd) if k in nd_values]) nd_str = '%s(%s)' % (icmpv6.nd_neighbor.__name__, _nd_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': nd_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
def _send_icmp_NS(self, datapath, outport_no, dst_ip): src_mac_addr = \ self.dpid_to_switch[datapath.id].ports[outport_no].hw_addr src_ip = \ self.dpid_to_switch[datapath.id].ports[outport_no].gateway.gw_ipv6 p = packet.Packet() dst_mac, dst_ip_multicast = self._generate_dst_for_NS(dst_ip) e = ethernet.ethernet(dst = dst_mac, src = src_mac_addr, ethertype = ether.ETH_TYPE_IPV6) ip6 = ipv6.ipv6(version = 6, traffic_class = 0, flow_label = 0, # 4byte ICMP header, 4byte reserved, 16byte target address, # 8byte "source link-layer address" option # next header value for ICMPv6 is 58 payload_length = 32, nxt = 58, hop_limit = 255, src = src_ip, dst = dst_ip_multicast) # source link-layer address sla_addr = icmpv6.nd_option_la(hw_src = src_mac_addr) # ns for neighbor solicit, res for reserved ns = icmpv6.nd_neighbor(res = 0, dst = dst_ip, type_ = icmpv6.nd_neighbor.ND_OPTION_SLA, length = 1, data = sla_addr) ic6 = icmpv6.icmpv6(type_ = icmpv6.ND_NEIGHBOR_SOLICIT, code = 0, # checksum = 0 then ryu calculate for you csum = 0, data = ns) p.add_protocol(e) p.add_protocol(ip6) p.add_protocol(ic6) p.serialize() datapath.send_packet_out(in_port = ofproto_v1_0.OFPP_NONE, actions = [datapath.ofproto_parser.OFPActionOutput(outport_no)], data = p.data)
def _send_icmp_NS(self, datapath, outport_no, dst_ip): src_mac_addr = \ self.dpid_to_switch[datapath.id].ports[outport_no].hw_addr src_ip = \ self.dpid_to_switch[datapath.id].ports[outport_no].gateway.gw_ipv6 p = packet.Packet() dst_mac, dst_ip_multicast = self._generate_dst_for_NS(dst_ip) e = ethernet.ethernet(dst=dst_mac, src=src_mac_addr, ethertype=ether.ETH_TYPE_IPV6) ip6 = ipv6.ipv6( version=6, traffic_class=0, flow_label=0, # 4byte ICMP header, 4byte reserved, 16byte target address, # 8byte "source link-layer address" option # next header value for ICMPv6 is 58 payload_length=32, nxt=58, hop_limit=255, src=src_ip, dst=dst_ip_multicast) # source link-layer address sla_addr = icmpv6.nd_option_la(hw_src=src_mac_addr) # ns for neighbor solicit, res for reserved ns = icmpv6.nd_neighbor(res=0, dst=dst_ip, type_=icmpv6.nd_neighbor.ND_OPTION_SLA, length=1, data=sla_addr) ic6 = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, code=0, # checksum = 0 then ryu calculate for you csum=0, data=ns) p.add_protocol(e) p.add_protocol(ip6) p.add_protocol(ic6) p.serialize() datapath.send_packet_out( in_port=ofproto_v1_0.OFPP_NONE, actions=[datapath.ofproto_parser.OFPActionOutput(outport_no)], data=p.data)
def test_to_string(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, self.nd_type, self.nd_length, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, nd) nd_opt_values = {'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join([ '%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values ]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_la.__name__, _nd_opt_str) nd_values = { 'res': repr(nd.res), 'dst': repr(self.dst), 'type_': repr(self.nd_type), 'length': repr(self.nd_length), 'data': nd_opt_str } _nd_str = ','.join([ '%s=%s' % (k, nd_values[k]) for k, v in inspect.getmembers(nd) if k in nd_values ]) nd_str = '%s(%s)' % (icmpv6.nd_neighbor.__name__, _nd_str) icmp_values = { 'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': nd_str } _ic_str = ','.join([ '%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values ]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, self.nd_type, self.nd_length, nd_opt) prev = ipv6(6, 0, 0, 32, 64, 255, self.src_ipv6, self.dst_ipv6) nd_csum = icmpv6_csum(prev, self.buf + self.data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (res, dst) = struct.unpack_from(nd._PACK_STR, buf, icmp._MIN_LEN) (nd_type, nd_length, nd_hw_src) = struct.unpack_from("!BB6s", buf, icmp._MIN_LEN + nd._MIN_LEN) data = buf[(icmp._MIN_LEN + nd._MIN_LEN + 8) :] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, nd_csum) eq_(res >> 29, self.res) eq_(dst, self.dst) eq_(nd_type, self.nd_type) eq_(nd_length, self.nd_length) eq_(nd_hw_src, self.nd_hw_src)
def test_to_string(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) rs = icmpv6.nd_router_solicit(self.res, self.nd_type, self.nd_length, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, rs) nd_opt_values = {'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join([ '%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values ]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_la.__name__, _nd_opt_str) rs_values = { 'res': repr(rs.res), 'type_': repr(self.nd_type), 'length': repr(self.nd_length), 'data': nd_opt_str } _rs_str = ','.join([ '%s=%s' % (k, rs_values[k]) for k, v in inspect.getmembers(rs) if k in rs_values ]) rs_str = '%s(%s)' % (icmpv6.nd_router_solicit.__name__, _rs_str) icmp_values = { 'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': rs_str } _ic_str = ','.join([ '%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values ]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) rs = icmpv6.nd_router_solicit(self.res, self.nd_type, self.nd_length, nd_opt) prev = ipv6(6, 0, 0, 16, 64, 255, self.src_ipv6, self.dst_ipv6) rs_csum = icmpv6_csum(prev, self.buf + self.data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, rs) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) res = struct.unpack_from(rs._PACK_STR, buf, icmp._MIN_LEN) (nd_type, nd_length, nd_hw_src) = struct.unpack_from( '!BB6s', buf, icmp._MIN_LEN + rs._MIN_LEN) data = buf[(icmp._MIN_LEN + rs._MIN_LEN + 8):] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, rs_csum) eq_(res[0], self.res) eq_(nd_type, self.nd_type) eq_(nd_length, self.nd_length) eq_(nd_hw_src, addrconv.mac.text_to_bin(self.nd_hw_src))
def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) rs = icmpv6.nd_router_solicit(self.res, self.nd_type, self.nd_length, nd_opt) prev = ipv6(6, 0, 0, 16, 64, 255, self.src_ipv6, self.dst_ipv6) rs_csum = icmpv6_csum(prev, self.buf + self.data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, rs) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) res = struct.unpack_from(rs._PACK_STR, buf, icmp._MIN_LEN) (nd_type, nd_length, nd_hw_src) = struct.unpack_from('!BB6s', buf, icmp._MIN_LEN + rs._MIN_LEN) data = buf[(icmp._MIN_LEN + rs._MIN_LEN + 8):] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, rs_csum) eq_(res[0], self.res) eq_(nd_type, self.nd_type) eq_(nd_length, self.nd_length) eq_(nd_hw_src, addrconv.mac.text_to_bin(self.nd_hw_src))
def _packet_in_handler(self, ev): msg = ev.msg in_port = msg.in_port datapath = msg.datapath ofproto = datapath.ofproto dpid = datapath.id print 'mac_to_port',self.mac_to_port,'\n' self.mac_to_port.setdefault(dpid, {}) print 'mac_to_port',self.mac_to_port,'\n' dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) LOG.info("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) if _eth_type == ether.ETH_TYPE_ARP: #if dst in self.port_to_switch_mac[dpid]: arp_pkt = self.find_packet(msg,'arp') if arp_pkt != None: dst_ip = arp_pkt.dst_ip src_ip = arp_pkt.src_ip self.port_to_ip.setdefault(dpid,{}) self.port_to_ip[dpid][in_port] = (src_ip & 0Xffffff00) + 0xfe if dst_ip == self.port_to_ip[dpid][in_port]: src_mac = self.port_to_switch_mac[dpid][in_port] e = ethernet.ethernet(src,self.port_to_switch_mac[dpid][in_port],ether.ETH_TYPE_ARP) if arp_pkt.opcode == arp.ARP_REQUEST: opcode = arp.ARP_REPLY #else: #opcode = arp.ARP_REV_REPLY a = arp.arp(hwtype = 1,proto = 0x0800, hlen = 6, plen = 4, opcode = opcode, src_mac = src_mac,src_ip = arp_pkt.dst_ip, dst_mac = arp_pkt.src_mac, dst_ip = arp_pkt.src_ip) p = Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data) print "arp request packet's dst_mac is ",haddr_to_str(self.port_to_switch_mac[dpid][in_port]) if _eth_type == ether.ETH_TYPE_IP: ip_pkt = self.find_packet(msg,'ipv4') #to judge if the ip packet contains icmp protocol #print 'lee 0' if ip_pkt.proto == 1: icmp_pkt = self.find_packet(msg,'icmp') if icmp_pkt.type == icmp.ICMP_ECHO_REQUEST: ip_src = ip_pkt.src ip_dst = ip_pkt.dst echo_id = icmp_pkt.data.id echo_seq = icmp_pkt.data.seq echo_data = bytearray(icmp_pkt.data.data) icmp_data = icmp.echo(id_=echo_id,seq=echo_seq,data=echo_data) self.port_to_ip.setdefault(dpid, {}) #mask is 24 bit self.port_to_ip[dpid][in_port] = (ip_src & 0Xffffff00) + 0xfe #print 'lee 1' if self.port_to_ip[dpid][in_port] == ip_dst: #send a echo reply packet ether_dst = src ether_src = self.port_to_switch_mac[dpid][in_port] e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IP) #csum calculation should be paied attention #ic = icmp.icmp(type_= 0,code=0,csum=0,data=icmp_pkt.data) i = ipv4.ipv4(version=4,header_length=5,tos=0,total_length=0, identification=0,flags=0x000,offset=0,ttl=64,proto=1,csum=0,src=ip_dst, dst=ip_src,option=None) ic = icmp.icmp(type_= 0,code=0,csum=0,data=icmp_data) p = Packet() p.add_protocol(e) p.add_protocol(i) p.add_protocol(ic) p.serialize() datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data) print 'send a ping replay' else: pass if _eth_type == ether.ETH_TYPE_IPV6: ipv6_pkt = self.find_packet(msg,'ipv6') #don't care about ipv6's extention header icmpv6_pkt = self.find_packet(msg,'icmpv6') if icmpv6_pkt != None: if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT: self.port_to_ipv6.setdefault(dpid,{}) #self.port_to_ipv6[dpid][in_port]=hexlify(((ipv6_pkt.src & (1<<128))-(1<<64)) + (1<<64) - 2) self.port_to_ipv6[dpid][in_port]=struct.pack('!4I',0x100000,0x0,0xffffffff,0xfffffffd) if icmpv6_pkt.data.dst == self.port_to_ipv6[dpid][in_port]: #send a ND_NEIGHBOR_REPLY packet ether_dst = src ether_src = self.port_to_switch_mac[dpid][in_port] e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IPV6) ic6_data_data = icmpv6.nd_option_la(hw_src=self.port_to_switch_mac[dpid][in_port],data=None) #res = 3 or 7 ic6_data = icmpv6.nd_neighbor(res=3,dst=icmpv6_pkt.data.dst,type_=icmpv6.nd_neighbor.ND_OPTION_TLA,length=1,data=ic6_data_data) ic6 = icmpv6.icmpv6(type_=icmpv6.ND_NEIGHBOR_ADVERT,code=0,csum=0,data=ic6_data) #payload_length i6 = ipv6.ipv6(version= 6,traffic_class=0,flow_label=0,payload_length=32,nxt=58,hop_limit=255, src=icmpv6_pkt.data.dst,dst=ipv6_pkt.src) p = Packet() p.add_protocol(e) p.add_protocol(i6) p.add_protocol(ic6) p.serialize() datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data) print 'send a NA packet' if icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST: if self.port_to_ipv6[dpid].has_key(in_port): #print hexlify(self.port_to_ipv6[dpid][in_port]) #print 'ipv6_pkt.dst is',hexlify(ipv6_pkt.dst) #print 'ipv6_pkt.dst is',hexlify(ipv6_pkt.dst) if ipv6_pkt.dst == self.port_to_ipv6[dpid][in_port]: ether_dst = src ether_src = self.port_to_switch_mac[dpid][in_port] e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IPV6) ic6_data = icmpv6_pkt.data ic6 = icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY,code=0,csum=0,data=ic6_data) i6 = ipv6.ipv6(version= 6,traffic_class=0,flow_label=0,payload_length=64,nxt=58,hop_limit=64, src=ipv6_pkt.dst,dst=ipv6_pkt.src) p = Packet() p.add_protocol(e) p.add_protocol(i6) p.add_protocol(ic6) p.serialize() datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data) print 'send a ping6 reply packet' # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = msg.in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] if out_port != ofproto.OFPP_FLOOD: if _eth_type == ether.ETH_TYPE_IP: self.add_flow(datapath, msg.in_port, dst, actions) #add a ipv6 flow table pay attention ipv6_flow entry only be added once when ipv4 flow entry is added elif _eth_type == ether.ETH_TYPE_IPV6: ''' # judge if src and dst addr is special # eg: src [0,0,0,0] dst begin with 0xff01 or 0x ff02 if ipv6_src == [0,0,0,0] or ipv6_dst[0]&0xff010000 == 0xff010000 or ipv6_dst[0]&0xff020000 == 0xff020000: print 'ipv6 reserved address\n' #elif ipv6_dst[0]&0xfe800000 == 0xfe800000: # print 'ipv6 dst address is Link-Local address' else: ''' ipv6_pkt = self.find_packet(msg,'ipv6') #ipv6_src=struct.pack('!4I',self._binary_to_ipv6_format(ipv6_packet.src)) #ipv6_dst=struct.pack('!4I',self._binary_to_ipv6_format(ipv6_packet.dst)) ipv6_src = convert.bin_to_ipv6_arg_list(ipv6_pkt.src) ipv6_dst = convert.bin_to_ipv6_arg_list(ipv6_pkt.dst) """ ipv6_src = struct.pack('!4I',int(hexlify(ipv6_pkt.src)[0:8],16),int(hexlify(ipv6_pkt.src)[8:16],16),int(hexlify(ipv6_pkt.src)[16:24],16),int(hexlify(ipv6_pkt.src)[24:32],16)) ipv6_dst = struct.pack('!4I',int(hexlify(ipv6_pkt.dst)[0:8],16),int(hexlify(ipv6_pkt.dst)[8:16],16),int(hexlify(ipv6_pkt.dst)[16:24],16),int(hexlify(ipv6_pkt.dst)[24:32],16)) """ rule={'ipv6_src':ipv6_src,'ipv6_dst':ipv6_dst} self.nx_ipv6_add_flow(datapath,rule,actions) print 'add a ipv6 flow entry' else: pass out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out)
def _handle_icmpv6(self, msg, pkt, icmpv6_pkt): #print 'icmpv6', icmpv6_pkt switch = self.dpid_to_switch[msg.datapath.id] in_port_no = msg.in_port if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_ADVERT: gateway = switch.ports[in_port_no].gateway pop_list = [] ipv6_pkt = self.find_packet(pkt, 'ipv6') if gateway and gateway.gw_ipv6 == ipv6_pkt.dst: self._remember_mac_addr(switch, pkt, 6) for i in xrange(len(switch.msg_buffer)): msg, pkt, outport_no, _4or6 = switch.msg_buffer[i] if self.last_switch_out(msg, pkt, outport_no, _4or6): pop_list.append(i) pop_list.sort(reverse = True) for i in pop_list: switch.msg_buffer.pop(i) return True return False elif icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT: port = switch.ports[in_port_no] if port.gateway and icmpv6_pkt.data.dst != port.gateway.gw_ipv6: print convert.bin_to_ipv6(icmpv6_pkt.data.dst) print convert.bin_to_ipv6(port.gateway.gw_ipv6) return False #send a ND_NEIGHBOR_REPLY packet ether_layer = self.find_packet(pkt, 'ethernet') ether_dst = ether_layer.src ether_src = port.hw_addr e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IPV6) ic6_data_data = icmpv6.nd_option_la(hw_src=ether_src, data=None) #res = 3 or 7 ic6_data = icmpv6.nd_neighbor(res=3,dst=icmpv6_pkt.data.dst, type_=icmpv6.nd_neighbor.ND_OPTION_TLA,length=1, data=ic6_data_data) ic6 = icmpv6.icmpv6(type_=icmpv6.ND_NEIGHBOR_ADVERT,code=0, csum=0,data=ic6_data) #payload_length ipv6_pkt = self.find_packet(pkt, 'ipv6') i6 = ipv6.ipv6(version= 6,traffic_class=0,flow_label=0, payload_length=32,nxt=58,hop_limit=255, src=icmpv6_pkt.data.dst,dst=ipv6_pkt.src) p = packet.Packet() p.add_protocol(e) p.add_protocol(i6) p.add_protocol(ic6) p.serialize() datapath = msg.datapath datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE, actions= [datapath.ofproto_parser.OFPActionOutput(in_port_no)], data=p.data) print 'send a NA packet' return True elif icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST: ipv6_pkt = self.find_packet(pkt, 'ipv6') need_reply = False for _k, p in switch.ports.iteritems(): if p.gateway and p.gateway.gw_ipv6 == ipv6_pkt.dst: need_reply = True break if not need_reply: return False ether_layer = self.find_packet(pkt, 'ethernet') ether_dst = ether_layer.src ether_src = switch.ports[in_port_no].hw_addr e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IPV6) ic6_data = icmpv6_pkt.data ic6 = icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY,code=0, csum=0,data=ic6_data) i6 = ipv6.ipv6(version= 6,traffic_class=0,flow_label=0, payload_length=64,nxt=58,hop_limit=64, src=ipv6_pkt.dst,dst=ipv6_pkt.src) p = packet.Packet() p.add_protocol(e) p.add_protocol(i6) p.add_protocol(ic6) p.serialize() datapath = msg.datapath datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE, actions= [datapath.ofproto_parser.OFPActionOutput(in_port_no)], data=p.data) print 'send a ping6 reply packet' return True return False
def _handle_icmpv6(self, msg, pkt, icmpv6_pkt): #print 'icmpv6', icmpv6_pkt switch = self.dpid_to_switch[msg.datapath.id] in_port_no = msg.in_port if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_ADVERT: gateway = switch.ports[in_port_no].gateway pop_list = [] ipv6_pkt = self.find_packet(pkt, 'ipv6') if gateway and gateway.gw_ipv6 == ipv6_pkt.dst: self._remember_mac_addr(switch, pkt, 6) for i in xrange(len(switch.msg_buffer)): msg, pkt, outport_no, _4or6 = switch.msg_buffer[i] if self.last_switch_out(msg, pkt, outport_no, _4or6): pop_list.append(i) pop_list.sort(reverse=True) for i in pop_list: switch.msg_buffer.pop(i) return True return False elif icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT: port = switch.ports[in_port_no] if port.gateway and icmpv6_pkt.data.dst != port.gateway.gw_ipv6: print convert.bin_to_ipv6(icmpv6_pkt.data.dst) print convert.bin_to_ipv6(port.gateway.gw_ipv6) return False #send a ND_NEIGHBOR_REPLY packet ether_layer = self.find_packet(pkt, 'ethernet') ether_dst = ether_layer.src ether_src = port.hw_addr e = ethernet.ethernet(ether_dst, ether_src, ether.ETH_TYPE_IPV6) ic6_data_data = icmpv6.nd_option_la(hw_src=ether_src, data=None) #res = 3 or 7 ic6_data = icmpv6.nd_neighbor( res=3, dst=icmpv6_pkt.data.dst, type_=icmpv6.nd_neighbor.ND_OPTION_TLA, length=1, data=ic6_data_data) ic6 = icmpv6.icmpv6(type_=icmpv6.ND_NEIGHBOR_ADVERT, code=0, csum=0, data=ic6_data) #payload_length ipv6_pkt = self.find_packet(pkt, 'ipv6') i6 = ipv6.ipv6(version=6, traffic_class=0, flow_label=0, payload_length=32, nxt=58, hop_limit=255, src=icmpv6_pkt.data.dst, dst=ipv6_pkt.src) p = packet.Packet() p.add_protocol(e) p.add_protocol(i6) p.add_protocol(ic6) p.serialize() datapath = msg.datapath datapath.send_packet_out( in_port=ofproto_v1_0.OFPP_NONE, actions=[datapath.ofproto_parser.OFPActionOutput(in_port_no)], data=p.data) print 'send a NA packet' return True elif icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST: ipv6_pkt = self.find_packet(pkt, 'ipv6') need_reply = False for _k, p in switch.ports.iteritems(): if p.gateway and p.gateway.gw_ipv6 == ipv6_pkt.dst: need_reply = True break if not need_reply: return False ether_layer = self.find_packet(pkt, 'ethernet') ether_dst = ether_layer.src ether_src = switch.ports[in_port_no].hw_addr e = ethernet.ethernet(ether_dst, ether_src, ether.ETH_TYPE_IPV6) ic6_data = icmpv6_pkt.data ic6 = icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY, code=0, csum=0, data=ic6_data) i6 = ipv6.ipv6(version=6, traffic_class=0, flow_label=0, payload_length=64, nxt=58, hop_limit=64, src=ipv6_pkt.dst, dst=ipv6_pkt.src) p = packet.Packet() p.add_protocol(e) p.add_protocol(i6) p.add_protocol(ic6) p.serialize() datapath = msg.datapath datapath.send_packet_out( in_port=ofproto_v1_0.OFPP_NONE, actions=[datapath.ofproto_parser.OFPActionOutput(in_port_no)], data=p.data) print 'send a ping6 reply packet' return True return False