コード例 #1
0
 def _ioctl_set_ipv4 (self, which, value):
   value = IPAddr(value)
   sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
   ifr = struct.pack(str(IFNAMESIZ) + "sHHI", self.name, socket.AF_INET, 0,
                     value.toUnsigned(networkOrder=True))
   ifr += "\0" * (IFREQ_SIZE - len(ifr))
   ret = ioctl(sock, which, ifr)
コード例 #2
0
ファイル: dhcp_server.py プロジェクト: rubiruchi/sd-mcan
 def __contains__(self, item):
     item = IPAddr(item)
     if item in self.removed: return False
     n = item.toUnsigned()
     mask = (1 << self.host_size) - 1
     nm = (n & mask) | self.network.toUnsigned()
     if nm != n: return False
     if (n & mask) == mask: return False
     if (n & mask) < self.first: return False
     if (n & mask) > self.last: return False
     return True
コード例 #3
0
 def __contains__ (self, item):
   item = IPAddr(item)
   if item in self.removed: return False
   n = item.toUnsigned()
   mask = (1<<self.host_size)-1
   nm = (n & mask) | self.network.toUnsigned()
   if nm != n: return False
   if (n & mask) == mask: return False
   if (n & mask) < self.first: return False
   if (n & mask) > self.last: return False
   return True
コード例 #4
0
ファイル: dhcp_server.py プロジェクト: rubiruchi/sd-mcan
class SimpleAddressPool(AddressPool):
    """
  Simple AddressPool for simple subnet based pools.
  """
    def __init__(self,
                 network="192.168.0.0/24",
                 first=1,
                 last=None,
                 count=None):
        """
    Simple subnet-based address pool

    Allocates count IP addresses out of network/network_size, starting
    with the first'th.  You may specify the end of the range with either
    last (to specify the last'th address to use) or count to specify the
    number to use.  If both are None, use up to the end of all
    legal addresses.

    Example for all of 192.168.x.x/16:
      SimpleAddressPool("192.168.0.0/16", 1, 65534)
    """

        network, network_size = parse_cidr(network)

        self.first = first
        self.network_size = network_size
        self.host_size = 32 - network_size
        self.network = IPAddr(network)

        # use entire host space
        if last is None and count is None:
            self.last = (1 << self.host_size) - 2
        # set last address to use
        elif last is not None:
            self.last = last
        # just use count many
        elif count is not None:
            self.last = self.first + count - 1
        else:
            raise RuntimeError("Cannot specify both last and count")

        self.removed = set()

        # error checking here
        if self.count <= 0: raise RuntimeError("Bad first/last range")
        if first == 0: raise RuntimeError("Can't allocate 0th address")
        if self.host_size < 0 or self.host_size > 32:
            raise RuntimeError("Bad network")
        if IPAddr(self.last | self.network.toUnsigned()) not in self:
            raise RuntimeError("Bad first/last range")

    def __repr__(self):
        return str(self)

    def __str__(self):
        t = self.network.toUnsigned()
        t = (IPAddr(t | self.first), IPAddr(t | self.last))
        return "<Addresses from %s to %s>" % t

    @property
    def subnet_mask(self):
        return IPAddr(((1 << self.network_size) - 1) << self.host_size)

    @property
    def count(self):
        return self.last - self.first + 1

    def __contains__(self, item):
        item = IPAddr(item)
        if item in self.removed: return False
        n = item.toUnsigned()
        mask = (1 << self.host_size) - 1
        nm = (n & mask) | self.network.toUnsigned()
        if nm != n: return False
        if (n & mask) == mask: return False
        if (n & mask) < self.first: return False
        if (n & mask) > self.last: return False
        return True

    def append(self, item):
        item = IPAddr(item)
        if item not in self.removed:
            if item in self:
                raise RuntimeError("%s is already in this pool" % (item, ))
            else:
                raise RuntimeError("%s does not belong in this pool" %
                                   (item, ))
        self.removed.remove(item)

    def remove(self, item):
        item = IPAddr(item)
        if item not in self:
            raise RuntimeError("%s not in this pool" % (item, ))
        self.removed.add(item)

    def __len__(self):
        return (self.last - self.first + 1) - len(self.removed)

    def __getitem__(self, index):
        if index < 0:
            raise RuntimeError("Negative indices not allowed")
        if index >= len(self):
            raise IndexError("Item does not exist")
        c = self.first

        # Use a heuristic to find the first element faster (we hope)
        # Note this means that removing items changes the order of
        # our "list".
        c += len(self.removed)
        while c > self.last:
            c -= self.count

        while True:
            addr = IPAddr(c | self.network.toUnsigned())
            if addr not in self.removed:
                assert addr in self
                index -= 1
                if index < 0: return addr
            c += 1
            if c > self.last: c -= self.count
