def main(): parser = argparse.ArgumentParser() parser.add_argument("infile", nargs='?', help="the pcap file to parse") parser.add_argument("-i", "--ip", help="only parse packages with specified source OR dest ip") parser.add_argument("-p", "--port", type=int, help="only parse packages with specified source OR dest port") parser.add_argument("-v", "--verbosity", help="increase output verbosity(-vv is recommended)", action="count") parser.add_argument("-g", "--group", help="group http request/response by connection", action="store_true") parser.add_argument("-o", "--output", help="output to file instead of stdout") parser.add_argument("-e", "--encoding", help="decode the data use specified encodings.") parser.add_argument("-b", "--beauty", help="output json in a pretty way.", action="store_true") parser.add_argument("-d", "--domain", help="filter http data by request domain") parser.add_argument("-u", "--uri", help="filter http data by request uri pattern") args = parser.parse_args() file_path = "-" if args.infile is None else args.infile _filter = config.get_filter() _filter.ip = args.ip _filter.port = args.port _filter.domain = args.domain _filter.uri_pattern = args.uri # deal with configs parse_config = config.get_config() if args.verbosity: parse_config.level = args.verbosity if args.encoding: parse_config.encoding = args.encoding if args.beauty: parse_config.pretty = args.beauty parse_config.group = args.group if args.output: output_file = open(args.output, "w+") else: output_file = sys.stdout config.out = output_file try: if file_path != '-': infile = io.open(file_path, "rb") else: infile = sys.stdin try: parse_pcap_file(infile) finally: infile.close() finally: if args.output: output_file.close()
def parse_pcap_file(infile): """ :type infile:file """ conn_dict = OrderedDict() file_format, head = get_file_format(infile) if file_format == FileFormat.PCAP: pcap_file = pcap.PcapFile(infile, head).read_packet elif file_format == FileFormat.PCAP_NG: pcap_file = pcapng.PcapngFile(infile, head).read_packet else: print("unknown file format.", file=sys.stderr) sys.exit(1) _filter = config.get_filter() for tcp_pac in packet_parser.read_tcp_packet(pcap_file): # filter if not (_filter.by_ip(tcp_pac.source) or _filter.by_ip(tcp_pac.dest)): continue if not (_filter.by_port(tcp_pac.source_port) or _filter.by_port(tcp_pac.dest_port)): continue key = tcp_pac.gen_key() # we already have this conn if key in conn_dict: conn_dict[key].on_packet(tcp_pac) # conn closed. # TODO: The connection should be closed after an expired time if conn_dict[key].closed(): conn_dict[key].finish() del conn_dict[key] # begin tcp connection. elif tcp_pac.syn and not tcp_pac.ack: conn_dict[key] = TcpConnection(tcp_pac) elif utils.is_request(tcp_pac.body): # tcp init before capture, we start from a possible http request header. # TODO: The packet maybe a http response header conn_dict[key] = TcpConnection(tcp_pac) # finish connection which not close yet for conn in conn_dict.values(): conn.finish()