File: rip.py

package info (click to toggle)
python-dpkt 1.9.8-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,104 kB
  • sloc: python: 14,911; makefile: 23
file content (122 lines) | stat: -rw-r--r-- 2,760 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# $Id: rip.py 23 2006-11-08 15:45:33Z dugsong $
# -*- coding: utf-8 -*-
"""Routing Information Protocol."""
from __future__ import print_function
from __future__ import absolute_import

from . import dpkt

# RIP v2 - RFC 2453
# http://tools.ietf.org/html/rfc2453

REQUEST = 1
RESPONSE = 2


class RIP(dpkt.Packet):
    """Routing Information Protocol.

    TODO: Longer class information....

    Attributes:
        __hdr__: Header fields of RIP.
        TODO.
    """

    __hdr__ = (
        ('cmd', 'B', REQUEST),
        ('v', 'B', 2),
        ('rsvd', 'H', 0)
    )

    def unpack(self, buf):
        dpkt.Packet.unpack(self, buf)
        l_ = []
        self.auth = None
        while self.data:
            rte = RTE(self.data[:20])
            if rte.family == 0xFFFF:
                self.auth = Auth(self.data[:20])
            else:
                l_.append(rte)
            self.data = self.data[20:]
        self.data = self.rtes = l_

    def __len__(self):
        n = self.__hdr_len__
        if self.auth:
            n += len(self.auth)
        n += sum(map(len, self.rtes))
        return n

    def __bytes__(self):
        auth = b''
        if self.auth:
            auth = bytes(self.auth)
        return self.pack_hdr() + auth + b''.join(map(bytes, self.rtes))


class RTE(dpkt.Packet):
    __hdr__ = (
        ('family', 'H', 2),
        ('route_tag', 'H', 0),
        ('addr', 'I', 0),
        ('subnet', 'I', 0),
        ('next_hop', 'I', 0),
        ('metric', 'I', 1)
    )


class Auth(dpkt.Packet):
    __hdr__ = (
        ('rsvd', 'H', 0xFFFF),
        ('type', 'H', 2),
        ('auth', '16s', 0)
    )


def test_creation_with_auth():
    from binascii import unhexlify

    buf_auth = unhexlify(
        'ffff'              # rsvd
        '0002'              # type
        '0123456789abcdef'  # auth
        '0123456789abcdef'  # auth
    )
    auth_direct = Auth(buf_auth)
    assert bytes(auth_direct) == buf_auth

    buf_rte = unhexlify(
        '0002'      # family
        '0000'      # route_tag
        '01020300'  # addr
        'ffffff00'  # subnet
        '00000000'  # next_hop
        '00000001'  # metric
    )

    rte = RTE(buf_rte)
    assert bytes(rte) == buf_rte

    buf_rip = unhexlify(
        '02'    # cmd
        '02'    # v
        '0000'  # rsvd
    )
    rip = RIP(buf_rip + buf_auth + buf_rte)

    assert rip.auth
    assert rip.auth.rsvd == 0xffff
    assert rip.auth.type == 2
    assert rip.auth.auth == unhexlify('0123456789abcdef') * 2

    assert len(rip.rtes) == 1

    rte = rip.rtes[0]
    assert rte.family == 2
    assert rte.route_tag == 0
    assert rte.metric == 1

    assert bytes(rip) == buf_rip + buf_auth + buf_rte
    assert len(rip) == len(buf_rip + buf_auth + buf_rte)