コード例 #5
0
class ipv4(packet_base):
    "IP packet struct"

    MIN_LEN = 20

    IPv4 = 4
    ICMP_PROTOCOL = 1
    TCP_PROTOCOL = 6
    UDP_PROTOCOL = 17
    IGMP_PROTOCOL = 2
    PWOSPF_PROTOCOL = 25

    DF_FLAG = 0x02
    MF_FLAG = 0x01

    ip_id = int(time.time())

    def __init__(self, raw=None, prev=None, **kw):
        packet_base.__init__(self)

        self.prev = prev

        self.v = 4
        self.hl = ipv4.MIN_LEN / 4
        self.tos = 0
        self.iplen = ipv4.MIN_LEN
        ipv4.ip_id = (ipv4.ip_id + 1) & 0xffff
        self.id = ipv4.ip_id
        self.flags = 0
        self.frag = 0
        self.ttl = 64
        self.protocol = 0
        self.csum = 0
        self.srcip = IP_ANY
        self.dstip = IP_ANY
        self.next = b''

        if raw is not None:
            self.parse(raw)

        self._init(kw)

    def __str__(self):
        s = "[IP+%s %s>%s (cs:%02x v:%s hl:%s l:%s t:%s)]" % (
            ipproto_to_str(self.protocol), self.srcip, self.dstip, self.csum,
            self.v, self.hl, self.iplen, self.ttl)

        return s

    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.next = None  # In case of unfinished parsing
        self.raw = raw
        dlen = len(raw)
        if dlen < ipv4.MIN_LEN:
            self.msg(
                'warning IP packet data too short to parse header: data len %u'
                % (dlen, ))
            return

        (vhl, self.tos, self.iplen, self.id, self.frag, self.ttl,
            self.protocol, self.csum, self.srcip, self.dstip) \
             = struct.unpack('!BBHHHBBHII', raw[:ipv4.MIN_LEN])

        self.v = vhl >> 4
        self.hl = vhl & 0x0f

        self.flags = self.frag >> 13
        self.frag = self.frag & 0x1fff

        self.dstip = IPAddr(self.dstip)
        self.srcip = IPAddr(self.srcip)

        if self.v != ipv4.IPv4:
            self.msg('(ip parse) warning IP version %u not IPv4' % self.v)
            return
        elif self.hl < 5:
            self.msg('(ip parse) warning IP header %u longer than len %u' \
                        % (self.hl, self.iplen))
            return
        elif self.iplen < ipv4.MIN_LEN:
            self.msg('(ip parse) warning invalid IP len %u' % self.iplen)
            return
        elif (self.hl * 4) >= self.iplen or (self.hl * 4) > dlen:
            self.msg('(ip parse) warning IP header %u longer than len %u' \
                        % (self.hl, self.iplen))
            return

        # At this point, we are reasonably certain that we have an IP
        # packet
        self.parsed = True

        length = self.iplen
        if length > dlen:
            length = dlen  # Clamp to what we've got
        if self.protocol == ipv4.UDP_PROTOCOL:
            self.next = udp(raw=raw[self.hl * 4:length], prev=self)
        elif self.protocol == ipv4.TCP_PROTOCOL:
            self.next = tcp(raw=raw[self.hl * 4:length], prev=self)
        elif self.protocol == ipv4.ICMP_PROTOCOL:
            self.next = icmp(raw=raw[self.hl * 4:length], prev=self)
        elif self.protocol == ipv4.IGMP_PROTOCOL:
            self.next = igmp(raw=raw[self.hl * 4:length], prev=self)
        elif self.protocol == ipv4.PWOSPF_PROTOCOL:
            self.next = pwospf(raw=raw[self.hl * 4:length], prev=self)
        elif dlen < self.iplen:
            self.msg(
                '(ip parse) warning IP packet data shorter than IP len: %u < %u'
                % (dlen, self.iplen))
        else:
            self.next = raw[self.hl * 4:length]

        if isinstance(self.next, packet_base) and not self.next.parsed:
            self.next = raw[self.hl * 4:length]

    def checksum(self):
        data = struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos,
                           self.iplen, self.id, (self.flags << 13) | self.frag,
                           self.ttl, self.protocol, 0, self.srcip.toUnsigned(),
                           self.dstip.toUnsigned())
        return checksum(data, 0)

    def hdr(self, payload):
        self.iplen = self.hl * 4 + len(payload)
        self.csum = self.checksum()
        return struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos,
                           self.iplen, self.id, (self.flags << 13) | self.frag,
                           self.ttl, self.protocol, self.csum,
                           self.srcip.toUnsigned(), self.dstip.toUnsigned())
