{"id":18151269,"url":"https://github.com/msantos/pkt","last_synced_at":"2025-04-05T02:08:06.874Z","repository":{"id":1258876,"uuid":"1197695","full_name":"msantos/pkt","owner":"msantos","description":"Erlang network protocol library","archived":false,"fork":false,"pushed_at":"2022-06-18T12:21:39.000Z","size":223,"stargazers_count":148,"open_issues_count":6,"forks_count":44,"subscribers_count":24,"default_branch":"master","last_synced_at":"2024-03-15T09:08:01.310Z","etag":null,"topics":["arp","dlt","ethernet","gre","icmp","icmpv6","igmp","ipsec","ipv4","ipv6","mpls","sctp","tcp","udp","vrrp"],"latest_commit_sha":null,"homepage":"http://blog.listincomprehension.com/search/label/epcap","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msantos.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}},"created_at":"2010-12-25T21:24:24.000Z","updated_at":"2024-01-30T20:50:26.000Z","dependencies_parsed_at":"2022-08-16T12:45:32.757Z","dependency_job_id":null,"html_url":"https://github.com/msantos/pkt","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msantos%2Fpkt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msantos%2Fpkt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msantos%2Fpkt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msantos%2Fpkt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msantos","download_url":"https://codeload.github.com/msantos/pkt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247276164,"owners_count":20912288,"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","dlt","ethernet","gre","icmp","icmpv6","igmp","ipsec","ipv4","ipv6","mpls","sctp","tcp","udp","vrrp"],"created_at":"2024-11-02T01:07:09.440Z","updated_at":"2025-04-05T02:08:06.848Z","avatar_url":"https://github.com/msantos.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nAn Erlang network protocol library.\n\nOriginally part of epcap:\n\u003chttp://github.com/msantos/epcap\u003e\n\n\n## EXPORTS\n\n    pkt:decapsulate(Data) -\u003e Packet\n    pkt:decapsulate(Proto, Data) -\u003e Packet\n\n        Types   Data = binary()\n                Proto = atom() | integer()\n                Packet = [ Header | Payload ]\n                Header = #ether{} | #arp{} | #null{} | #linux_cooked{} |\n                    #ipv4{} | #ipv6{} | #tcp{} | #udp{} | #sctp{} | #icmp{} |\n                    #icmp6{} | #igmp{} | #gre{} | #llc{} | #vrrp{} | #'802.1q'{} |\n                    #lldp{} | #mpls{} | #rarp{} | #'802.1x'{}\n                Payload = binary()\n\n        Convert network protocols from binary data to a list of Erlang\n        records followed by the payload.\n\n        decapsulate/1,2 works on valid packets. If the packet is malformed\n        or unsupported, decapsulate/1 will crash.\n\n        decapsulate/1 parses the data as an ethernet frame.\n\n        decapsulate/2 allows specifying the protocol for decoding the\n        packet. If the protocol is specified as an integer, the integer\n        is treated as a datalink type.\n\n    pkt:decode(Data) -\u003e {ok, Packet} | {error, SoFar, {FailedProto, binary()}}\n    pkt:decode(Proto, Data) -\u003e {ok, Packet} | {error, SoFar, {FailedProto, binary()}}\n\n        Types   Data = binary()\n                Proto = FailedProto = atom()\n                Packet = {Headers, Payload}\n                Headers = [Header]\n                Header = #ether{} | #arp{} | #null{} | #linux_cooked{} |\n                    #ipv4{} | #ipv6{} | #tcp{} | #udp{} | #sctp{} | #icmp{} |\n                    #icmp6{} | #igmp{} | #gre{} | #llc{} | #vrrp{} | #'802.1q'{} |\n                    #lldp{} | #mpls{} | #rarp{} | #'802.1x'{}\n                SoFar = Headers | []\n                Payload = binary()\n\n        Similar to decapsulate/1 but, on error, returns any part of the\n        packet that has been successfully converted to Erlang term format.\n\nThe following functions create the protocol headers, converting between\nrecords and binaries. See include/pkt.hrl for definition of the record\ntypes.\n\n    ether(Packet) -\u003e {#ether{}, Payload} | binary()\n    llc(Packet) -\u003e {#llc{}, Payload} | binary()\n    vrrp(Packet) -\u003e {#vrrp{}, Payload} | binary()\n    '802.1q'(Packet) -\u003e {#'802.1q'{}, Payload} | binary()\n    null(Packet) -\u003e {#null{}, Payload} | binary()\n    linux_cooked(Packet) -\u003e {#linux_cooked{}, Payload} | binary()\n    gre(Packet) -\u003e {#gre{}, Payload} | binary()\n    arp(Packet) -\u003e {#arp{}, Payload} | binary()\n    ipv4(Packet) -\u003e {#ipv4{}, Payload} | binary()\n    ipv6(Packet) -\u003e {#ipv6{}, Payload} | binary()\n    tcp(Packet) -\u003e {#tcp{}, Payload} | binary()\n    sctp(Packet) -\u003e {#sctp{}, Payload} | binary()\n    udp(Packet) -\u003e {#udp{}, Payload} | binary()\n    icmp(Packet) -\u003e {#icmp{}, Payload} | binary()\n    icmp6(Packet) -\u003e {#icmp6{}, Payload} | binary()\n    igmp(Packet) -\u003e {#igmp{}, Payload} | binary()\n    mpls(Packet) -\u003e {#mpls{}, Next, Payload}\n    lldp(Packet) -\u003e {#lldp{}, Payload}\n    rarp(Packet) -\u003e {#rarp{}, Payload}\n    '802.1x'(Packet) -\u003e {#'802.1x'{}, Payload}\n\n        Types   Packet = Header | binary()\n                Header = #ether{} | #null{} | #linux_cooked{} | #arp{} |\n                    #ipv4{} | #ipv6{} | #tcp{} | #sctp{} | #udp{} |\n                    #icmp{} | #icmp6{} | #igmp{} | #gre{} | #llc{} |\n                    #vrrp{} | #'802.1q'{} | #lldp{} | #mpls{} | #rarp{} | #'802.1x'{}\n                Next = ipv4 | ipv6\n\n\n    makesum(Packet) -\u003e integer()\n\n        Types   Packet = IPv4_header | [IPv4_header, Header, Payload]\n                IPv4_header = #ipv4{}\n                Header = #tcp{} | #udp{}\n                Payload = binary()\n\n        Calculate the one's complement checksum of the packet.\n\n        When computing the checksum, the header sum field must be set\n        to 0:\n\n            Sum = pkt:makesum([IPv4, TCP#tcp{sum = 0}, Payload]).\n\n        For verifcation, the checksum can be compared to the value in\n        the header or:\n\n            0 = pkt:makesum([IPv4, TCP, Payload]).\n\n## EXAMPLES\n\n* decode an ethernet frame, displaying the source and destination of\n  valid packets\n\n```erlang\nFrame = \u003c\u003c224,105,149,59,163,24,0,22,182,181,62,198,8,0,69,0,0,54,2,108,64,\n          0,53,6,172,243,173,192,82,195,192,168,213,54,0,80,143,166,75,154,\n          212,181,116,33,53,92,128,24,0,126,60,199,0,0,1,1,8,10,92,104,96,\n          16,22,69,237,136,137,0\u003e\u003e,\n\ntry pkt:decapsulate(Frame) of\n    [#ether{}, #ipv4{saddr = Saddr, daddr = Daddr},\n        #tcp{sport = Sport, dport = Dport}, _Payload] -\u003e\n        {{Saddr, Sport}, {Daddr, Dport}}\ncatch\n    error:_ -\u003e\n        ok % ignore invalid packets\nend\n```\n\n* verify the TCP checksum of an ethernet frame\n\n```erlang\n{ok, [#ether{}, IPv4, #tcp{sum = Sum} = TCP, Payload]} = pkt:decode(ether, Frame),\n\n% Re-calculate the checksum and match against the checksum in the header\nSum = pkt:makesum([IPv4, TCP#tcp{sum = 0}, Payload]),\n\n% Or just verify the checksum\n0 = pkt:makesum([IPv4, TCP, Payload]).\n```\n\n## PADDING OF ETHERNET FRAMES\n\nThe minimum size of an ethernet payload is 46 bytes. An ethernet frame\ncontaining a TCP/IP packet composed of a 20 byte IPv4 header and 20 byte\nTCP header and payload will be padded by 6 bytes. To calculate the actual\nlength of the packet, use the length and header length values in the IPv4\nheader and the offset value in the TCP header:\n\n```erlang\n[#ether{}, #ipv4{len = Len, hl = HL}, #tcp{off = Off}, Payload] = pkt:decapsulate(Frame),\n    Size = Len - (HL * 4) - (Off * 4),\n    \u003c\u003cPayload:Size/bytes\u003e\u003e.\n```\n\n## TODO\n\n* support RFC 2675 (IPv6 Jumbograms)\n\n* IPv6 AH and ESP\n    * handle alignment differences between IPv4 and IPv6 (IPv4 uses 32\n      bits, IPv6 uses 64 bits)\n\n* ICMPv6\n    * fix handling of neighbour discovery\n    * simplify ICMPv6 header record and add a record for ICMPv6 type or\n      add functions for ICMPv6 variable length payloads\n\n* IGMP\n    * support IGMPv3 variable payloads\n\n* merge in DLT\\_IEEE802\\_11 support from wierl\n\n* merge in ICMPv6 code from gen_icmp\n\n* DLTs\n    * DLT_SLIP\n    * DLT_PPP\n    * DLT_RAW\n    * DLT\\_PPP\\_SERIAL\n    * DLT\\_PPP\\_ETHER\n    * DLT_LOOP\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsantos%2Fpkt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsantos%2Fpkt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsantos%2Fpkt/lists"}