{"id":15572213,"url":"https://github.com/hatamiarash7/packettracer","last_synced_at":"2025-04-24T02:10:53.644Z","repository":{"id":57450189,"uuid":"230677430","full_name":"hatamiarash7/PacketTracer","owner":"hatamiarash7","description":"Network Packet Tracer Library","archived":false,"fork":false,"pushed_at":"2024-04-01T20:54:15.000Z","size":1546,"stargazers_count":12,"open_issues_count":1,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-12T06:17:25.760Z","etag":null,"topics":["arp","cpython","network","packet-analyzer","packet-generator","packet-parsing","packet-processing","packet-sniffer","packet-tracer","packets","parses","pcap","pcap-analyzer","pcap-parser","pypy","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hatamiarash7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-28T22:58:35.000Z","updated_at":"2024-11-12T13:02:07.000Z","dependencies_parsed_at":"2024-10-02T18:01:51.600Z","dependency_job_id":"d46bd71c-78b7-481c-be69-774ba7d955fa","html_url":"https://github.com/hatamiarash7/PacketTracer","commit_stats":{"total_commits":27,"total_committers":2,"mean_commits":13.5,"dds":0.03703703703703709,"last_synced_commit":"a36aea8c5fb52c1950740dd086f44535989a6e40"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatamiarash7%2FPacketTracer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatamiarash7%2FPacketTracer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatamiarash7%2FPacketTracer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatamiarash7%2FPacketTracer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hatamiarash7","download_url":"https://codeload.github.com/hatamiarash7/PacketTracer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250546086,"owners_count":21448260,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arp","cpython","network","packet-analyzer","packet-generator","packet-parsing","packet-processing","packet-sniffer","packet-tracer","packets","parses","pcap","pcap-analyzer","pcap-parser","pypy","python"],"created_at":"2024-10-02T18:01:42.484Z","updated_at":"2025-04-24T02:10:53.612Z","avatar_url":"https://github.com/hatamiarash7.png","language":"Python","funding_links":["https://ko-fi.com/D1D1WGU9"],"categories":[],"sub_categories":[],"readme":"![banner](banner.jpg)\n\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fhatamiarash7%2FPacketTracer.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fhatamiarash7%2FPacketTracer?ref=badge_shield)\n\n# Packet Tracer ( Beta )\n\nThe low-level packet tracer library for Python\n\n## What you can do\nCreate custom packets via keywords or from raw bytes :\n\n```python\nfrom packetracer.layer3.ip import IP\nfrom packetracer.layer3.icmp import ICMP\n\n# Packet via keywords\nip0 = IP(src_s=\"127.0.0.1\", dst_s=\"192.168.0.1\", p=1) +\\\n\tICMP(type=8) +\\\n\tICMP.Echo(id=123, seq=1, body_bytes=b\"foobar\")\n\n# Packet from raw bytes. ip1_bts can also be retrieved via ip0.bin()\nip1_bts = b\"E\\x00\\x00*\\x00\\x00\\x00\\x00@\\x01;)\\x7f\\x00\\x00\\x01\\xc0\\xa8\\x00\\x01\\x08\\x00\\xc0?\\x00{\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00foobar\"\nip1 = IP(ip1_bts) \n# Change source IPv4 address\nip0.src_s = \"1.2.3.4\"\n# Change ICMP payload\nip0[IP,ICMP,ICMP.Echo].body_bytes = b\"foobar2\"\n\n# Output packet (similar result for ip1)\nprint(\"%s\" % ip0)\nlayer3.ip.IP\n        v_hl        : 0x45 = 69 = 0b1000101\n        tos         : 0x0 = 0 = 0b0\n        len         : 0x2B = 43 = 0b101011\n        id          : 0x0 = 0 = 0b0\n        off         : 0x0 = 0 = 0b0\n        ttl         : 0x40 = 64 = 0b1000000\n        p           : 0x1 = 1 = 0b1\n        sum         : 0xB623 = 46627 = 0b1011011000100011\n        src         : b'\\x01\\x02\\x03\\x04' = 1.2.3.4\n        dst         : b'\\xc0\\xa8\\x00\\x01' = 192.168.0.1\n        opts        : []\nlayer3.icmp.ICMP\n        type        : 0x8 = 8 = 0b1000\n        code        : 0x0 = 0 = 0b0\n        sum         : 0x8E3F = 36415 = 0b1000111000111111\nlayer3.icmp.Echo\n        id          : 0x7B = 123 = 0b1111011\n        seq         : 0x1 = 1 = 0b1\n        ts          : 0x0 = 0 = 0b0\n        bodybytes   : b'foobar2'\n```\n\nRead/write packets from/to file ( pcap/tcpdump format ). You can test with [Wireshark](https://www.wireshark.org/):\n\n```python\nfrom packetracer import ppcap\nfrom packetracer.layer12 import ethernet\nfrom packetracer.layer3 import ip\nfrom packetracer.layer4 import tcp\n\npreader = ppcap.Reader(filename=\"packets_ether.pcap\")\npwriter = ppcap.Writer(filename=\"packets_ether_new.pcap\", linktype=ppcap.DLT_EN10MB)\n\nfor ts, buf in preader:\n\teth = ethernet.Ethernet(buf)\n\n\tif eth[ethernet.Ethernet, ip.IP, tcp.TCP] is not None:\n\t\tprint(\"%d: %s:%s -\u003e %s:%s\" % (ts, eth[ip.IP].src_s, eth[tcp.TCP].sport,\n\t\t\teth[ip.IP].dst_s, eth[tcp.TCP].dport))\n\t\tpwriter.write(eth.bin())\n\npwriter.close()\n```\n\nSend/receive layer 2 packets:\n\n```python\nfrom packetracer import psocket\nfrom packetracer.layer12 import ethernet\n\npsock = psocket.SocketHndl(timeout=10)\n\ndef filter_pkt(pkt):\n\treturn pkt.ip.tcp.sport == 80\n\n# Receive raw bytes\nfor raw_bytes in psock:\n\teth = ethernet.Ethernet(raw_bytes)\n\tprint(\"Got packet: %r\" % eth)\n\teth.reverse_address()\n\teth.higher_layer.reverse_address()\n\t# Send bytes\n\tpsock.send(eth.bin())\n\t# Receive raw bytes\n\tbts = psock.recv()\n\t# Send/receive based on source/destination data in packet\n\tpkts = psock.sr(packet_ip)\n\t# Use filter to get specific packets\n\tpkts = psock.recvp(filter_match_recv=filter_pkt)\n\t# stop on first packet\n\tbreak\n\npsock.close()\n```\n\nIntercept (and modificate) Packets eg for MITM:\n\n```python\n# Add iptables rule:\n# iptables -I INPUT 1 -p icmp -j NFQUEUE --queue-balance 0:2\nimport time\n\nfrom packetracer import interceptor\nfrom packetracer.layer3 import ip, icmp\n\n# ICMP Echo request intercepting\ndef verdict_cb(ll_data, ll_proto_id, data, ctx):\n\tip1 = ip.IP(data)\n\ticmp1 = ip1[icmp.ICMP]\n\n\tif icmp1 is None or icmp1.type != icmp.ICMP_TYPE_ECHO_REQ:\n\t\treturn data, interceptor.NF_ACCEPT\n\n\techo1 = icmp1[icmp.ICMP.Echo]\n\n\tif echo1 is None:\n\t\treturn data, interceptor.NF_ACCEPT\n\n\tpp_bts = b\"PACKETRACER\"\n\tprint(\"changing ICMP echo request packet\")\n\techo1.body_bytes = echo1.body_bytes[:-len(pp_bts)] + pp_bts\n\treturn ip1.bin(), interceptor.NF_ACCEPT\n\nictor = interceptor.Interceptor()\nictor.start(verdict_cb, queue_ids=[0, 1, 2])\nprint(\"now sind a ICMP echo request to localhost: ping 127.0.0.1\")\ntime.sleep(999)\nictor.stop()\n```\n\n\n## Prerequisites\n- Python 3.x (CPython, Pypy, Jython or whatever Interpreter)\n- Optional: netifaces \u003e=0.10.6 (for utils)\n- Optional (for interceptor):\n  - CPython\n  - Linux based system with kernel support for NFQUEUE target. The config option is at:\n\t- Networking Options -\u003e Network packet filtering -\u003e Core Netfilter -\u003e NFQUEUE target\n  - iptables (alternatively nftables)\n    - NFQUEUE related rulez can be added eg \"iptables -I INPUT 1 -j NFQUEUE --queue-num 0\"\n  - libnetfilter_queue library (see http://www.netfilter.org/projects/libnetfilter_queue)\n\n## Installation\nThere is two way :\n- Clone newest version\n  - ```git clone https://github.com/hatamiarash7/PacketTracer.git```\n  - ```cd packetracer```\n  - ```python setup.py install```\n- Use pip (synched to master on major version changes)\n  - ```pip install packetracer```\n\n## Usage examples\nSee examples/ and tests/test_packetracer.py.\n\n## Testing\nTests are executed as follows:\n\n1) Add packetracer directory to the PYTHONPATH.\n\n- ```cd packetracer```\n- ```export PYTHONPATH=$(pwd):$PYTHONPATH```\n\n2) execute tests\n\n- ```python tests/test_packetracer.py```\n\n**Performance test results: packetracer**\n```\norC = Intel Core2 Duo CPU @ 1,866 GHz, 2GB RAM, CPython v3.6\norP = Intel Core2 Duo CPU @ 1,866 GHz, 2GB RAM, Pypy 5.10.1\nrounds per test: 10000\n=====================================\n\u003e\u003e\u003e parsing (IP + ICMP)\norC = 86064 p/s\norP = 208346 p/s\n\u003e\u003e\u003e creating/direct assigning (IP only header)\norC = 41623 p/s\norP = 59370 p/s\n\u003e\u003e\u003e bin() without change (IP)\norC = 170356 p/s\norP = 292133 p/s\n\u003e\u003e\u003e output with change/checksum recalculation (IP)\norC = 10104 p/s\norP = 23851 p/s\n\u003e\u003e\u003e basic/first layer parsing (Ethernet + IP + TCP + HTTP)\norC = 62748 p/s\norP = 241047 p/s\n\u003e\u003e\u003e changing Triggerlist element value (Ethernet + IP + TCP + HTTP)\norC = 101552 p/s\norP = 201994 p/s\n\u003e\u003e\u003e changing Triggerlist/text based proto (Ethernet + IP + TCP + HTTP)\norC = 37249 p/s\norP = 272972 p/s\n\u003e\u003e\u003e direct assigning and concatination (Ethernet + IP + TCP + HTTP)\norC = 7428 p/s\norP = 14315 p/s\n\u003e\u003e\u003e full packet parsing (Ethernet + IP + TCP + HTTP)\norC = 6886 p/s\norP = 17040 p/s\n```\n\n**Performance test results: packetracer vs. dpkt vs. scapy**\n```\nComparing packetracer, dpkt and scapy performance (parsing Ethernet + IP + TCP + HTTP)\norC = Intel Core2 Duo CPU @ 1,866 GHz, 2GB RAM, CPython v3.6\norC2 = Intel Core2 Duo CPU @ 1,866 GHz, 2GB RAM, CPython v2.7\nrounds per test: 10000\n=====================================\n\u003e\u003e\u003e testing packetracer parsing speed\norC = 17938 p/s\n\u003e\u003e\u003e testing dpkt parsing speed\norC = 12431 p/s\n\u003e\u003e\u003e testing scapy parsing speed\norC2 = 726 p/s\n```\n\n## Usage hints\n### Performance related\n- For maxmimum performance start accessing attributes at lowest level e.g. for filtering:\n```\n# This will lazy parse only needed layers behind the scenes\nif ether.src == \"...\":\n    ...\nelif ip.src == \"...\":\n    ...\nelif tcp.sport == \"...\":\n    ...\n```\n\n- Avoid to convert packets using the \"%s\" or \"%r\" format as it triggers parsing behind the scene:\n```\npkt = Ethernet() + IP() + TCP()\n# This parses ALL layers\npacket_print = \"%s\" % pkt\n```\n\n- Avoid searching for a layer using single-value index-notation via pkt[L] as it parses all layers until L is found or highest layer is reached:\n```\npacket_found = pkt[Telnet]\n# Alternative: Use multi-value index-notation. This will stop parsing at any non-matching layer:\npacket_found = pkt[Ethernet,IP,TCP,Telnet]\n```\n\n- Use pypy instead of cpython (~3x faster related to full packet parsing)\n\n- For even more performance disable auto fields (affects calling bin(...)):\n```\npkt = ip.IP(src_s=\"1.2.3.4\", dst_s=\"1.2.3.5\") + tcp.TCP()\n# Disable checksum calculation (and any other update) for IP and TCP (only THIS packet instance)\npkt.sum_au_active = False\npkt.tcp.sum_au_active = False\nbts = pkt.bin(update_auto_fields=False)\n```\n\n- Enlarge receive/send buffers to get max performance. This can be done using the following commands\n\t(taken from: http://www.cyberciti.biz/faq/linux-tcp-tuning/):\n```\nsysctl -w net.core.rmem_max=12582912\nsysctl -w net.core.rmem_default=12582912\nsysctl -w net.core.wmem_max=12582912\nsysctl -w net.core.wmem_default=12582912\nsysctl -w net.core.optmem_max=2048000\nsysctl -w net.core.netdev_max_backlog=5000\nsysctl -w net.unix.max_dgram_qlen=1000\nsysctl -w net.ipv4.tcp_rmem=\"10240 87380 12582912\"\nsysctl -w net.ipv4.tcp_wmem=\"10240 87380 12582912\"\nsysctl -w net.ipv4.tcp_mem=\"21228 87380 12582912\"\nsysctl -w net.ipv4.udp_mem=\"21228 87380 12582912\"\nsysctl -w net.ipv4.tcp_window_scaling=1\nsysctl -w net.ipv4.tcp_timestamps=1\nsysctl -w net.ipv4.tcp_sack=1\n```\n\n### Misc related\n- Assemblation of TCP/UDP streams can be done by tshark using pipes\n\twith \"-i -\" and \"-z follow,prot,mode,filter[,range]\"\n\n\n## License\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fhatamiarash7%2FPacketTracer.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fhatamiarash7%2FPacketTracer?ref=badge_large)\n\n---\n\n## Support\n\n[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D1WGU9)\n\n\u003cdiv\u003e\u003ca href=\"https://payping.ir/@hatamiarash7\"\u003e\u003cimg src=\"https://cdn.payping.ir/statics/Payping-logo/Trust/blue.svg\" height=\"128\" width=\"128\"\u003e\u003c/a\u003e\u003c/div\u003e\n\n## Contributing\n\n1. Fork it !\n2. Create your feature branch : `git checkout -b my-new-feature`\n3. Commit your changes : `git commit -am 'Add some feature'`\n4. Push to the branch : `git push origin my-new-feature`\n5. Submit a pull request :D\n\n## Issues\n\nEach project may have many problems. Contributing to the better development of this project by reporting them.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhatamiarash7%2Fpackettracer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhatamiarash7%2Fpackettracer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhatamiarash7%2Fpackettracer/lists"}