コード例 #6
0
ファイル: ipv4.py プロジェクト: TingOOOgniT/sine_controller
class ipv4(packet_base):
    "IP packet struct"

    MIN_LEN = 20

    IPv4 = 4
    ICMP_PROTOCOL = 1
    TCP_PROTOCOL  = 6
    UDP_PROTOCOL  = 17
    IGMP_PROTOCOL = 2
    SINE_PROTOCOL = 160 #DJ++ 20131204 10100000


    DF_FLAG = 0x02
    MF_FLAG = 0x01

    ip_id = int(time.time())

    def __init__(self, raw=None, prev=None, **kw):
        packet_base.__init__(self)

        self.prev = prev

        self.v     = 4
        self.hl    = ipv4.MIN_LEN / 4
        self.tos   = 0
        self.iplen = ipv4.MIN_LEN
        ipv4.ip_id = (ipv4.ip_id + 1) & 0xffff
        self.id    = ipv4.ip_id
        self.flags = 0
        self.frag  = 0
        self.ttl   = 64
        self.protocol = 0
        self.csum  = 0
        self.srcip = IP_ANY
        self.dstip = IP_ANY
        self.next  = b''

        if raw is not None:
            self.parse(raw)

        self._init(kw) #for what? DJ 20131218

    def __str__(self):
        s = "[IP+%s %s>%s (cs:%02x v:%s hl:%s l:%s t:%s)]" % (
            ipproto_to_str(self.protocol),
            self.srcip, self.dstip,
            self.csum,
            self.v, self.hl, self.iplen, self.ttl)

        return s

    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < ipv4.MIN_LEN:
            self.msg('warning IP packet data too short to parse header: data len %u' % (dlen,))
            return

        (vhl, self.tos, self.iplen, self.id, self.frag, self.ttl,
            self.protocol, self.csum, self.srcip, self.dstip) \
             = struct.unpack('!BBHHHBBHII', raw[:ipv4.MIN_LEN])

        self.v = vhl >> 4
        self.hl = vhl & 0x0f

        self.flags = self.frag >> 13
        self.frag  = self.frag & 0x1fff

        if self.v != ipv4.IPv4:
            self.msg('(ip parse) warning IP version %u not IPv4' % self.v)
            return
        elif self.hl < 5:
            self.msg('(ip parse) warning IP header %u longer than len %u' \
                        % (self.hl, self.iplen))
            return
        elif self.iplen < ipv4.MIN_LEN:
            self.msg('(ip parse) warning invalid IP len %u' % self.iplen)
            return
        elif (self.hl * 4) >= self.iplen or (self.hl * 4) > dlen:
            self.msg('(ip parse) warning IP header %u longer than len %u' \
                        % (self.hl, self.iplen))
            return

        self.dstip = IPAddr(self.dstip)
        self.srcip = IPAddr(self.srcip)

        # At this point, we are reasonably certain that we have an IP
        # packet
        self.parsed = True

        length = self.iplen
        if length > dlen:
            length = dlen # Clamp to what we've got
        if self.protocol == ipv4.UDP_PROTOCOL:
            self.next = udp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.TCP_PROTOCOL:
            self.next = tcp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.ICMP_PROTOCOL:
            self.next = icmp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.IGMP_PROTOCOL:
            self.next = igmp(raw=raw[self.hl*4:length], prev=self)
        #DJ++ 20131204
        elif self.protocol == ipv4.SINE_PROTOCOL:
            self.next = sine(raw=raw[self.hl*4:length], prev=self)
        elif dlen < self.iplen:
            self.msg('(ip parse) warning IP packet data shorter than IP len: %u < %u' % (dlen, self.iplen))
        else:
            self.next =  raw[self.hl*4:length]

        if isinstance(self.next, packet_base) and not self.next.parsed:
            self.next = raw[self.hl*4:length]

    def checksum(self):
        data = struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos,
                                 self.iplen, self.id,
                                 (self.flags << 13) | self.frag, self.ttl,
                                 self.protocol, 0, self.srcip.toUnsigned(),
                                 self.dstip.toUnsigned())
        return checksum(data, 0)


    def hdr(self, payload):
        self.iplen = self.hl * 4 + len(payload)
        self.csum = self.checksum()
        return struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos,
                           self.iplen, self.id,
                           (self.flags << 13) | self.frag, self.ttl,
                           self.protocol, self.csum, self.srcip.toUnsigned(),
                           self.dstip.toUnsigned())
