{"id":39167278,"url":"https://github.com/irai/packet","last_synced_at":"2026-01-17T22:13:19.504Z","repository":{"id":44927392,"uuid":"338175410","full_name":"irai/packet","owner":"irai","description":"A go package to process ARP, ICMP, DHCP and notify when mac is online or offline.","archived":false,"fork":false,"pushed_at":"2025-02-04T04:32:28.000Z","size":4251,"stargazers_count":26,"open_issues_count":2,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-01T23:17:30.684Z","etag":null,"topics":["arp-spoof","dhcp-spoof","dns","icmp6-spoof","ip","lan","raw","spoofing"],"latest_commit_sha":null,"homepage":"","language":"Go","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/irai.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":"2021-02-11T23:01:56.000Z","updated_at":"2025-02-04T04:32:32.000Z","dependencies_parsed_at":"2022-09-05T15:11:16.471Z","dependency_job_id":null,"html_url":"https://github.com/irai/packet","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/irai/packet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irai%2Fpacket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irai%2Fpacket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irai%2Fpacket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irai%2Fpacket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/irai","download_url":"https://codeload.github.com/irai/packet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irai%2Fpacket/sbom","scorecard":{"id":494175,"data":{"date":"2025-08-11","repo":{"name":"github.com/irai/packet","commit":"75d97ccc5be1c991a5d5a1933eec7f3cf44caa7d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.8,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 2/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 4 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T20:01:03.225Z","repository_id":44927392,"created_at":"2025-08-19T20:01:03.226Z","updated_at":"2025-08-19T20:01:03.226Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28519871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T22:11:28.393Z","status":"ssl_error","status_checked_at":"2026-01-17T22:11:27.841Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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-spoof","dhcp-spoof","dns","icmp6-spoof","ip","lan","raw","spoofing"],"created_at":"2026-01-17T22:13:18.790Z","updated_at":"2026-01-17T22:13:19.498Z","avatar_url":"https://github.com/irai.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# packet\nImplements layer 2, IPv4, IPv6, UDP, TCP and application level packet processing.\n\nThe motivation for this package is to enable fast, memory efficient\nparsing of network packets and tracking of LAN hosts. The package \nautomatically track host IPs on the LAN and notifies when the IP is online offline.\n\n## Features\n\n* session: fast parsing of network packets without allocation\n* session: auto tracking of LAN hosts and host IP changes\n* session: notification of host online and offline\n* naming: host naming via various protocols dhcp, mdns, ssdp, nbns, \n* arp: module to spoof arp mac table\n* dhcp: module to spoof DHCP4 traffic on LAN \n* icmp6: module to spoof Local Link Address via Neigbour Discovery\n* fastlog: a custom log package to log network protocols\n\n## Fast parsing\n\nThe package is designed to operate in low power CPUs (i.e. ARM) and with limited memory. It\nuses memory mapped slices to provide direct access to protocol fields without \ncopying to a new structure. This technique provides fast access to fields with zero allocation and the\ncompiler inlines most protocol field functions to a memory reference.\n\n## Use Session to capture raw network packets\n\nSession provides easy access to read raw packets from the wire. Session automatically places\nthe nic in promiscuous mode so we receive **all** packets hiting the network card including packets sent by us.\n```\n\ts, err := packet.NewSession(\"eth0\")\n\tif err != nil {\n\t\tfmt.Printf(\"conn error: %s\", err)\n\t\treturn\n\t}\n\tdefer s.Close()\n\n\tbuffer := make([]byte, packet.EthMaxSize)\n\tfor {\n\t\tn, _, err := s.ReadFrom(buffer)\n\t\tif err != nil {\n\t\t\tfmt.Println(\"error reading packet\", err)\n\t\t\treturn\n\t\t}\n        // process packet...\n    }\n```\n\n## Use Parse() to map a raw packet into protocol types\n\nParse() provides a memory mapping of protocols to slices without copying or allocation.\nGiven a network packet b that contains a udp frame inside an ip4 and ethernet frame, you can \naccess all protocol fields after calling Parse(). Parse returns a Frame structure with accessor for all \ninteresting bits.\n```\n  n, _, _ := s.ReadFrom(b)          // read network packet\n  frame, err := session.Parse(b[:n]) // fast parse and set references\n  ether := frame.Ether()            // memory mapped slice to access ether fields; return nil if not valid ethernet\n  ip := frame.IP4()                 // memory mapped slice to access ipv4 fields; return nil if it does not contain IP4\n  udp := frame.UDP()                // memory mapped slice to access udp fields; return nil if it does not contain UDP\n  payload := frame.Payload()        // memory mapped slice to access payload\n\n  fmt.Println(\"ether\", ether.Src(), ether.Dst())\n  fmt.Println(\"ip4\", ip.Src(), ip.Dst())\n  fmt.Println(\"udp\", udp.SrcPort(), udp.DstPort())\n  fmt.Printf(\"payloadID=%s payload=[%x]\\n\", frame.PayloadID, payload)\n```\n\n## Payload identification\n\nFrame contains a payload ID that identifies the last payload in the packet. In most cases, this will be the application protocol ID. For example,\nif the packet is a udp DHCP4 packet, PayloadID will return PayloadDHCP4 and Payload() will return a slice to the DHCP4 packet. \n\n```\n    frame, err := s.Parse(b[:n])\n    // if err\n\n    switch frame.PayloadID {\n    case packet.PayloadARP: \n        // Process arp packets\n    case packet.PayloadDHCP4: \n        // Process DHCPv4 packets\n    }\n```\n\n## IPv4 and IPv6 parsing\n\nWorking with IPv4, IPv6, UDP frames is fairly straight forward. For example:\n```\n  frame, err := packet.Parse(b[:n])\n  if err != nil { panic(err)}\n  \n  // if you are only interested in mac and ip (either v4 or v6), \n  // frame.Src() and frame.Dst() are convenient structures to get this data.\n  fmt.Println(\"srcAddr\", frame.Src().MAC, frame.Src().IP) // will print source mac and ip\n  fmt.Println(\"dstAddr\", frame.Dst().MAC, frame.Dst().IP) // will print source mac and ip\n\n  // if you are interested in the IPv4 fields\n  if p := frame.IP4(); p != nil {\n    // access ipv4 fields\n    fmt.Println(\"version\", p.Version(), \"src\", p.Src(), \"dst\", p.Dst(),\"proto\", p.Protocol(), \"ttl\", p.TTL())\n  }\n\n  // if you are intereste in the IPv6 fields\n  if p := frame.IP6(); p != nil {\n    fmt.Println(\"version\", p.Version(), \"src\", p.Src(), \"dst\", p.Dst(),\"nextHeader\", p.NextHeader(), \"hopLimit\", p.HopLimit())\n  }\n\n  // if you are interested in UDP fields\n  if p := frame.UDP(); p != nil {\n    fmt.Println(p)\n  }\n```\n\n## Session provides notifications for Host online and offline\n\nSession tracks when a host changes to online or offline and sends notifications via a go channel.\nThe first time an IP is detected or when an existing host changes IP, Session sends an online notification via the notification channel.\nSimilarly, if an IP is not seen on the network for 5 minutes or more, Session sends an offline  notification via the notification channel.\n\n```\ns, err := packet.NewSession(*nic)\ngo func() {\n    for {\n        notification := \u003c-s.C\n        switch notification.Online {\n        case true:\n            fmt.Printf(\"is online: %s\\n\", notification)\n        default:\n            fmt.Printf(\"is offline: %s\\n\", notification)\n        }\n        s.PrintTable()\n    }\n}()\n\nfor {\n    n, _, err := s.ReadFrom(buffer)\n    if err != nil { panic(err) }\n\n    frame, err := s.Parse(buffer[:n])\n    // work on the packet...\n}\n```\n\n## arp spoofing\n\nThe package contains an arp_spoofer handler that can spoof \nthe arp table on a target host. The handler will send\npoisoned arp packets continously to keep the arp cache pointing to us. See example arp_spoofer application.\n\nIf you like to spoof all hosts on a network, use the notification handler to start and stop the arp hunt for each host. \n```\ns, err := packet.NewSession(*nic)\ndefer s.Close()\narpSpoofer, err = arp.New(s)\ndefer arpSpoofer.Close()\n\ngo func() {\n\t\tfor {\n\t\t\tnotification := \u003c-s.C\n\t\t\tswitch notification.Online {\n\t\t\tcase true:\n\t\t\t\tfmt.Printf(\"is online: %s\\n\", notification)\n\t\t\t\tarpSpoofer.StartHunt(notification.Addr)\n\t\t\tdefault:\n\t\t\t\tfmt.Printf(\"is offline: %s\\n\", notification)\n\t\t\t\tarpSpoofer.StopHunt(notification.Addr)\n\t\t\t}\n\t\t\ts.PrintTable()\n\t\t}\n\t}()\n\t\n// In your main packet processing loop, call the s.Notify() function as the last action in the loop.\n// See example here: https://github.com/irai/packet/tree/main/examples/hosts\n```\n\n## IPv6 icmp spoofing\n\nThe package contains an icmpv6_spoofer handler that can spoof the \nneighgor discovery protocol on a target host making all IPv6 traffic redirect\nto us. The handler will send poisoned icmpv6 packets continously to keep the ndp cache pointing to us.\n\nSee example application below.\n\n\n## DHCP4 server and spoofing\n\nneed notes\nrefer to example dhcp server.\n\n## DNS naming\n\nThe package includes a dns_naming handler that creates a map of names to a mac address\nto simplify host identification.\n\n## Examples\n\n[arp spoofer](/examples/arpspoofer)  \n[dhcpd](/examples/dhcpd)  \n[dnslistener](/examples/dnslistener)  \n[hosts](/examples/hosts)  \n[tcpdump](/examples/tcpdump)  \n\n\n## Credits\n\nThanks to the following individuals for making their outstanding source code available to all to learn and re-use.\n\n* Richard Warburton - The idea of memory mapped slices appeared when inspecting his DHCP4 library (https://github.com/krolaw/dhcp4).\n* Matt Layer - Great low level raw packet processing packages (https://github.com/mdlayher/raw, https://github.com/mdlayher/ethernet)\n* Gopacket Authors - Comprehensive package to process network packets (https://github.com/google/gopacket)\n\nMany other packages contributed ideas or \"code reuse\" and references to these are mentioned in the source code.\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firai%2Fpacket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Firai%2Fpacket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firai%2Fpacket/lists"}