Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pcs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,7 @@ def fromHTML(self):
"""Create a Packet from HTML."""
pass


class Chain(list):
"""A chain is simply a list of packets. Chains are used to
aggregate related sub packets into one chunk for transmission."""
Expand Down Expand Up @@ -1559,6 +1560,7 @@ def fixup(self):
self.calc_checksums()
self.encode()


class ConnNotImpError(Exception):
"""Calling a method that is not implemented raises this exception.

Expand Down
1 change: 1 addition & 0 deletions pcs/packets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
'ipv4',
'ipv6',
'icmpv4',
'icmpv6',
'igmpv2',
'igmpv3',
'tcp',
Expand Down
24 changes: 18 additions & 6 deletions pcs/packets/icmpv6.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
# Description: A class which describes an ICMPv6 packet

import pcs
import pcs.packets.pseudoipv6
import pcs.packets.ipv4
from pcs.packets.pseudoipv6 import pseudoipv6
from pcs.packets.ipv4 import ipv4


import struct

Expand Down Expand Up @@ -132,6 +133,12 @@ def __init__(self, type = 0, bytes = None, **kv):
else:
pcs.Packet.__init__(self, [ty, code, cksum], bytes, **kv)

if (bytes is not None):
self.data = self.next(bytes[self.sizeof():len(bytes)],
timestamp = timestamp)
else:
self.data = None

def cksum(self, ip, data = "", nx = 0):
"""Calculate the checksum for this ICMPv6 header, outside
of a chain."""
Expand All @@ -153,9 +160,9 @@ def calc_checksum(self):
self.checksum = 0
if self._head is not None:
payload = self._head.collate_following(self)
ip6 = self._head.find_preceding(self, pcs.packets.ipv6)
ip6 = self._head.find_preceding(self, pcs.packets.ipv6.ipv6)[0]
assert ip6 is not None, "No preceding IPv6 header."
pip6 = pseudoipv6.pseudoipv6()
pip6 = pseudoipv6()
pip6.src = ip6.src
pip6.dst = ip6.dst
pip6.next_header = ip6.next_header
Expand All @@ -168,7 +175,7 @@ def calc_checksum(self):
class icmpv6option(pcs.Packet):

_layout = pcs.Layout()

def __init__(self, type = 0, bytes = None, **kv):
"""add icmp6 option header RFC2461"""
ty = pcs.Field("type", 8, default = type)
Expand Down Expand Up @@ -196,10 +203,15 @@ def __init__(self, type = 0, bytes = None, **kv):
elif type == 4:
reserved = pcs.StringField("reserved", 48)
pcs.Packet.__init__(self, [ty, length, reserved], bytes, **kv)
# MTU
# MTU
elif type == 5:
reserved = pcs.Field("reserved", 16)
mtu = pcs.Field("mtu", 32)
pcs.Packet.__init__(self, [ty, length, reserved, mtu], bytes, **kv)
else:
pcs.Packet.__init__(self, [ty, length], bytes, **kv)

def calc_length(self):
"""Calculate and store the length of the ICMPv6 option into the ICMPv6
option packet. The length is in units of 8-octets (8-bytes)."""
self.length = len(self) >> 3
17 changes: 12 additions & 5 deletions pcs/packets/ipv6.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
IPV6_FRAG = 44
IPV6_ESP = 50
IPV6_AH = 51
IPV6_ICMP = 58
IPV6_NONE = 59
IPV6_DSTOPTS = 60

Expand All @@ -57,7 +58,7 @@ class ipv6(pcs.Packet):

_layout = pcs.Layout()
_map = ipv6_map.map

def __init__(self, bytes = None, timestamp = None, **kv):
"""IPv6 Packet from RFC 2460"""
version = pcs.Field("version", 4, default = 6)
Expand All @@ -77,17 +78,17 @@ def __init__(self, bytes = None, timestamp = None, **kv):
else:
self.timestamp = timestamp


if (bytes is not None):
## 40 bytes is the standard size of an IPv6 header
# 40 bytes is the standard size of an IPv6 header
offset = 40
self.data = self.next(bytes[offset:len(bytes)],
timestamp = timestamp)
else:
self.data = None

def __str__(self):
"""Walk the entire packet and pretty print the values of the fields. Addresses are printed if and only if they are set and not 0."""
"""Walk the entire packet and pretty print the values of the fields.
Addresses are printed if and only if they are set and not 0."""
retval = ""
for field in self._layout:
if (field.name == "src" or field.name == "dst"):
Expand All @@ -109,3 +110,9 @@ def getipv6(self, iface):
break
return v6

def calc_length(self):
"""Calculate the IPv6 payload length and store into header. Payload
length does not include the heads length."""
self.length = 0
if self._head is not None:
self.length = len(self._head.collate_following(self))
6 changes: 3 additions & 3 deletions tests/ptptest.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@
# with extra arguments.

from pcs.packets.ptpv1 import *
from pcs.packets.ptpv1_common import Common
from pcs.packets.ptpv1_common import CommonV1
from pcs.packets.ipv4 import ipv4
from pcs.packets.udpv4 import udpv4
import pcs

class ptpTestCase(unittest.TestCase):
def test_ptp_header(self):
# create one header, copy its bytes, then compare their fields
ptp = Common()
ptp = CommonV1()
assert (ptp != None)

ptp.versionPTP = 2
Expand All @@ -66,7 +66,7 @@ def test_ptp_header(self):
ptp.controlField = 0

# Create a packet to compare against
ptpnew = Common()
ptpnew = CommonV1()
ptpnew.decode(ptp.bytes)

self.assertEqual(ptp.bytes, ptpnew.bytes, "bytes not equal")
Expand Down
4 changes: 2 additions & 2 deletions tests/ptpv1test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
# with extra arguments.

from pcs.packets.ptpv1 import *
from pcs.packets.ptpv1_common import Common
from pcs.packets.ptpv1_common import CommonV1
from pcs.packets.ipv4 import ipv4
from pcs.packets.udpv4 import udpv4
import pcs
Expand All @@ -69,7 +69,7 @@ def test_ptp_header(self):
ptp.control = 0

# Create a packet to compare against
ptpnew = Common()
ptpnew = CommonV1()
ptpnew.decode(ptp.bytes)

self.assertEqual(ptp.bytes, ptpnew.bytes, "bytes not equal")
Expand Down