コード例 #7
0
class SimpleAddressPool (AddressPool):
  """
  Simple AddressPool for simple subnet based pools.
  """
  def __init__ (self, network = "192.168.0.0/24", first = 1, last = None,
                count = None):
    """
    Simple subnet-based address pool

    Allocates count IP addresses out of network/network_size, starting
    with the first'th.  You may specify the end of the range with either
    last (to specify the last'th address to use) or count to specify the
    number to use.  If both are None, use up to the end of all
    legal addresses.

    Example for all of 192.168.x.x/16:
      SimpleAddressPool("192.168.0.0/16", 1, 65534)
    """
    network,network_size = parse_cidr(network)

    self.first = first
    self.network_size = network_size
    self.host_size = 32-network_size
    self.network = IPAddr(network)

    if last is None and count is None:
      self.last = (1 << self.host_size) - 2
    elif last is not None:
      self.last = last
    elif count is not None:
      self.last = self.first + count - 1
    else:
      raise RuntimeError("Cannot specify both last and count")

    self.removed = set()

    if self.count <= 0: raise RuntimeError("Bad first/last range")
    if first == 0: raise RuntimeError("Can't allocate 0th address")
    if self.host_size < 0 or self.host_size > 32:
      raise RuntimeError("Bad network")
    if IPAddr(self.last | self.network.toUnsigned()) not in self:
      raise RuntimeError("Bad first/last range")

  def __repr__ (self):
    return str(self)

  def __str__ (self):
    t = self.network.toUnsigned()
    t = (IPAddr(t|self.first),IPAddr(t|self.last))
    return "<Addresses from %s to %s>" % t

  @property
  def subnet_mask (self):
    return IPAddr(((1<<self.network_size)-1) << self.host_size)

  @property
  def count (self):
    return self.last - self.first + 1

  def __contains__ (self, item):
    item = IPAddr(item)
    if item in self.removed: return False
    n = item.toUnsigned()
    mask = (1<<self.host_size)-1
    nm = (n & mask) | self.network.toUnsigned()
    if nm != n: return False
    if (n & mask) == mask: return False
    if (n & mask) < self.first: return False
    if (n & mask) > self.last: return False
    return True

  def append (self, item):
    item = IPAddr(item)
    if item not in self.removed:
      if item in self:
        raise RuntimeError("%s is already in this pool" % (item,))
      else:
        raise RuntimeError("%s does not belong in this pool" % (item,))
    self.removed.remove(item)

  def remove (self, item):
    item = IPAddr(item)
    if item not in self:
      raise RuntimeError("%s not in this pool" % (item,))
    self.removed.add(item)

  def __len__ (self):
    return (self.last-self.first+1) - len(self.removed)

  def __getitem__ (self, index):
    if index < 0:
      raise RuntimeError("Negative indices not allowed")
    if index >= len(self):
      raise IndexError("Item does not exist")
    c = self.first

    # Use a heuristic to find the first element faster (we hope)
    # Note this means that removing items changes the order of
    # our "list".
    c += len(self.removed)
    while c > self.last:
      c -= self.count

    while True:
      addr = IPAddr(c | self.network.toUnsigned())
      if addr not in self.removed:
        assert addr in self
        index -= 1
        if index < 0: return addr
      c += 1
      if c > self.last: c -= self.count
