aboutsummaryrefslogtreecommitdiff
path: root/netsec-assignment1-S4498062/exercise3/sniffer.py
blob: 55416a82d6e528d36c8c24fd18075c6b93bf6ab0 (plain) (blame)
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
#!/usr/bin/env python3

import socket
import struct

def parse_udp(packet):
    header_length = 8
    header = packet[:header_length]
    data = packet[header_length:]
    (source_port, dest_port, data_length, checksum) = struct.unpack(
            "!HHHH", header)
    return source_port, dest_port, data_length, data, checksum

def parse_ip(packet):
    header_length_in_bytes = (packet[0] & 0x0f) * 4
    header = packet[:20]
    data = packet[header_length_in_bytes:]
    length, protocol, src, dst = struct.unpack(
            "!xxHxxxxxBxx4s4s", header)
    header = {'length': length,
            'protocol': protocol,
            'source': src,
            'destination': dst}
    return header_length_in_bytes, header, data

def format_ip(addr):
    return '.'.join('%d'%i for i in addr)

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
    while True:
        raw, address = s.recvfrom(2 ** 16 - 1)
        ip_header_len, ip_header, ip_payload = parse_ip(raw)
        src_port, dst_port, udp_len, udp_data, udp_crc = parse_udp(ip_payload)
        print("{}:{} --> {}:{}\nData length: {}\nChecksum: {}\n{}\n".format(
            format_ip(ip_header['source']), src_port,
            format_ip(ip_header['destination']), dst_port,
            udp_len, udp_crc, udp_data))

if __name__ == "__main__":
    main()