00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 import pcapy
00018 from impacket.ImpactDecoder import EthDecoder, IPDecoder
00019 from impacket.ImpactPacket import ImpactPacketException, IP, TCP, UDP, ICMP, IGMP
00020 from objects.logic.common.logger import logger
00021 from objects.logic.common.exception import exception
00022
00023
00024
00025
00026
00027 class packetDecoder():
00028 def __init__(self):
00029 self.readerObject = None
00030 self.datalink = None
00031 self.EthDecoder = None
00032 self.IPDecoder = None
00033
00034
00035
00036 self.PROTOCOL_IP = 2048
00037 self.PROTOCOL_ARP = 2054
00038
00039
00040 self.PROTOCOL_ICMP = 1
00041 self.PROTOCOL_IGMP = 2
00042
00043 self.PROTOCOL_TCP = 6
00044 self.PROTOCOL_UDP = 17
00045
00046
00047
00048
00049
00050
00051 def getNetProtocolString(self, protNum):
00052 if protNum == self.PROTOCOL_IP:
00053 return "IP"
00054 if protNum == self.PROTOCOL_ARP:
00055 return "ARP"
00056
00057 return "UNK"
00058
00059
00060
00061
00062
00063 def getXportProtocolString(self, protNum):
00064 if protNum == self.PROTOCOL_ICMP:
00065 return "ICMP"
00066 if protNum == self.PROTOCOL_IGMP:
00067 return "IGMP"
00068 if protNum == self.PROTOCOL_TCP:
00069 return "TCP"
00070 if protNum == self.PROTOCOL_UDP:
00071 return "UDP"
00072
00073 return "UNK"
00074
00075
00076
00077
00078
00079
00080
00081 def setReader(self, readerObj):
00082 if readerObj == None:
00083 logger.log(__name__ + ": Could not set reader object. Object is null")
00084 raise exception("There was an error configuring the network device. This device cannot be used", True)
00085
00086 logger.log(__name__ + ":initializing reader object")
00087 self.readerObject = readerObj
00088 self.datalink = self.readerObject.datalink()
00089
00090
00091
00092 if self.datalink == pcapy.DLT_EN10MB:
00093 self.EthDecoder = EthDecoder()
00094 self.IPDecoder = IPDecoder()
00095 else:
00096 logger.log(__name__ + "Data link is not supported. Only Ethernet is currently supported")
00097 raise exception("Data link is not supported. Only Ethernet is currently supported", 1)
00098
00099
00100
00101
00102
00103
00104 def setDefaultReader(self):
00105 self.EthDecoder = EthDecoder()
00106 self.IPDecoder = IPDecoder()
00107
00108
00109
00110
00111
00112
00113
00114 def decodePacket(self, header, data):
00115
00116 dict = None
00117 try:
00118 ethernetPacket = self.EthDecoder.decode(data)
00119 except Exception, e:
00120 logger.log(__name__ + "There was an error decoding raw packet")
00121 logger.log(str(e))
00122 return
00123
00124 except ImpactPacketException, ime:
00125 logger.log(__name__ + "There was an error decoding raw packet")
00126 logger.log(str(ime))
00127 return
00128
00129
00130 ether_protocol_typ = ethernetPacket.get_ether_type()
00131
00132 if (ether_protocol_typ == self.PROTOCOL_IP):
00133 dict = self.handle_ethernet_IPPacket(ethernetPacket)
00134 elif (ether_protocol_typ == self.PROTOCOL_ARP):
00135 dict = self.handle_ethernet_ARPPacket(ethernetPacket)
00136 else:
00137 logger.log(__name__ + ": Received an unsupported Ehternet protocol type -- ")
00138
00139
00140 return dict
00141
00142
00143
00144
00145
00146 def handle_ethernet_IPPacket(self, ethernetFrame):
00147
00148 try:
00149 decodedPacket = None
00150 ipPacket = ethernetFrame.child()
00151
00152
00153 ipHeader = ipPacket.get_bytes()[0:ipPacket.get_header_size()]
00154 ipPacketProtocol = ipPacket.get_ip_p()
00155 except Exception, ex:
00156 logger.log(__name__ + ": Could not process IP packet")
00157 logger.log(ex)
00158
00159
00160 if (ipPacketProtocol == self.PROTOCOL_TCP):
00161 try:
00162
00163 tcpPacket = ipPacket.child()
00164
00165 tcpHeader = tcpPacket.get_bytes() + tcpPacket.get_padded_options()
00166
00167
00168
00169 payload = tcpPacket.get_packet()
00170 payload = payload[tcpPacket.get_header_size():]
00171
00172
00173 payloadLen = ipPacket.get_ip_len() - (ipPacket.get_ip_hl() * 4) - (tcpPacket.get_th_off() * 4)
00174
00175 except Exception, ex:
00176 logger.log(__name__ + ": Could not process TCP packet")
00177 logger.log(ex)
00178
00179 raise ex
00180 else:
00181
00182 decodedPacket = self.createPacketDic('ETHERNET', self.PROTOCOL_IP, self.PROTOCOL_TCP, payloadLen,
00183 ipPacket.get_ip_src(), tcpPacket.get_th_sport(), ipPacket.get_ip_dst(), tcpPacket.get_th_dport(),
00184 ipHeader, tcpHeader, payload)
00185
00186 if (ipPacketProtocol == self.PROTOCOL_UDP):
00187
00188 try:
00189 udpPacket = ipPacket.child()
00190
00191 udpHeader = udpPacket.get_bytes()[0:udpPacket.get_header_size()]
00192
00193 payload = udpPacket.get_packet()
00194 payload = payload[udpPacket.get_header_size():]
00195
00196
00197
00198
00199
00200 payloadLen = udpPacket.get_uh_ulen() - 8
00201
00202 except Exception, ex:
00203 logger.log(__name__ + ": Could not process UDP packet")
00204 logger.log(ex)
00205
00206 raise ex
00207 else:
00208 decodedPacket = self.createPacketDic('ETHERNET', self.PROTOCOL_IP, self.PROTOCOL_UDP, payloadLen,
00209 ipPacket.get_ip_src(), udpPacket.get_uh_sport(), ipPacket.get_ip_dst(), udpPacket.get_uh_dport(),
00210 ipHeader, udpHeader, payload)
00211
00212 if (ipPacketProtocol == self.PROTOCOL_ICMP):
00213 message = "%s: Got an ICMP packet -- %s -> %s" % (__name__, ipPacket.get_ip_src(), ipPacket.get_ip_dst())
00214
00215
00216 try:
00217 icmpPacket = ipPacket.child()
00218
00219 icmpHeader = icmpPacket.get_bytes()[0:icmpPacket.get_header_size()]
00220 except Exception, ex:
00221 logger.log(__name__ + ": Could not process ICMP packet")
00222 logger.log(ex)
00223
00224 raise ex
00225 else:
00226 decodedPacket = self.createPacketDic('ETHERNET', self.PROTOCOL_IP, self.PROTOCOL_ICMP, 0,
00227 ipPacket.get_ip_src(), 0, ipPacket.get_ip_dst(), 0,
00228 ipHeader, icmpHeader, None)
00229
00230 if (ipPacketProtocol == self.PROTOCOL_IGMP):
00231
00232 try:
00233 igmpPacket = ipPacket.child()
00234
00235 igmpHeader = igmpPacket.get_bytes()
00236 except Exception, ex:
00237 logger.log(__name__ + ": Could not process IGMP packet")
00238 logger.log(ex)
00239
00240 raise ex
00241 else:
00242 decodedPacket = self.createPacketDic('ETHERNET', self.PROTOCOL_IP, self.PROTOCOL_IGMP, 0,
00243 ipPacket.get_ip_src(), 0, ipPacket.get_ip_dst(), 0,
00244 ipHeader, igmpHeader, None)
00245
00246 return decodedPacket
00247
00248
00249
00250
00251 def handle_ethernet_ARPPacket(self, ARPPacket):
00252 logger.log(__name__ + ":Received ARP packet. No handler for that yet")
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 def createPacketDic(self,
00270 lanProtocol,
00271 netProtocol,
00272 transportProtocol,
00273 payloadSize,
00274 sourceIP,
00275 sourcePort,
00276 destIP,
00277 destPort,
00278 netHeader,
00279 xportHeader,
00280 payload):
00281
00282 decodedPacket = dict()
00283
00284 decodedPacket['lanProtocol'] = lanProtocol
00285 decodedPacket['netProtocol'] = netProtocol
00286 decodedPacket['transportProtocol'] = transportProtocol
00287 decodedPacket['sourceIP'] = sourceIP
00288 decodedPacket['sourcePort'] = sourcePort
00289 decodedPacket['destIP'] = destIP
00290 decodedPacket['destPort'] = destPort
00291 decodedPacket['payloadSize'] = payloadSize
00292
00293 decodedPacket['networkHeader'] = netHeader
00294 decodedPacket['transportHeader'] = xportHeader
00295 decodedPacket['payload'] = payload
00296
00297
00298 return decodedPacket
00299
00300
00301
00302
00303
00304
00305
00306 def isPing(self, netHeader, xportHeader):
00307 try:
00308 ipHdr = IP(netHeader)
00309 except ImpactPacketException, ex:
00310
00311 logger.log(__name__ + "Error parsing IP header when trying to determine if content is PING:" + str(ex))
00312 return False
00313
00314 ipPacketProtocol = ipHdr.get_ip_p()
00315
00316
00317 if ipPacketProtocol != self.PROTOCOL_ICMP:
00318 return False
00319
00320 try:
00321 icmpHdr = ICMP(xportHeader)
00322 icmpType = icmpHdr.get_icmp_type()
00323
00324 if icmpType == 0 or icmpType == 8:
00325 return True
00326 except ImpactPacketException, ex:
00327
00328 logger.log(__name__ + "Error parsing ICMP header when trying to determine if content is PING: " + str(ex))
00329 return False
00330
00331
00332