huangcm
2024-12-18 9d29be7f7249789d6ffd0440067187a9f040c2cd
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
## This file is part of Scapy
## See http://www.secdev.org/projects/scapy for more informations
## Copyright (C) Philippe Biondi <phil@secdev.org>
## This program is published under a GPLv2 license
 
"""
L2TP (Layer 2 Tunneling Protocol) for VPNs.
 
[RFC 2661]
"""
 
import struct
 
from scapy.packet import *
from scapy.fields import *
from scapy.layers.inet import UDP
from scapy.layers.ppp import PPP
 
 
class L2TP(Packet):
    name = "L2TP"
    fields_desc = [ 
                    FlagsField("hdr", 0, 12, ['res00', 'res01', 'res02', 'res03', 'priority', 'offset',
                                              'res06', 'sequence', 'res08', 'res09', 'length', 'control']),
                    BitEnumField("version", 2, 4, {2: 'L2TPv2'}),
 
                    ConditionalField(ShortField("len", 0),
                        lambda pkt: pkt.hdr & 'control+length'),
                    ShortField("tunnel_id", 0),
                    ShortField("session_id", 0),
                    ConditionalField(ShortField("ns", 0),
                        lambda pkt: pkt.hdr & 'sequence+control'),
                    ConditionalField(ShortField("nr", 0),
                        lambda pkt: pkt.hdr & 'sequence+control'),
                    ConditionalField(
                        PadField(ShortField("offset", 0), 4, b"\x00"),
                        lambda pkt: not (pkt.hdr & 'control') and pkt.hdr & 'offset'
                        )
                    ]
 
    def post_build(self, pkt, pay):
        if self.len is None:
            l = len(pkt)+len(pay)
            pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:]
        return pkt+pay
 
 
bind_layers( UDP,           L2TP,          sport=1701, dport=1701)
bind_layers( L2TP,          PPP,           )