コード例 #8
0
ファイル: arp.py プロジェクト: XianliangJ/collections
class arp(packet_base):
    "ARP/RARP packet struct"

    MIN_LEN = 28

    HW_TYPE_ETHERNET = 1
    PROTO_TYPE_IP = 0x0800

    # OPCODES
    REQUEST = 1  # ARP
    REPLY = 2  # ARP
    REV_REQUEST = 3  # RARP
    REV_REPLY = 4  # RARP

    def __init__(self, raw=None, prev=None, **kw):
        packet_base.__init__(self)

        self.prev = prev

        self.hwtype = arp.HW_TYPE_ETHERNET
        self.prototype = arp.PROTO_TYPE_IP
        self.hwsrc = ETHER_ANY
        self.hwdst = ETHER_ANY
        self.hwlen = 6
        self.opcode = 0
        self.protolen = 4
        self.protosrc = IP_ANY
        self.protodst = IP_ANY
        self.next = b""

        if raw is not None:
            self.parse(raw)

        self._init(kw)

    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < arp.MIN_LEN:
            self.msg("(arp parse) warning IP packet data too short to parse header: data len %u" % dlen)
            return

        (self.hwtype, self.prototype, self.hwlen, self.protolen, self.opcode) = struct.unpack("!HHBBH", raw[:8])

        if self.hwtype != arp.HW_TYPE_ETHERNET:
            self.msg("(arp parse) hw type unknown %u" % self.hwtype)
        if self.hwlen != 6:
            self.msg("(arp parse) unknown hw len %u" % self.hwlen)
        else:
            self.hwsrc = EthAddr(raw[8:14])
            self.hwdst = EthAddr(raw[18:24])
        if self.prototype != arp.PROTO_TYPE_IP:
            self.msg("(arp parse) proto type unknown %u" % self.prototype)
        if self.protolen != 4:
            self.msg("(arp parse) unknown proto len %u" % self.protolen)
        else:
            self.protosrc = IPAddr(struct.unpack("!I", raw[14:18])[0])
            self.protodst = IPAddr(struct.unpack("!I", raw[24:28])[0])

        self.next = raw[28:]
        self.parsed = True

    def hdr(self, payload):
        buf = struct.pack("!HHBBH", self.hwtype, self.prototype, self.hwlen, self.protolen, self.opcode)
        if type(self.hwsrc) == bytes:
            buf += self.hwsrc
        else:
            buf += self.hwsrc.toRaw()
        if type(self.protosrc) is IPAddr:
            buf += struct.pack("!I", self.protosrc.toUnsigned())
        else:
            buf += struct.pack("!I", self.protosrc)
        if type(self.hwdst) == bytes:
            buf += self.hwdst
        else:
            buf += self.hwdst.toRaw()
        if type(self.protodst) is IPAddr:
            buf += struct.pack("!I", self.protodst.toUnsigned())
        else:
            buf += struct.pack("!I", self.protodst)
        return buf

    def __str__(self):
        op = str(self.opcode)

        eth_type = None
        # Ethernet
        if hasattr(self.prev, "type"):
            eth_type = self.prev.type
        # Vlan
        elif hasattr(self.prev, "eth_type"):
            eth_type = self.prev.eth_type
        else:
            self.err("(arp) unknown datalink type")
            eth_type = ethernet.ARP_TYPE

        if eth_type == ethernet.ARP_TYPE:
            if self.opcode == arp.REQUEST:
                op = "REQUEST"
            elif self.opcode == arp.REPLY:
                op = "REPLY"
        elif eth_type == ethernet.RARP_TYPE:
            if self.opcode == arp.REV_REQUEST:
                op = "REV_REQUEST"
            elif self.opcode == arp.REV_REPLY:
                op = "REV_REPLY"

        s = "{0} hw:{1} p:{2} {3}>{4} {5}>{6}".format(
            op,
            self.hwtype,
            self.prototype,
            EthAddr(self.hwsrc),
            EthAddr(self.hwdst),
            IPAddr(self.protosrc),
            IPAddr(self.protodst),
        )
        return s
