packet lib: ipv6: simplify the operations of __init__()

before applying this patch:
  - ipv6.parser() uses 'nxt' of the last extension header
  - ipv6.__init__() rewrites 'nxt' in conjunction with extension headers
  - 'nxt' of the extension headers are set automatically, i.e. they are obscure

after applying this patch:
  - ipv6.parser() does not consider 'nxt' of the extension headers
  - ipv6.__init__() does not rewrite 'nxt'
  - 'nxt' of the extension headers are set manually as an argument of __init__()

Signed-off-by: itoyuichi <ito.yuichi0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
Yuichi Ito 2013-09-25 13:58:45 +09:00 committed by FUJITA Tomonori
parent 2275dc15cc
commit 96afdc7bbc
2 changed files with 48 additions and 60 deletions

View File

@ -80,16 +80,8 @@ class ipv6(packet_base.PacketBase):
self.dst = dst
if ext_hdrs:
assert isinstance(ext_hdrs, list)
last_hdr = None
for ext_hdr in ext_hdrs:
assert isinstance(ext_hdr, header)
if last_hdr:
ext_hdr.set_nxt(last_hdr.nxt)
last_hdr.nxt = ext_hdr.TYPE
else:
ext_hdr.set_nxt(self.nxt)
self.nxt = ext_hdr.TYPE
last_hdr = ext_hdr
self.ext_hdrs = ext_hdrs
@classmethod
@ -111,10 +103,8 @@ class ipv6(packet_base.PacketBase):
ext_hdrs.append(hdr)
offset += len(hdr)
last = hdr.nxt
# call ipv6.__init__() using 'nxt' of the last extension
# header that points the next protocol.
msg = cls(version, traffic_class, flow_label, payload_length,
last, hop_limit, addrconv.ipv6.bin_to_text(src),
nxt, hop_limit, addrconv.ipv6.bin_to_text(src),
addrconv.ipv6.bin_to_text(dst), ext_hdrs)
return (msg, ipv6.get_packet_type(last),
buf[offset:offset+payload_length])
@ -148,10 +138,7 @@ class header(stringify.StringifyMixin):
__metaclass__ = abc.ABCMeta
def __init__(self):
self.nxt = None
def set_nxt(self, nxt):
def __init__(self, nxt):
self.nxt = nxt
@classmethod
@ -179,8 +166,8 @@ class opt_header(header):
_FIX_SIZE = 8
@abc.abstractmethod
def __init__(self, size, data):
super(opt_header, self).__init__()
def __init__(self, nxt, size, data):
super(opt_header, self).__init__(nxt)
assert not (size % 8)
self.size = size
self.data = data
@ -200,9 +187,7 @@ class opt_header(header):
opt = option.parser(buf[size:])
size += len(opt)
data.append(opt)
ret = cls(len_, data)
ret.set_nxt(nxt)
return ret
return cls(nxt, len_, data)
def serialize(self):
buf = struct.pack(self._PACK_STR, self.nxt, self.size)
@ -230,6 +215,7 @@ class hop_opts(opt_header):
============== =======================================
Attribute Description
============== =======================================
nxt Next Header
size the length of the Hop-by-Hop Options header,
not include the first 8 octet.
data IPv6 options.
@ -237,8 +223,8 @@ class hop_opts(opt_header):
"""
TYPE = inet.IPPROTO_HOPOPTS
def __init__(self, size, data):
super(hop_opts, self).__init__(size, data)
def __init__(self, nxt, size, data):
super(hop_opts, self).__init__(nxt, size, data)
@ipv6.register_header_type(inet.IPPROTO_DSTOPTS)
@ -256,6 +242,7 @@ class dst_opts(opt_header):
============== =======================================
Attribute Description
============== =======================================
nxt Next Header
size the length of the destination header,
not include the first 8 octet.
data IPv6 options.
@ -263,8 +250,8 @@ class dst_opts(opt_header):
"""
TYPE = inet.IPPROTO_DSTOPTS
def __init__(self, size, data):
super(dst_opts, self).__init__(size, data)
def __init__(self, nxt, size, data):
super(dst_opts, self).__init__(nxt, size, data)
class option(stringify.StringifyMixin):
@ -341,6 +328,7 @@ class fragment(header):
============== =======================================
Attribute Description
============== =======================================
nxt Next Header
offset offset, in 8-octet units, relative to
the start of the fragmentable part of
the original packet.
@ -354,8 +342,8 @@ class fragment(header):
_PACK_STR = '!BxHI'
_MIN_LEN = struct.calcsize(_PACK_STR)
def __init__(self, offset, more, id_):
super(fragment, self).__init__()
def __init__(self, nxt, offset, more, id_):
super(fragment, self).__init__(nxt)
self.offset = offset
self.more = more
self.id_ = id_
@ -365,9 +353,7 @@ class fragment(header):
(nxt, off_m, id_) = struct.unpack_from(cls._PACK_STR, buf)
offset = off_m >> 3
more = off_m & 0x1
ret = cls(offset, more, id_)
ret.set_nxt(nxt)
return ret
return cls(nxt, offset, more, id_)
def serialize(self):
off_m = (self.offset << 3 | self.more)
@ -393,6 +379,7 @@ class auth(header):
============== =======================================
Attribute Description
============== =======================================
nxt Next Header
size the length of the Authentication Header
in 64-bit words, subtracting 1.
spi security parameters index.
@ -405,8 +392,8 @@ class auth(header):
_PACK_STR = '!BB2xII'
_MIN_LEN = struct.calcsize(_PACK_STR)
def __init__(self, size, spi, seq, data):
super(auth, self).__init__()
def __init__(self, nxt, size, spi, seq, data):
super(auth, self).__init__(nxt)
self.size = size
self.spi = spi
self.seq = seq
@ -421,9 +408,7 @@ class auth(header):
(nxt, size, spi, seq) = struct.unpack_from(cls._PACK_STR, buf)
form = "%ds" % (cls._get_size(size) - cls._MIN_LEN)
(data, ) = struct.unpack_from(form, buf, cls._MIN_LEN)
ret = cls(size, spi, seq, data)
ret.set_nxt(nxt)
return ret
return cls(nxt, size, spi, seq, data)
def serialize(self):
buf = struct.pack(self._PACK_STR, self.nxt, self.size, self.spi,

View File

@ -66,16 +66,17 @@ class Test_ipv6(unittest.TestCase):
ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data),
ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data),
]
self.hop_opts_nxt = 6
self.hop_opts_size = 0
self.hop_opts = ipv6.hop_opts(self.hop_opts_size, self.options)
self.hop_opts = ipv6.hop_opts(
self.hop_opts_nxt, self.hop_opts_size, self.options)
self.ext_hdrs = [self.hop_opts]
self.payload_length += len(self.hop_opts)
self.nxt = ipv6.hop_opts.TYPE
self.ip = ipv6.ipv6(
self.version, self.traffic_class, self.flow_label,
self.payload_length, self.nxt, self.hop_limit, self.src,
self.dst, self.ext_hdrs)
self.hop_opts.nxt = self.nxt
self.nxt = self.hop_opts.TYPE
self.buf = struct.pack(
ipv6.ipv6._PACK_STR, self.v_tc_flow,
self.payload_length, self.nxt, self.hop_limit,
@ -94,16 +95,17 @@ class Test_ipv6(unittest.TestCase):
ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data),
ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data),
]
self.dst_opts_nxt = 6
self.dst_opts_size = 0
self.dst_opts = ipv6.dst_opts(self.dst_opts_size, self.options)
self.dst_opts = ipv6.dst_opts(
self.dst_opts_nxt, self.dst_opts_size, self.options)
self.ext_hdrs = [self.dst_opts]
self.payload_length += len(self.dst_opts)
self.nxt = ipv6.dst_opts.TYPE
self.ip = ipv6.ipv6(
self.version, self.traffic_class, self.flow_label,
self.payload_length, self.nxt, self.hop_limit, self.src,
self.dst, self.ext_hdrs)
self.dst_opts.nxt = self.nxt
self.nxt = self.dst_opts.TYPE
self.buf = struct.pack(
ipv6.ipv6._PACK_STR, self.v_tc_flow,
self.payload_length, self.nxt, self.hop_limit,
@ -112,19 +114,20 @@ class Test_ipv6(unittest.TestCase):
self.buf += self.dst_opts.serialize()
def setUp_with_fragment(self):
self.fragment_nxt = 6
self.fragment_offset = 50
self.fragment_more = 1
self.fragment_id = 123
self.fragment = ipv6.fragment(
self.fragment_offset, self.fragment_more, self.fragment_id)
self.fragment_nxt, self.fragment_offset, self.fragment_more,
self.fragment_id)
self.ext_hdrs = [self.fragment]
self.payload_length += len(self.fragment)
self.nxt = ipv6.fragment.TYPE
self.ip = ipv6.ipv6(
self.version, self.traffic_class, self.flow_label,
self.payload_length, self.nxt, self.hop_limit, self.src,
self.dst, self.ext_hdrs)
self.fragment.nxt = self.nxt
self.nxt = self.fragment.TYPE
self.buf = struct.pack(
ipv6.ipv6._PACK_STR, self.v_tc_flow,
self.payload_length, self.nxt, self.hop_limit,
@ -133,20 +136,21 @@ class Test_ipv6(unittest.TestCase):
self.buf += self.fragment.serialize()
def setUp_with_auth(self):
self.auth_nxt = 6
self.auth_size = 4
self.auth_spi = 256
self.auth_seq = 1
self.auth_data = '\xa0\xe7\xf8\xab\xf9\x69\x1a\x8b\xf3\x9f\x7c\xae'
self.auth = ipv6.auth(
self.auth_size, self.auth_spi, self.auth_seq, self.auth_data)
self.auth_nxt, self.auth_size, self.auth_spi, self.auth_seq,
self.auth_data)
self.ext_hdrs = [self.auth]
self.payload_length += len(self.auth)
self.nxt = ipv6.auth.TYPE
self.ip = ipv6.ipv6(
self.version, self.traffic_class, self.flow_label,
self.payload_length, self.nxt, self.hop_limit, self.src,
self.dst, self.ext_hdrs)
self.auth.nxt = self.nxt
self.nxt = self.auth.TYPE
self.buf = struct.pack(
ipv6.ipv6._PACK_STR, self.v_tc_flow,
self.payload_length, self.nxt, self.hop_limit,
@ -165,24 +169,25 @@ class Test_ipv6(unittest.TestCase):
ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data),
ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data),
]
self.hop_opts_nxt = ipv6.auth.TYPE
self.hop_opts_size = 0
self.hop_opts = ipv6.hop_opts(self.hop_opts_size, self.options)
self.hop_opts = ipv6.hop_opts(
self.hop_opts_nxt, self.hop_opts_size, self.options)
self.auth_nxt = 6
self.auth_size = 4
self.auth_spi = 256
self.auth_seq = 1
self.auth_data = '\xa0\xe7\xf8\xab\xf9\x69\x1a\x8b\xf3\x9f\x7c\xae'
self.auth = ipv6.auth(
self.auth_size, self.auth_spi, self.auth_seq, self.auth_data)
self.auth_nxt, self.auth_size, self.auth_spi, self.auth_seq,
self.auth_data)
self.ext_hdrs = [self.hop_opts, self.auth]
self.payload_length += len(self.hop_opts) + len(self.auth)
self.nxt = ipv6.hop_opts.TYPE
self.ip = ipv6.ipv6(
self.version, self.traffic_class, self.flow_label,
self.payload_length, self.nxt, self.hop_limit, self.src,
self.dst, self.ext_hdrs)
self.hop_opts.nxt = self.nxt
self.nxt = self.hop_opts.TYPE
self.auth.nxt = self.hop_opts.nxt
self.hop_opts.nxt = self.auth.TYPE
self.buf = struct.pack(
ipv6.ipv6._PACK_STR, self.v_tc_flow,
self.payload_length, self.nxt, self.hop_limit,
@ -403,8 +408,7 @@ class Test_hop_opts(unittest.TestCase):
ipv6.option(0xc2, 4, '\x00\x01\x00\x00'),
ipv6.option(1, 0, None),
]
self.hop = ipv6.hop_opts(self.size, self.data)
self.hop.set_nxt(self.nxt)
self.hop = ipv6.hop_opts(self.nxt, self.size, self.data)
self.form = '!BB'
self.buf = struct.pack(self.form, self.nxt, self.size) \
+ self.data[0].serialize() \
@ -475,8 +479,7 @@ class Test_dst_opts(unittest.TestCase):
ipv6.option(0xc2, 4, '\x00\x01\x00\x00'),
ipv6.option(1, 0, None),
]
self.dst = ipv6.dst_opts(self.size, self.data)
self.dst.set_nxt(self.nxt)
self.dst = ipv6.dst_opts(self.nxt, self.size, self.data)
self.form = '!BB'
self.buf = struct.pack(self.form, self.nxt, self.size) \
+ self.data[0].serialize() \
@ -615,8 +618,8 @@ class Test_fragment(unittest.TestCase):
self.offset = 50
self.more = 1
self.id_ = 123
self.fragment = ipv6.fragment(self.offset, self.more, self.id_)
self.fragment.set_nxt(self.nxt)
self.fragment = ipv6.fragment(
self.nxt, self.offset, self.more, self.id_)
self.off_m = (self.offset << 3 | self.more)
self.form = '!BxHI'
@ -658,8 +661,8 @@ class Test_auth(unittest.TestCase):
self.spi = 256
self.seq = 1
self.data = '\x21\xd3\xa9\x5c\x5f\xfd\x4d\x18\x46\x22\xb9\xf8'
self.auth = ipv6.auth(self.size, self.spi, self.seq, self.data)
self.auth.set_nxt(self.nxt)
self.auth = ipv6.auth(
self.nxt, self.size, self.spi, self.seq, self.data)
self.form = '!BB2xII12s'
self.buf = struct.pack(self.form, self.nxt, self.size, self.spi,
self.seq, self.data)