IP fragment reassembly Store the first seen packet, collect data from followup packets, then glue it all together and update that first packet with new data
(self, packet: 'Packet')
| 259 | raise e |
| 260 | |
| 261 | def ipdefrag(self, packet: 'Packet') -> 'Packet': |
| 262 | """ |
| 263 | IP fragment reassembly |
| 264 | |
| 265 | Store the first seen packet, collect data from followup packets, then |
| 266 | glue it all together and update that first packet with new data |
| 267 | """ |
| 268 | pkt = packet.pkt |
| 269 | ipp = pkt.upper_layer |
| 270 | if isinstance(ipp, ip.IP): # IPv4 |
| 271 | f = self._packet_fragments[(ipp.src, ipp.dst, ipp.id)] |
| 272 | f[ipp.offset] = packet |
| 273 | |
| 274 | if not ipp.flags & 0x1: # If no more fragments (MF) |
| 275 | if len(f) <= 1 and 0 in f: |
| 276 | # If only one unfragmented packet, return that packet |
| 277 | del self._packet_fragments[(ipp.src, ipp.dst, ipp.id)] |
| 278 | return f[0] |
| 279 | elif 0 not in f: |
| 280 | logger.debug(f"Missing first fragment of fragmented packet. Dropping ({packet.sip} -> {packet.dip}: {ipp.id}:{ipp.flags}:{ipp.offset})") |
| 281 | del self._packet_fragments[(ipp.src, ipp.dst, ipp.id)] |
| 282 | return None |
| 283 | fkeys = sorted(f.keys()) |
| 284 | data = b'' |
| 285 | firstpacket = f[fkeys[0]] |
| 286 | for key in fkeys: |
| 287 | data += f[key].pkt.upper_layer.body_bytes |
| 288 | newip = ip.IP(firstpacket.pkt.upper_layer.header_bytes + data) |
| 289 | newip.bin(update_auto_fields=True) # refresh checksum |
| 290 | firstpacket.pkt.upper_layer = newip |
| 291 | del self._packet_fragments[(ipp.src, ipp.dst, ipp.id)] |
| 292 | return Packet( |
| 293 | firstpacket.pkt.__len__, |
| 294 | firstpacket.pkt, |
| 295 | firstpacket.ts, |
| 296 | firstpacket.frame |
| 297 | ) |
| 298 | |
| 299 | elif isinstance(pkt, ip6.IP6): # IPv6 |
| 300 | # TODO handle IPv6 offsets https://en.wikipedia.org/wiki/IPv6_packet#Fragment |
| 301 | return pkt |
| 302 | |
| 303 | def handle_plugin_options(self): |
| 304 | """ |
no test coverage detected