コード例 #9
0
ファイル: arp.py プロジェクト: RunNJump/cs168
class arp(packet_base):
    "ARP/RARP packet struct"

    MIN_LEN = 28

    HW_TYPE_ETHERNET = 1
    PROTO_TYPE_IP = 0x0800

    # OPCODES
    REQUEST = 1  # ARP
    REPLY = 2  # ARP
    REV_REQUEST = 3  # RARP
    REV_REPLY = 4  # RARP

    def __init__(self, raw=None, prev=None, **kw):
        packet_base.__init__(self)

        self.prev = prev

        self.hwtype = arp.HW_TYPE_ETHERNET
        self.prototype = arp.PROTO_TYPE_IP
        self.hwsrc = ETHER_ANY
        self.hwdst = ETHER_ANY
        self.hwlen = 6
        self.opcode = 0
        self.protolen = 4
        self.protosrc = IP_ANY
        self.protodst = IP_ANY
        self.next = b''

        if raw is not None:
            self.parse(raw)

        self._init(kw)

    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.next = None  # In case of unfinished parsing
        self.raw = raw
        dlen = len(raw)
        if dlen < arp.MIN_LEN:
            self.msg(
                '(arp parse) warning IP packet data too short to parse header: data len %u'
                % dlen)
            return

        (self.hwtype, self.prototype, self.hwlen, self.protolen,self.opcode) =\
        struct.unpack('!HHBBH', raw[:8])

        if self.hwtype != arp.HW_TYPE_ETHERNET:
            self.msg('(arp parse) hw type unknown %u' % self.hwtype)
            return
        if self.hwlen != 6:
            self.msg('(arp parse) unknown hw len %u' % self.hwlen)
            return
        else:
            self.hwsrc = EthAddr(raw[8:14])
            self.hwdst = EthAddr(raw[18:24])
        if self.prototype != arp.PROTO_TYPE_IP:
            self.msg('(arp parse) proto type unknown %u' % self.prototype)
            return
        if self.protolen != 4:
            self.msg('(arp parse) unknown proto len %u' % self.protolen)
            return
        else:
            self.protosrc = IPAddr(struct.unpack('!I', raw[14:18])[0])
            self.protodst = IPAddr(struct.unpack('!I', raw[24:28])[0])

        self.next = raw[28:]
        self.parsed = True

    def hdr(self, payload):
        buf = struct.pack('!HHBBH', self.hwtype, self.prototype, self.hwlen,
                          self.protolen, self.opcode)
        if type(self.hwsrc) == bytes:
            buf += self.hwsrc
        else:
            buf += self.hwsrc.toRaw()
        if type(self.protosrc) is IPAddr:
            buf += struct.pack('!I', self.protosrc.toUnsigned())
        else:
            buf += struct.pack('!I', self.protosrc)
        if type(self.hwdst) == bytes:
            buf += self.hwdst
        else:
            buf += self.hwdst.toRaw()
        if type(self.protodst) is IPAddr:
            buf += struct.pack('!I', self.protodst.toUnsigned())
        else:
            buf += struct.pack('!I', self.protodst)
        return buf

    def _to_str(self):
        op = str(self.opcode)

        eth_type = None
        # Ethernet
        if hasattr(self.prev, 'type'):
            eth_type = self.prev.type
        # Vlan
        elif hasattr(self.prev, 'eth_type'):
            eth_type = self.prev.eth_type
        else:
            self.err('(arp) unknown datalink type')
            eth_type = ethernet.ARP_TYPE

        if eth_type == ethernet.ARP_TYPE:
            if self.opcode == arp.REQUEST:
                op = "REQUEST"
            elif self.opcode == arp.REPLY:
                op = "REPLY"
        elif eth_type == ethernet.RARP_TYPE:
            if self.opcode == arp.REV_REQUEST:
                op = "REV_REQUEST"
            elif self.opcode == arp.REV_REPLY:
                op = "REV_REPLY"

        s = "[ARP {0} hw:{1} p:{2} {3}>{4} {5}>{6}]".format(
            op, self.hwtype, self.prototype, EthAddr(self.hwsrc),
            EthAddr(self.hwdst), IPAddr(self.protosrc), IPAddr(self.protodst))
        return s