def arp_response(a): r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = EthAddr('00:00:00:00:00:02') e = ethernet(type=packet.type, src=EthAddr('00:00:00:00:00:02'), dst=a.hwsrc) e.payload = r if packet.type == ethernet.VLAN_TYPE: v_rcv = packet.find('vlan') e.payload = vlan(eth_type=e.type, payload=e.payload, id=v_rcv.id, pcp=v_rcv.pcp) e.type = ethernet.VLAN_TYPE msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = event.port event.connection.send(msg)
def forwardToAppropriateController(self, event): # print "forwarding to controller : " + str(event) # Get list of controllers from VMOC Switch Controller MAP controller_conns = scmap.lookup_controllers_for_switch_connection(self) if not controller_conns: log.debug("No controller connection : dropping " + str(event)) return if event.ofp.header_type == of.OFPT_PACKET_IN: # Send the event to the client controller associated with this slice # Based on VLAN ethernet_packet = ethernet(raw=event.ofp.data) dst = ethernet_packet.dst src = ethernet_packet.src vlan_id = None if ethernet_packet.type == ethernet.VLAN_TYPE: # print "EVENT: " + str(event) vlan_data = event.ofp.data[ethernet.MIN_LEN:] vlan_packet = vlan(vlan_data) log.debug("VLAN PACKET : " + str(vlan_packet)) vlan_id = vlan_packet.id # If the switch is a 'VLAN HYBRID', # we will not get tagged packets but we can use the # VLAN asssociated with the port if not config.vmoc_set_vlan_on_untagged_flow_mod: port_info = config.vlan_port_map[str(self._port)] if not vlan_id and port_info and \ bool(port_info['handle_untagged']): vlan_id = int(port_info['vlan']) matched_controller_conn = None for controller_conn in controller_conns: if controller_conn.belongsToSlice(vlan_id, src, dst): matched_controller_conn = controller_conn break if matched_controller_conn is not None: log.debug("Sending packet " + str(event) + " " + str(ethernet_packet) + " " + str(matched_controller_conn) + " " + str(vlan_id)) try: matched_controller_conn.send(event.ofp) except Exception as e: log.debug( "Error writing to controller connection: resetting %s" % e) matched_controller_conn.close() else: log.debug("Dropping packet : " + str(event) + " " + str(ethernet_packet) + " " + str(vlan_id)) else: # Send every non-packet message directly to each controller # And the controller connection will send back every response for controller_conn in controller_conns: # log.debug("Sending to CC : " + str(event.ofp.header_type)) controller_conn.send(event.ofp)
def forwardToAppropriateController(self, event): # print "forwarding to controller : " + str(event) # Get list of controllers from VMOC Switch Controller MAP controller_conns = scmap.lookup_controllers_for_switch_connection(self) if not controller_conns: log.debug("No controller connection : dropping " + str(event)) return if event.ofp.header_type == of.OFPT_PACKET_IN: # Send the event to the client controller associated with this slice # Based on VLAN ethernet_packet = ethernet(raw=event.ofp.data) dst=ethernet_packet.dst src=ethernet_packet.src vlan_id = None if ethernet_packet.type == ethernet.VLAN_TYPE: # print "EVENT: " + str(event) vlan_data = event.ofp.data[ethernet.MIN_LEN:] vlan_packet = vlan(vlan_data) log.debug("VLAN PACKET : " + str(vlan_packet)) vlan_id = vlan_packet.id # If the switch is a 'VLAN HYBRID', # we will not get tagged packets but we can use the # VLAN asssociated with the port if not config.vmoc_set_vlan_on_untagged_flow_mod: port_info = config.vlan_port_map[str(self._port)] if not vlan_id and port_info and \ bool(port_info['handle_untagged']): vlan_id = int(port_info['vlan']) matched_controller_conn = None for controller_conn in controller_conns: if controller_conn.belongsToSlice(vlan_id, src, dst): matched_controller_conn = controller_conn break if matched_controller_conn is not None: log.debug("Sending packet " + str(event) + " " + str(ethernet_packet) + " " + str(matched_controller_conn) + " " + str(vlan_id)) try: matched_controller_conn.send(event.ofp) except Exception as e: log.debug("Error writing to controller connection: resetting %s" % e) matched_controller_conn.close() else: log.debug("Dropping packet : " + str(event) + " " + str(ethernet_packet) + " " + str(vlan_id)) else: # Send every non-packet message directly to each controller # And the controller connection will send back every response for controller_conn in controller_conns: # log.debug("Sending to CC : " + str(event.ofp.header_type)) controller_conn.send(event.ofp)
def add_vlan_to_packet(ethernet_packet, vlan_id): # Grab the ethernet packet = E new_ethernet_packet = ethernet(ethernet_packet.raw) new_ethernet_packet.type = ethernet.VLAN_TYPE E = new_ethernet_packet.hdr('') # Create the vlan packet = V vlan_packet = vlan() vlan_packet.id = vlan_id vlan_packet.pcp = 0 vlan_packet.eth_type = ethernet_packet.type V = vlan_packet.hdr('') # Grab the rest of the packet = R R = ethernet_packet.raw[ethernet.MIN_LEN:] # Construct E + V + R new_raw = E + V + R new_ethernet_packet = ethernet(new_raw) return new_ethernet_packet
def parsePacket(self, event): # data = event.ofp.data ethernet_packet = ethernet(raw=data) # print str(ethernet_packet) if ethernet_packet.type != ethernet.VLAN_TYPE: log.debug("WEIRD: Got packet without VLAN") return data, ethernet_packet, None, None vlan_packet = vlan(raw=data[ethernet.MIN_LEN:]) ethernet_packet.set_payload(vlan_packet) # print str(vlan_packet) ip_packet = None if vlan_packet.eth_type == ethernet.ARP_TYPE: ip_packet = arp(raw=data[IP_START:]) vlan_packet.set_payload(ip_packet) elif vlan_packet.eth_type == ethernet.IP_TYPE: ip_packet = ipv4(raw=data[IP_START:]) vlan_packet.set_payload(ip_packet) elif vlan_packet.eth_type == ethernet.IPV6_TYPE: pass else: log.debug("GOT soemthing that wasn't expecting: " + vlan_packet.eth_type) tcp_packet = None if ip_packet and vlan_packet.eth_type == ethernet.IP_TYPE: if ip_packet.protocol == ipv4.TCP_PROTOCOL: tcp_raw = ip_packet.raw[ipv4.MIN_LEN:] tcp_packet = tcp(raw=tcp_raw) ip_packet.set_payload(tcp_packet) payload = tcp_packet.payload # print "TCP = " + str(tcp_packet) + " PAYLOAD = " + payload # print str(ip_packet) # ip_packet.dump() return data, ethernet_packet, vlan_packet, ip_packet, tcp_packet
def _handle_PacketIn(self, event): # Note: arp.hwsrc is not necessarily equal to ethernet.src # (one such example are arp replies generated by this module itself # as ethernet mac is set to switch dpid) so we should be careful # to use only arp addresses in the learning code! squelch = False dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return a = packet.find('arp') if not a: return log.debug("%s ARP %s %s => %s", dpid_to_str(dpid), { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if _learn: # Learn or update port/MAC info if a.protosrc in _arp_table: if _arp_table[a.protosrc] != a.hwsrc: log.warn("%s RE-learned %s: %s->%s", dpid_to_str(dpid), a.protosrc, _arp_table[a.protosrc].mac, a.hwsrc) else: log.info("%s learned %s", dpid_to_str(dpid), a.protosrc) _arp_table[a.protosrc] = Entry(a.hwsrc) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in _arp_table: # We have an answer... r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst mac = _arp_table[a.protodst].mac if mac is True: # Special case -- use ourself mac = _dpid_to_mac(dpid) r.hwsrc = mac e = ethernet(type=packet.type, src=_dpid_to_mac(dpid), dst=a.hwsrc) e.payload = r if packet.type == ethernet.VLAN_TYPE: v_rcv = packet.find('vlan') e.payload = vlan(eth_type=e.type, payload=e.payload, id=v_rcv.id, pcp=v_rcv.pcp) e.type = ethernet.VLAN_TYPE log.info("%s answering ARP for %s" % (dpid_to_str(dpid), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return EventHalt if _eat_packets else None else: # Keep track of failed queries squelch = a.protodst in _failed_queries _failed_queries[a.protodst] = time.time() if self._check_for_flood(dpid, a): # Didn't know how to handle this ARP, so just flood it msg = "%s flooding ARP %s %s => %s" % (dpid_to_str(dpid), { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if squelch: log.debug(msg) else: log.info(msg) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.data = event.ofp event.connection.send(msg.pack()) return EventHalt if _eat_packets else None
def _handle_PacketIn (self, event): # Note: arp.hwsrc is not necessarily equal to ethernet.src # (one such example are arp replies generated by this module itself # as ethernet mac is set to switch dpid) so we should be careful # to use only arp addresses in the learning code! squelch = False # print _arp_table # core.openflow.addListeners(self, priority=3) dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return a = packet.find('arp') if not a: return log.debug("%s ARP %s %s => %s", dpid_to_str(dpid), {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # if _learn: # # Learn or update port/MAC info # if a.protosrc in _arp_table: # if _arp_table[a.protosrc] != a.hwsrc: # log.warn("%s RE-learned %s: %s->%s", dpid_to_str(dpid), # a.protosrc, _arp_table[a.protosrc].mac, a.hwsrc) # else: # log.info("%s learned %s", dpid_to_str(dpid), a.protosrc) # _arp_table[a.protosrc] = Entry(a.hwsrc) # print "PacketIn" # print _arp_table if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in _arp_table: # We have an answer... r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst mac = _arp_table[a.protodst].mac if mac is True: # Special case -- use ourself mac = _dpid_to_mac(dpid) r.hwsrc = mac e = ethernet(type=packet.type, src=_dpid_to_mac(dpid), dst=a.hwsrc) e.payload = r if packet.type == ethernet.VLAN_TYPE: v_rcv = packet.find('vlan') e.payload = vlan(eth_type = e.type, payload = e.payload, id = v_rcv.id, pcp = v_rcv.pcp) e.type = ethernet.VLAN_TYPE log.info("%s answering ARP for %s" % (dpid_to_str(dpid), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) # print "SUCCESS" return EventHalt if _eat_packets else None else: # Keep track of failed queries squelch = a.protodst in _failed_queries _failed_queries[a.protodst] = time.time()
def validateMessage(self, ofp, switch): ofp_revised = None if ofp.header_type == of.OFPT_FLOW_MOD: # Need to narrow down between the sub-cases for FLOW MOD below # Check that the match is okay match = ofp.match # print "COMMAND = " + str(ofp.command) + " " + str(of.OFPFC_DELETE) # print "WC = " + str(match.wildcards) + " " + str(OFPFW_ALL) if ofp.command == of.OFPFC_DELETE and not match.dl_vlan: if not config.vmoc_accept_clear_all_flows_on_startup: return None # Weird case of getting a 'clear all entries' at startup # print "OFP = " + str(ofp) # print "*** CASE 0 ***" return ofp elif match.dl_vlan == of.OFP_VLAN_NONE or not match.dl_vlan: if not config.vmoc_set_vlan_on_untagged_flow_mod: return ofp # add in the tag to the match if not set # print "OFP = " + str(ofp) # print "MATCH = " + str(match) match.dl_vlan = self._vlan # print "MATCH = " + str(match) # print "MATCH.DL_VLAN = " + str(match.dl_vlan) + " " + str(of.OFP_VLAN_NONE) # print "*** CASE 1 ***" # # pdb.set_trace() return ofp elif match.dl_vlan != self._vlan: return ofp # *** log.debug("Dropping FLOW MOD: match tagged with wrong VLAN : " + \ str(ofp) + " " + str(self)) # print "*** CASE 2 ***" # pdb.set_trace() return None # Check that the actions are okay actions = ofp.actions for action in actions: if isinstance(action, ofp_action_vlan_vid) and action.vlan_vid != self._vlan: log.debug("Dropping FLOW MOD: action to set wrong VLAN : " + \ str(ofp) + " " + str(self)) # print "*** CASE 3 ***" # pdb.set_trace() return None return ofp elif ofp.header_type == of.OFPT_PACKET_OUT: data = ofp.data ethernet_packet = ethernet(raw=data) # if packet has a VLAN, make sure it fits this connection if ethernet_packet.type == ethernet.VLAN_TYPE: vlan_packet = vlan(data[ethernet.MIN_LEN:]) if vlan_packet.id != self._vlan: log.debug("Dropping PACKET OUT: wrong VLAN set : " + str(vlan_packet) + " " + str(ofp) + " " + str(self)) # print "*** CASE 4 ***" # pdb.set_trace() return None else: return ofp else: if not config.vmoc_set_vlan_on_untagged_packet_out: return ofp # If not, set it orig_in_port = ofp.in_port new_ethernet_packet = add_vlan_to_packet(ethernet_packet, self._vlan) # Create a new ofp from the new data ofp_orig = ofp ofp = of.ofp_packet_out(data=new_ethernet_packet.raw) ofp.buffer_id = None ofp.in_port = orig_in_port ofp.actions = ofp_orig.actions ofp.xid = ofp_orig.xid log.debug("Adding vlan to PACKET_OUT : " + \ str(ethernet_packet) + " " + str(new_ethernet_packet) + " " + \ str(ofp) + " " + str(self)) # print str(ethernet_packet) # ip_packet = ipv4(ethernet_packet.raw[ethernet.MIN_LEN:]) # print str(ip_packet) # print str(ofp_orig) # print str(ofp) # print str(new_ethernet_packet) # vlan_packet = vlan(new_ethernet_packet.raw[ethernet.MIN_LEN:]) # print str(vlan_packet) # ip_packet = ipv4(new_ethernet_packet.raw[ethernet.MIN_LEN+vlan.MIN_LEN:]) # print str(ip_packet) # pdb.set_trace() return ofp else: # Not a FLOW_MOD or PACKET_OUT return ofp
def _handle_PacketIn (self, event): # Note: arp.hwsrc is not necessarily equal to ethernet.src # (one such example are arp replies generated by this module itself # as ethernet mac is set to switch dpid) so we should be careful # to use only arp addresses in the learning code! squelch = False dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return a = packet.find('arp') if not a: return log.debug("%s ARP %s %s => %s", dpid_to_str(dpid), {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if _learn: # Learn or update port/MAC info old_entry = _arp_table.get(a.protosrc) if old_entry is None: log.info("%s learned %s", dpid_to_str(dpid), a.protosrc) _arp_table[a.protosrc] = Entry(a.hwsrc) else: if old_entry.mac is True: # We never replace these special cases. # Might want to warn on conflict? pass elif old_entry.mac != a.hwsrc: if old_entry.static: log.warn("%s static entry conflict %s: %s->%s", dpid_to_str(dpid), a.protosrc, old_entry.mac, a.hwsrc) else: log.warn("%s RE-learned %s: %s->%s", dpid_to_str(dpid), a.protosrc, old.entry.mac, a.hwsrc) _arp_table[a.protosrc] = Entry(a.hwsrc) else: # Update timestamp _arp_table[a.protosrc] = Entry(a.hwsrc) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in _arp_table: # We have an answer... r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst mac = _arp_table[a.protodst].mac if mac is True: # Special case -- use ourself mac = event.connection.eth_addr r.hwsrc = mac e = ethernet(type=packet.type, src=event.connection.eth_addr, dst=a.hwsrc) e.payload = r if packet.type == ethernet.VLAN_TYPE: v_rcv = packet.find('vlan') e.payload = vlan(eth_type = e.type, payload = e.payload, id = v_rcv.id, pcp = v_rcv.pcp) e.type = ethernet.VLAN_TYPE log.info("%s answering ARP for %s" % (dpid_to_str(dpid), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return EventHalt if _eat_packets else None else: # Keep track of failed queries squelch = a.protodst in _failed_queries _failed_queries[a.protodst] = time.time() if self._check_for_flood(dpid, a): # Didn't know how to handle this ARP, so just flood it msg = "%s flooding ARP %s %s => %s" % (dpid_to_str(dpid), {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst) if squelch: log.debug(msg) else: log.info(msg) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.data = event.ofp event.connection.send(msg.pack()) return EventHalt if _eat_packets else None
def _handle_PacketIn(self, event): # Note: arp.hwsrc is not necessarily equal to ethernet.src # (one such example are arp replies generated by this module itself # as ethernet mac is set to switch dpid) so we should be careful # to use only arp addresses in the learning code! squelch = False dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return #UPDATE ARP TABLE BASED ON DHCP checkD = packet.find('ipv4') if checkD: cD = checkD.payload if cD.srcport == pkt.dhcp.CLIENT_PORT or cD.srcport == pkt.dhcp.SERVER_PORT: bootPk = cD.payload dhcpOpt = bootPk.options.get(bootPk.MSG_TYPE_OPT) print "FOUND A DHCP PACKET; LOOKIE THERE, with option: " + str( dhcpOpt) if dhcpOpt.type == 5: _arp_table[bootPk.yiaddr] = Entry(packet.dst, static=False) elif dhcpOpt.type == 7: print "Looking to release" + str(bootPk.ciaddr) for k, v in _arp_table.iteritems(): print k, v if bootPk.ciaddr in _arp_table: print "Let's get rid of the IP-MAC binding for " + str( bootPk.ciaddr) del _arp_table[bootPk.ciaddr] a = packet.find('arp') if not a: return log.debug("%s ARP %s %s => %s", dpid_to_str(dpid), { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if _learn: # Learn or update port/MAC info old_entry = _arp_table.get(a.protosrc) if old_entry is None: log.info("%s learned %s", dpid_to_str(dpid), a.protosrc) _arp_table[a.protosrc] = Entry(a.hwsrc) else: if old_entry.mac is True: # We never replace these special cases. # Might want to warn on conflict? pass elif old_entry.mac != a.hwsrc: if old_entry.static: log.warn( "%s static entry conflict %s: %s->%s", dpid_to_str(dpid), a.protosrc, old_entry.mac, a.hwsrc) else: log.warn("%s RE-learned %s: %s->%s", dpid_to_str(dpid), a.protosrc, old_entry.mac, a.hwsrc) _arp_table[a.protosrc] = Entry(a.hwsrc) else: # Update timestamp _arp_table[a.protosrc] = Entry(a.hwsrc) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in _arp_table: # We have an answer... r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst mac = _arp_table[a.protodst].mac if mac is True: # Special case -- use ourself mac = event.connection.eth_addr r.hwsrc = mac e = ethernet(type=packet.type, src=event.connection.eth_addr, dst=a.hwsrc) e.payload = r if packet.type == ethernet.VLAN_TYPE: v_rcv = packet.find('vlan') e.payload = vlan(eth_type=e.type, payload=e.payload, id=v_rcv.id, pcp=v_rcv.pcp) e.type = ethernet.VLAN_TYPE log.info("%s answering ARP for %s" % (dpid_to_str(dpid), str(r.protosrc))) log.info("The corresponding MAC is %s" % str(r.hwsrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return EventHalt if _eat_packets else None else: # Keep track of failed queries squelch = a.protodst in _failed_queries _failed_queries[a.protodst] = time.time() if self._check_for_flood(dpid, a): # Didn't know how to handle this ARP, so just flood it msg = "%s flooding ARP %s %s => %s" % (dpid_to_str(dpid), { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if squelch: log.debug(msg) else: log.info(msg) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.data = event.ofp event.connection.send(msg.pack()) return EventHalt if _eat_packets else None
vlan_packet.id = vlan_id vlan_packet.pcp = 0 vlan_packet.eth_type = ethernet_packet.type V = vlan_packet.hdr('') # Grab the rest of the packet = R R = ethernet_packet.raw[ethernet.MIN_LEN:] # Construct E + V + R new_raw = E + V + R new_ethernet_packet = ethernet(new_raw) return new_ethernet_packet if __name__ == "__main__": eth = ethernet() eth.dst = EthAddr("01:02:03:04:05:06") eth.src = EthAddr("11:12:13:14:15:16") eth.type = ethernet.IP_TYPE ip = ipv4() ip.srcip = IPAddr("128.99.98.97") ip.dstip = IPAddr("128.89.8.87") joint_eth = ethernet(eth.hdr('') + ip.hdr('')) print "JOINT = " + str(joint_eth) print "IP = " + str(ipv4(joint_eth.raw[ethernet.MIN_LEN:])) joint_eth_vlan = add_vlan_to_packet(joint_eth, 1000) print "JOINT_V = " + str(joint_eth_vlan) print "V = " + str(vlan(joint_eth_vlan.raw[ethernet.MIN_LEN:])) print "IP = " + str(ipv4(joint_eth_vlan.raw[ethernet.MIN_LEN+vlan.MIN_LEN:]))