summaryrefslogtreecommitdiffstats
path: root/scripts/external_libs/dpkt-1.8.6/dpkt/ppp.py
blob: f4898b955be6ac39cd6969d607fb70d7a9ff0146 (plain)
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
# $Id: ppp.py 65 2010-03-26 02:53:51Z dugsong $

"""Point-to-Point Protocol."""

import struct
import dpkt

# XXX - finish later

# http://www.iana.org/assignments/ppp-numbers
PPP_IP	= 0x21		# Internet Protocol
PPP_IP6 = 0x57		# Internet Protocol v6

# Protocol field compression
PFC_BIT	= 0x01

class PPP(dpkt.Packet):
    __hdr__ = (
        ('p', 'B', PPP_IP),
        )
    _protosw = {}
    
    def set_p(cls, p, pktclass):
        cls._protosw[p] = pktclass
    set_p = classmethod(set_p)

    def get_p(cls, p):
        return cls._protosw[p]
    get_p = classmethod(get_p)
    
    def unpack(self, buf):
        dpkt.Packet.unpack(self, buf)
        if self.p & PFC_BIT == 0:
            self.p = struct.unpack('>H', buf[:2])[0]
            self.data = self.data[1:]
        try:
            self.data = self._protosw[self.p](self.data)
            setattr(self, self.data.__class__.__name__.lower(), self.data)
        except (KeyError, struct.error, dpkt.UnpackError):
            pass

    def pack_hdr(self):
        try:
            if self.p > 0xff:
                return struct.pack('>H', self.p)
            return dpkt.Packet.pack_hdr(self)
        except struct.error, e:
            raise dpkt.PackError(str(e))

def __load_protos():
    g = globals()
    for k, v in g.iteritems():
        if k.startswith('PPP_'):
            name = k[4:]
            modname = name.lower()
            try:
                mod = __import__(modname, g)
            except ImportError:
                continue
            PPP.set_p(v, getattr(mod, name))

if not PPP._protosw:
    __load_protos()