10ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# This file is part of Scapy 20ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# Scapy is free software: you can redistribute it and/or modify 30ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# it under the terms of the GNU General Public License as published by 40ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# the Free Software Foundation, either version 2 of the License, or 50ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# any later version. 60ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# 70ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# Scapy is distributed in the hope that it will be useful, 80ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# but WITHOUT ANY WARRANTY; without even the implied warranty of 90ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 100ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# GNU General Public License for more details. 110ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# 120ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# You should have received a copy of the GNU General Public License 130ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# along with Scapy. If not, see <http://www.gnu.org/licenses/>. 140ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 150ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# author: <jellch@harris.com> 160ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 170ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# scapy.contrib.description = PPI 180ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# scapy.contrib.status = loads 190ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 200ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 210ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter""" 220ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterPPI (Per-Packet Information). 230ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter""" 24b4d6c78846baf0254ab9a7556ffcfad97280501aPierre LALETimport logging 25b4d6c78846baf0254ab9a7556ffcfad97280501aPierre LALETimport struct 26b4d6c78846baf0254ab9a7556ffcfad97280501aPierre LALET 27b4d6c78846baf0254ab9a7556ffcfad97280501aPierre LALET 280ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterfrom scapy.config import conf 29b4d6c78846baf0254ab9a7556ffcfad97280501aPierre LALETfrom scapy.data import DLT_EN10MB, DLT_IEEE802_11, DLT_PPI 300ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterfrom scapy.packet import * 310ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterfrom scapy.fields import * 320ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterfrom scapy.layers.l2 import Ether 330ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterfrom scapy.layers.dot11 import Dot11 340ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 350ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# Dictionary to map the TLV type to the class name of a sub-packet 360ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter_ppi_types = {} 370ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterdef addPPIType(id, value): 380ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter _ppi_types[id] = value 390ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterdef getPPIType(id, default="default"): 400ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter return _ppi_types.get(id, _ppi_types.get(default, None)) 410ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 420ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 430ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter# Default PPI Field Header 440ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterclass PPIGenericFldHdr(Packet): 450ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter name = "PPI Field Header" 460ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter fields_desc = [ LEShortField('pfh_type', 0), 470ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter FieldLenField('pfh_length', None, length_of="value", fmt='<H', adjust=lambda p,x:x+4), 480ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter StrLenField("value", "", length_from=lambda p:p.pfh_length) ] 490ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 500ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter def extract_padding(self, p): 51aaf1370d4578765810d3789767c32b3d9d025d21gpotter return b"",p 520ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 530ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterdef _PPIGuessPayloadClass(p, **kargs): 540ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter """ This function tells the PacketListField how it should extract the 550ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter TLVs from the payload. We pass cls only the length string 560ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter pfh_len says it needs. If a payload is returned, that means 570ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter part of the sting was unused. This converts to a Raw layer, and 580ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter the remainder of p is added as Raw's payload. If there is no 590ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter payload, the remainder of p is added as out's payload. 600ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter """ 610ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter if len(p) >= 4: 620ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter t,pfh_len = struct.unpack("<HH", p[:4]) 630ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter # Find out if the value t is in the dict _ppi_types. 640ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter # If not, return the default TLV class 650ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter cls = getPPIType(t, "default") 660ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter pfh_len += 4 670ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter out = cls(p[:pfh_len], **kargs) 680ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter if (out.payload): 690ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter out.payload = conf.raw_layer(out.payload.load) 70aaf1370d4578765810d3789767c32b3d9d025d21gpotter out.payload.underlayer = out 710ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter if (len(p) > pfh_len): 720ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter out.payload.payload = conf.padding_layer(p[pfh_len:]) 73aaf1370d4578765810d3789767c32b3d9d025d21gpotter out.payload.payload.underlayer = out.payload 740ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter elif (len(p) > pfh_len): 750ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter out.payload = conf.padding_layer(p[pfh_len:]) 76aaf1370d4578765810d3789767c32b3d9d025d21gpotter out.payload.underlayer = out 770ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter else: 780ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter out = conf.raw_layer(p, **kargs) 790ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter return out 800ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 810ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 820ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 830ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 840ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotterclass PPI(Packet): 850ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter name = "PPI Packet Header" 860ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter fields_desc = [ ByteField('pph_version', 0), 870ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter ByteField('pph_flags', 0), 880ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter FieldLenField('pph_len', None, length_of="PPIFieldHeaders", fmt="<H", adjust=lambda p,x:x+8 ), 890ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter LEIntField('dlt', None), 900ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter PacketListField("PPIFieldHeaders", [], _PPIGuessPayloadClass, length_from=lambda p:p.pph_len-8,) ] 910ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter def guess_payload_class(self,payload): 920ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter return conf.l2types.get(self.dlt, Packet.guess_payload_class(self, payload)) 930ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 940ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter#Register PPI 950ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotteraddPPIType("default", PPIGenericFldHdr) 960ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 97b4d6c78846baf0254ab9a7556ffcfad97280501aPierre LALETconf.l2types.register(DLT_PPI, PPI) 980ef62bfe3120bcc901bbf38c7582d4d3645a733cgpotter 99b4d6c78846baf0254ab9a7556ffcfad97280501aPierre LALETbind_layers(PPI, Dot11, dlt=DLT_IEEE802_11) 100b4d6c78846baf0254ab9a7556ffcfad97280501aPierre LALETbind_layers(PPI, Ether, dlt=DLT_EN10MB) 101