5
from optparse import OptionParser
21
def getNdisTypesInfo():
24
global NET_BUFFER_LIST
29
NET_BUFFER_LIST = ndis.type("_NET_BUFFER_LIST")
30
MDL = ndis.type("_MDL")
31
NET_BUFFER = ndis.type("_NET_BUFFER")
32
except SymbolException:
33
NET_BUFFER_LIST =typeInfo("_NET_BUFFER_LIST")
34
MDL = typeInfo("_MDL")
35
NET_BUFFER = typeInfo("_NET_BUFFER")
38
def getHostWord( dataPos ):
39
return ( dataPos.next() << 8 ) + dataPos.next()
42
def getNetWord( dataPos ):
43
return dataPos.next() + ( dataPos.next() << 8 )
46
def getHostDWord( dataPos ):
47
return ( dataPos.next() << 24 ) + ( dataPos.next() << 16 ) + ( dataPos.next() << 8 ) + dataPos.next()
50
def getNetDWord( dataPos ):
51
return dataPos.next() + ( dataPos.next() << 8 ) + ( dataPos.next() << 16 ) + ( dataPos.next() << 24 )
55
def __init__( self, dataPos ):
60
self.sourcePort = getHostWord( dataPos )
61
self.destPort = getHostWord( dataPos )
62
self.length = getHostWord( dataPos )
63
self.checksum = getHostWord( dataPos )
73
s += "\tSrc port: %d\n" % self.sourcePort
74
s += "\tDest port: %d\n" % self.destPort
75
s += "\tLength: %d\n" % self.length
76
s += "\tChecksum: %#x\n" % self.checksum
86
def __init__( self, dataPos ):
92
self.sourcePort = getHostWord( dataPos )
93
self.destPort = getHostWord( dataPos )
94
self.SeqNumber = getHostDWord( dataPos )
95
self.AckNumber = getHostDWord( dataPos )
96
self.dataOffset = ( dataPos.next() >> 4 )
97
self.flags = dataPos.next() & 0x3F
98
self.window = getHostWord( dataPos )
99
self.checksum = getHostWord( dataPos )
100
self.urgentPointer = getHostWord( dataPos )
103
except StopIteration:
109
fl = [ "FIN", "SYN","RST", "PSH", "ACK", "URG" ]
113
s += "\tSrc port: %d\n" % self.sourcePort
114
s += "\tDest port: %d\n" % self.destPort
115
s += "\tSEQ: %x\n" % self.SeqNumber
116
s += "\tACK: %x\n" % self.AckNumber
117
s += "\tFlags: %x ( %s )\n" % ( self.flags, " ".join( [ fl[i] for i in xrange( len(fl) ) if ( self.flags & ( 1 << i ) ) != 0 ] ) )
118
s += "\tWindows: %x\n" % self.window
119
s += "\tChecksum: %x\n" % self.checksum
129
def __init__( self, dataPos ):
138
def __init__( self, dataPos ):
140
self.addr = [ dataPos.next() for i in xrange(4) ]
144
return "%d.%d.%d.%d" % tuple( self.addr[0:4] )
149
def __init__( self, dataPos ):
150
self.addr = [ getHostWord( dataPos ) for i in xrange(8) ]
153
return "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" % tuple( self.addr )
158
def __init__( self, dataPos ):
159
self.typeVal = dataPos.next()
162
return self.typeVal==ICMP_PROTO
165
return self.typeVal==UDP_PROTO
168
return self.typeVal==TCP_PROTO
171
return { ICMP_PROTO: "ICMP", UDP_PROTO: "UDP", TCP_PROTO: "TCP" }.get( self.typeVal, hex(self.typeVal) )
174
def getNextLayerPacket( self, dataPos ):
176
ICMP_PROTO : lambda x : "",
177
UDP_PROTO : lambda x : UdpPacket(x),
178
TCP_PROTO : lambda x : TcpPacket(x)
179
}.get( self.typeVal, lambda x : "Unknown protocol" )(dataPos)
184
def __init__( self, dataPos ):
190
version = dataPos.next()
191
self.ihl = version & 0xF
192
self.version = version >> 4
193
self.tos = dataPos.next()
194
self.TotalLength = getHostWord( dataPos )
195
self.ident = getHostWord( dataPos )
196
frag = getHostWord( dataPos )
197
self.offset = frag & 0x1FFF
198
self.flags = frag >> 13
199
self.ttl = dataPos.next()
200
self.protocol = IpProtocol( dataPos )
201
self.checlsum = getNetWord( dataPos )
202
self.srcAddr = IpAddress( dataPos )
203
self.destAddr = IpAddress( dataPos )
206
self.nextLayerPckt = self.protocol.getNextLayerPacket( dataPos )
208
self.nextLayerPckt = ""
212
except StopIteration:
223
s += "\tversion: %x\n" % self.version
224
s += "\theader length: %d bytes\n" % ( self.ihl * 4 )
225
s += "\ttotal length: %d bytes\n" % self.TotalLength
226
s += "\tID: %x\n" % self.ident
227
s += "\tflags: %x\n" % self.flags
228
s += "\toffset: %x" % ( self.offset * 8)
229
if ( self.offset == 0 ) and ( self.flags & 0x4 == 0 ):
230
s += " (not fragmented)\n"
231
elif self.offset == 0 :
232
s += " (first fragment)\n"
233
elif not ( self.flags & 0x4 == 0 ):
234
s += " (fragmented)\n"
236
s += " (last fragment)\n"
237
s += "\tprotocol: " + str( self.protocol ) + "\n"
238
s += "\tTTL: %d\n" % self.ttl
239
s += "\tSrc addr: " + str(self.srcAddr) + "\n"
240
s += "\tDest addr: " + str(self.destAddr) + "\n"
241
s += str( self.nextLayerPckt )
251
def __init__( self, dataPos ):
257
t = getHostDWord( dataPos )
258
self.version = ( t >> 28 ) & 0xF
259
self.trafficClass = ( t >> 20 ) & 0xFF
260
self.flowLabel = t & 0xFFF
261
self.payloadLength = getNetWord( dataPos )
262
self.nextHeader = IpProtocol( dataPos )
263
self.hopLimit = dataPos.next()
264
self.srcAddr = Ip6Address( dataPos )
265
self.destAddr = Ip6Address( dataPos )
267
self.nextLayerPckt = self.nextHeader.getNextLayerPacket( dataPos )
271
except StopIteration:
280
s += "\tversion: %x\n" % self.version
281
s += "\ttraffic class %x\n" % self.trafficClass
282
s += "\tflowLabel: %x\n" % self.flowLabel
283
s += "\tpayloadLength: %x\n" % self.payloadLength
284
s += "\tnextHeader: " + str( self.nextHeader ) + "\n"
285
s += "\thopLimit: %d\n" % self.hopLimit
286
s += "\tsrcAddr: " + str(self.srcAddr) + "\n"
287
s += "\tdestAddr: " + str(self.destAddr) + "\n"
288
s += str( self.nextLayerPckt )
297
def __init__( self, dataPos ):
303
self.HWType = getNetWord( dataPos )
304
self.PType = getNetWord( dataPos )
305
self.HLen = dataPos.next()
306
self.PLen = dataPos.next()
307
self.oper = getNetWord( dataPos )
308
self.senderHWAddr = EthernetAddress( dataPos )
309
self.senderPAddr = IpAddress( dataPos )
310
self.targetHWAddr = EthernetAddress( dataPos )
311
self.targetPAddr = IpAddress( dataPos )
315
except StopIteration:
323
s += { 0x100: "REQUEST", 0x200: "REPLAY" }.get(self.oper, hex(self.oper) ) + "\n"
324
s += "HTYPE: " + { 0x100: "Ethernet", }.get( self.HWType, hex( self.HWType) ) + " "
325
s += "PTYPE: " + { IPv4: "IPv4", }.get( self.PType, hex( self.PType) ) + " "
326
s += "HLEN: %x " % self.HLen
327
s += "PLEN: %x " % self.PLen
328
s += "\nSender: " + str(self.senderHWAddr) + " " + str( self.senderPAddr )
329
s += "\nTarget: " + str(self.targetHWAddr) + " " + str( self.targetPAddr ) + "\n"
339
def __init__( self, dataPos ):
340
self.typeVal = getNetWord( dataPos )
343
return self.typeVal == IPv4
346
return self.typeVal == ARP
349
return self.typeVal == IPv6
352
return { IPv4 : "IPv4", ARP : "ARP", IPv6 : "IPv6" }.get( self.typeVal, str(self.typeVal) )
354
def getNextLayerPacket( self, dataPos ):
356
IPv4 : lambda x : IpPacket(x),
357
ARP : lambda x : ARPPacket(x),
358
IPv6 : lambda x : Ip6Packet(x),
359
}.get( self.typeVal, lambda x : "" )( dataPos )
362
class EthernetAddress:
364
def __init__( self, dataPos ):
365
self.addr = [ dataPos.next() for i in range(0,6) ]
368
return "%02x-%02x-%02x-%02x-%02x-%02x" % tuple( self.addr[0:6] )
374
def __init__( self, dataPos ):
380
self.destAddress = EthernetAddress( dataPos)
381
self.srcAddress = EthernetAddress( dataPos)
382
self.frametype = EthernetType( dataPos )
383
self.nextLayerPckt = self.frametype.getNextLayerPacket( dataPos )
386
except StopIteration:
392
s = "Ethernet header: "
397
s += "\tDest MAC: " + str(self.destAddress) + "\n"
398
s += "\tSrc MAC: " + str(self.srcAddress) + "\n"
399
s += "\tType: " + str( self.frametype) + "\n"
400
s += str( self.nextLayerPckt )
410
def __init__( self, rawData, startProtocol="eth", beginOffset=0 ):
411
self.rawData = rawData
412
dataPos = iter( self.rawData[ beginOffset : ] )
415
"eth" : lambda : EthernetPacket( dataPos ),
416
"ip4" : lambda : IpPacket( dataPos ),
417
"ip6" : lambda : Ip6Packet( dataPos ),
418
"tcp" : lambda : TcpPacket( dataPos ),
419
"udp" : lambda : UdpPacket( dataPos )
423
s = "Length: %d bytes\n" % len(self.rawData)
424
s += str( self.mediaParsed )
428
def getPacketFromNb( nb ):
432
mdl = typedVar( MDL, nb.CurrentMdl )
433
dataLength = nb.DataLength
434
dataOffset = nb.CurrentMdlOffset
436
while dataLength > 0:
438
copyData = mdl.ByteCount - dataOffset
439
if copyData > dataLength: copyData = dataLength
441
pcktBytes.extend( loadBytes( mdl.MappedSystemVa + dataOffset, copyData ) )
443
dataLength -= copyData
445
mdl = typedVar( MDL, mdl.Next )
451
def getPacketsFromNbl( nblAddr ):
459
nbl = typedVar( NET_BUFFER_LIST, nblAddr )
463
nb = typedVar( NET_BUFFER, nbl.FirstNetBuffer )
467
pcktList.append( getPacketFromNb( nb ) )
472
nb = typedVar( NET_BUFFER, nb.Next )
477
nbl = typedVar( NET_BUFFER_LIST, nbl.Next )
481
except TypeException:
483
dprintln( "the symbols are wrong" )
485
def printNblStruct( nblAddr, showNdisStruct = False, beginProtocol="eth", beginOffset=0 ):
494
dprintln( "NET_BUFFER_LIST %#x" % nblAddr )
496
nbl = typedVar( NET_BUFFER_LIST, nblAddr )
498
nbAddr = nbl.FirstNetBuffer
502
nb = typedVar( NET_BUFFER, nbAddr )
505
dprint( "\tNET_BUFFER %#x" % nbAddr )
506
dprintln( " data length = %d, data offset = %#x " % ( nb.DataLength, nb.DataOffset ) )
508
mdlAddr = nb.CurrentMdl
512
mdl = typedVar( MDL, mdlAddr )
515
dprint( "\t\tMDL %#x" % mdlAddr )
516
dprintln( " byte count = %d, byte offset = %#x, mapped addr = %#x" % ( mdl.ByteCount, mdl.ByteOffset, mdl.MappedSystemVa ) )
520
dprintln( str( NetPacket( getPacketFromNb( nb ), beginProtocol, beginOffset ) ) )
526
except TypeException:
528
dprintln( "the symbols are wrong" )
532
if not isKernelDebugging():
533
dprintln( "This script is for kernel debugging only" )
536
parser = OptionParser(usage="usage: !py nbl [options] address")
537
parser.add_option("-s", "--struct", action="store_true", dest="showNdisStruct", default=False, help="Show NDIS structures" )
538
parser.add_option("-p", "--proto", action="store", type="string", dest="startProtocol", default="eth", help="Packet protocol. Can be eth, ip4, ip6, tcp, udp. By default - eth." )
539
parser.add_option("-o", "--offset", action="store", type="long", dest="beginOffset", default=0, help="Bytes offset from packet beginning" )
540
parser.add_option("-r", "--raw", action="store_true", dest="rawBuffer", default=False, help="Show raw buffer")
542
(options, args) = parser.parse_args()
545
parser.error("you should note address of network packet")
547
if options.rawBuffer:
550
parser.error("you should note buffer length")
553
dprintln( str( NetPacket( rawData = loadBytes(expr(args[0]),expr(args[1])), startProtocol=options.startProtocol, beginOffset=options.beginOffset ) ) )
556
printNblStruct( expr(args[0]), showNdisStruct = options.showNdisStruct, beginProtocol=options.startProtocol, beginOffset=options.beginOffset )
559
if __name__ == "__main__":