{"id":19065524,"url":"https://github.com/menci/magpie","last_synced_at":"2025-08-02T12:06:29.971Z","repository":{"id":85769965,"uuid":"502291909","full_name":"Menci/magpie","owner":"Menci","description":"Bidirectional NDP proxy and route maintainer to relay an IPv6 SLAAC network.","archived":false,"fork":false,"pushed_at":"2022-06-14T21:16:45.000Z","size":35,"stargazers_count":26,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-11T00:01:55.049Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","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/Menci.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":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-11T08:24:44.000Z","updated_at":"2025-03-22T08:49:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"dd8f1703-9ef9-4dee-b904-226d4101e2ee","html_url":"https://github.com/Menci/magpie","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/Menci/magpie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fmagpie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fmagpie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fmagpie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fmagpie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Menci","download_url":"https://codeload.github.com/Menci/magpie/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fmagpie/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268385727,"owners_count":24242101,"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","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-11-09T00:50:35.409Z","updated_at":"2025-08-02T12:06:29.947Z","avatar_url":"https://github.com/Menci.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Magpie\n\nBidirectional NDP proxy and route maintainer to relay an IPv6 SLAAC network.\n\n\u003e The name \"magpie\" is from the Chinese folk tale *[The Cowherd and the Weaver Girl](https://en.wikipedia.org/wiki/The_Cowherd_and_the_Weaver_Girl)*: once a year on the 7-th day of the 7-th lunar month, all the magpies flys to the Milky Way and form a ***bridge*** to let couple, the Cowherd and the Weaver Girl, to meet.\n\n## Introduction\n\nIn an IPv6 network, the **downstream router** (your homelab LAN gateway) usually got a /64 routed prefix with DHCPv6's PD (prefix delegation) from **upstream network** (ISP). Then your downstream router could broadcast RA with the delegated prefix so that all hosts in your main LAN could get IPv6 addresses with SLAAC.\n\n```plain\n        Upstream         \u003c---\u003e       Downstream Router        \u003c---\u003e            Hosts in main LAN\n(DHCPv6 server with PD)         (Got /64 PD from upstream)              (Got IPv6 addresses with SLAAC)\n                                     (Broadcasting RA)\n```\n\nBut what if you connect a **secondary router** to the **downstream router**'s main LAN? Your secondary router gets a globally routable IPv6 address with that prefix, but not your secondary LAN's terminal devices because no one is broadcasting RA. You can pretend to be owning that PD, re-broadcasting the **downstream router**'s RA to the secondary LAN (with [radvd](https://radvd.litech.org/)). But even if your terminal devices could get \"real\" IPv6 address, it's not globally routable.\n\n```plain\n     Downstream Router        \u003c---\u003e             Secondary Router             \u003c---\u003e        Terminal devices in secondary LAN\n(Got /64 PD from upstream)              (Got IPv6 addresses with SLAAC)                    (Got IPv6 addresses with SLAAC)\n     (Broadcasting RA)                        (Re-broadcasting RA)                               (But not working?)\n```\n\nWhy? Because that /64 prefix doesn't belong to your **secondary router**, an output packet could reach the Internet but no input packet goes to your terminal devices through your **secondary router**. To go deeper, the **upstream router**, who owns the PD in real, doesn't know where to send the packet.\n\nSo why it can without the **secondary router**? Just like IPv4's ARP, in IPv6, a host resolves an IP address in the same broadcast domain to MAC address with [NDP](https://en.wikipedia.org/wiki/Neighbor_Discovery_Protocol). But your **secondary router** divides the hosts in a /64 network, which are in theory belong to one broadcast domain, to two -- the main LAN and secondary LAN. Then there are two problems involved:\n\n1. For an IPv6 address used by your secondary LAN's terminal device, the **downstream router**, who need to do the first-time routing for each packet to your network, couldn't find it with NDP.\n2. For an IPv6 address in the /64 prefix of all your hosts, your **secondary router** don't know whether it's in main LAN or secondary LAN -- since the two interfaces are in the same broadcast domain in theory.\n\nFor the 1st problem, we can proxy the NDP messages on your **secondary router**. When receiving a NDP query (NS) from one network, send a NDP query to the other network from itself, when receving a NDP response (NA) from one network, respond to the the other network to announce the IP is on itself. Then hosts in two networks are thinking they're in the same broadcast domain, but in real they communicate with your **secondary router** as the gateway.\n\nFor the 2st problem, we can learn routes from the NDP responses (NA). Once receving a NA from one network, add a rule to route the target IP to that network in the system routing table. We have a timeout and reprobe mechanism to delete expired (disconnected) hosts. In addition, we can capture the output ICMPv6 \"destination unreachable\" messages and try to probe them and fix the routes.\n\n## Building\n\nInstall dependencies:\n\n```bash\napt install -y libpcap-dev # Ubuntu or Debian\npacman -Sy libpcap         # Archlinux\n```\n\nClone this repo with `--recursive`:\n\n```bash\ngit clone https://github.com/Menci/magpie --recursive\ncd magpie\n```\n\nBuild with CMake:\n\n```bash\nmkdir build \u0026\u0026 cd build\ncmake .. -DCMAKE_BUILD_TYPE=Release\nmake -j\n# Result binary: ./src/magpie\n```\n\n## Usage\n\nMagpie listens on multiple (two normally but more are possible) interfaces, specified by `-i`, and do NDP proxying and routes probing/learning. Usually it's the only argument needed. But for debugging purpose you could also specify the log level with `-l`.\n\n```bash\nmagpie -i wan,br-lan # Relaying IPv6 on interface \"wan\" and \"br-lan\"\nmagpie -i wan,br-lan -l verbose # Increase the log level for \n```\n\nIt sets alarm and check for the timeout of routes in each `--alarm-interval, -a` seconds, any route lasted `--probe-interval, -p` seconds will be reprobed. There will be `--probe-retries, -r` reprobe retries before a route being deleted as expired. For example, the default:\n\n```bash\n# A route will be reprobed 5 times before deleted as expired, in an interval of 60s for each reprobe\nmagpie -i wan,br-lan -a 10 -p 60 -r 5\n```\n\nIt's better to provide a `--routes-save-file` to save the routes to file on exit and load (reprobe) them on start. This helps reduce the IPv6 network down time between your restarts of the daemon.\n\n```bash\nmagpie -i wan,br-lan -f /var/lib/magpie/saved-routes.json\n```\n\n## Security Notice\n\nThis project aims on using in homelab / school network in which the hosts are trusted. **Don't use it in a public / untrusted network** since it maintains routing states without any security measure. Attacks like NDP hijacking and routing table DDoS could be done easily.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmenci%2Fmagpie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmenci%2Fmagpie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmenci%2Fmagpie/lists"}