{"id":27096840,"url":"https://github.com/gechandesu/netaddr","last_synced_at":"2025-10-13T03:35:44.422Z","repository":{"id":286408378,"uuid":"957109885","full_name":"gechandesu/netaddr","owner":"gechandesu","description":"Network address processing for V","archived":false,"fork":false,"pushed_at":"2025-08-02T23:33:35.000Z","size":50,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-13T03:35:43.613Z","etag":null,"topics":["eui","ip","ip-address","ipv4","ipv6","mac","mac-address","networking","vlang","vlang-module","vlang-package"],"latest_commit_sha":null,"homepage":"https://gechandesu.github.io/netaddr/","language":"V","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gechandesu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","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,"zenodo":null}},"created_at":"2025-03-29T15:25:30.000Z","updated_at":"2025-08-02T23:33:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"d99ca2df-8ff6-44ce-a129-83af7ff45c9d","html_url":"https://github.com/gechandesu/netaddr","commit_stats":null,"previous_names":["gechandesu/netaddr"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/gechandesu/netaddr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fnetaddr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fnetaddr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fnetaddr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fnetaddr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gechandesu","download_url":"https://codeload.github.com/gechandesu/netaddr/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fnetaddr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279013516,"owners_count":26085368,"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-10-13T02:00:06.723Z","response_time":61,"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":["eui","ip","ip-address","ipv4","ipv6","mac","mac-address","networking","vlang","vlang-module","vlang-package"],"created_at":"2025-04-06T10:01:21.765Z","updated_at":"2025-10-13T03:35:44.417Z","avatar_url":"https://github.com/gechandesu.png","language":"V","funding_links":[],"categories":["Libraries"],"sub_categories":["Networking"],"readme":"# Network address processing library for V\n\n`netaddr` supports IP (both IPv4 and IPv6) and EUI (EUI-48, EUI-64) addresses.\n\nFeatures:\n\n- Parsing and validation of EUI, IP addresses and IP network addresses.\n- Converting addresses to/from different formats, e.g. various string representations, byte arrays, integers.\n- IP addresses and networks comparison.\n- IPv4-IPv6 interoperability.\n- IPv6 scopes support.\n- Parsing/creating Teredo (IPv4 over IPv6 tunneling) addresses.\n- Testing addresses and networks i.e. check is network intended for private use or not and many other tests.\n- Generating random EUI-48 (useful for virtual machines, etc).\n- Converting EUI to IPv6.\n- Calculating IP networks (both versions).\n- ...\n\n## Usage\n\n### IP address/network parsing and validation\n\nOnce you got an `Ipv{4,6}Addr` or `Ipv{4,6}Net` instance without errors — that's done,\nvalidation is passed. In the simplest case you can do:\n\n```v okfmt\nif ip := netaddr.IpAddr.from_string('::1') {\n\t// address is valid\n} else {\n\t// address is not valid\n}\n```\n\nMore concrete example that prints the address on success:\n\n```v\nimport netaddr\n\nfn main() {\n\taddr := arguments()[1] or {\n\t\tpanic('no such argument, specify an IP address')\n\t}\n\tip := netaddr.IpAddr.from_string(addr) or {\n\t\tpanic('${addr} is not valid IP address')\n\t}\n\tif ip is netaddr.Ipv4Net || ip is netaddr.Ipv6Net {\n\t\tpanic('${ip} seems to be network, not a single host addresses')\n\t}\n\tprintln(ip)\n}\n```\n\n### Working with IP networks\n\nBasic usage:\n\n```v\nimport netaddr\n\nfn main() {\n\tnetwork4 := netaddr.Ipv4Net.from_string('172.16.16.0/24')!\n\tnetwork6 := netaddr.Ipv6Net.from_string('fe80:aaaa:bbbb:cccc::/64')!\n\tprintln(network4)\n\tprintln(network6)\n}\n```\n\nThe `from_string()` method of the Ipv4Net and Ipv6Net structs supports several different\nformats for network prefixes:\n\n- a single address without a prefix length will be considered as a network with a prefix of 32 or 128 depending on the IP version;\n- an address with an integer non-negative prefix length;\n- an address with a subnet mask;\n- an address with a host mask;\n\n```v okfmt\nnetwork := netaddr.Ipv4Net.from_string('203.0.113.99/0.0.0.255')!\nassert network.network_address.str() == '203.0.113.0'\nassert (network.host_address as netaddr.Ipv4Addr).str() == '203.0.113.99'\n```\n\nIf host bits is set in the network address the optional `host_address` field will be filled with\nthis host address. The `network_address` field always will contain the real network address.\nThe `host_address` will equal `none` for single address \"networks\" such as `127.0.0.1/32`, etc.\n\n#### Iterating over network hosts\n\n`Ipv4Net` and `Ipv6Net` has `next()` method that implements the V iterator mechanism\nwhich allow you use object in `for` loop in following maner:\n\n```v okfmt\nnetwork := netaddr.Ipv4Net.from_string('172.16.16.0/26')!\nfor host in network {\n\t// `host` is an Ipv4Addr instance\n\tif host == network.network_address || host == network.broadcast_address {\n\t\tcontinue\n\t}\n\tprintln(host)\n}\n```\n\nNote that the iterator will iterate over all addresses in the network, including those that\ncannot be used as a host address: the network address and broadcast address. Exceptions are\nthe networks with small prefixes: 31 (point-to-point) and 32 (single address) for IPv4, and\n127 and 128 for IPv6 respectively.\n\nIf you just want to check is network contain some address use `contains()` method:\n\n```v okfmt\nnetwork := netaddr.Ipv4Net.from_string('172.16.0.0/26')!\naddr := netaddr.Ipv4Addr.from_string('172.16.16.68')!\nassert !network.contains(addr)\n```\n\n#### Networks intersection tests and subnetting\n\nTo choose the right prefix when planning a network, it is important to avoid overlapping\nnetwork address spaces.\n\nCheck partial overlapping:\n\n```v okfmt\nnet_a := netaddr.Ipv4Net.from_string('100.64.0.0/22')!\nnet_b := netaddr.Ipv4Net.from_string('100.64.4.0/22')!\nassert !net_a.overlaps(net_b)\n```\n\nAlso you can check is the network a subnet or supernet of another one:\n\n```v okfmt\nassert !net_a.is_subnet_of(net_b)\nassert !net_a.is_supernet_of(net_b)\n```\n\nTo split the network into equal prefixes, you can use the `subnets()` method:\n\n```v okfmt\nnetwork := netaddr.Ipv4Net.from_string('100.64.64.0/20')!\nprintln(network)\nmut subnets := []netaddr.Ipv4Net{}\nfor subnet in network.subnets(22)! {\n\tsubnets \u003c\u003c subnet\n}\nprintln(subnets)\n// [100.64.64.0/22, 100.64.68.0/22, 100.64.72.0/22, 100.64.76.0/22]\n```\n\n### IPv4-IPv6 interoperability\n\n`netaddr` supports IP conversion between 4 and 6 versions in both directions.\n\nThe V REPL session below illustrates this:\n\n```\n\u003e\u003e\u003e import netaddr\n\u003e\u003e\u003e ip4 := netaddr.Ipv4Addr.from_string('203.0.113.99')!\n\u003e\u003e\u003e ip4\n203.0.113.99\n\u003e\u003e\u003e ip6 := ip4.ipv6()\n\u003e\u003e\u003e ip6\n::ffff:203.0.113.99\n\u003e\u003e\u003e ip6.is_ipv4_mapped()\ntrue\n\u003e\u003e\u003e ip6.is_ipv4_compat()\nfalse\n\u003e\u003e\u003e ip6.ipv4()!\n203.0.113.99\n\u003e\u003e\u003e ip4 == ip6.ipv4()!\ntrue\n```\n\nIPv6 address cannot be converted to IPv4 if it is not the IPv4-mapped or IPv4-compatible\nper RFC 4291 Section 2.5.5.\n\nAlso several representation formats are supported:\n\n```\n\u003e\u003e\u003e ip6.format(.dotted | .compact)\n::ffff:203.0.113.99\n\u003e\u003e\u003e ip6.format(.dotted | .verbose)\n0000:0000:0000:0000:0000:ffff:203.0.113.99\n\u003e\u003e\u003e ip6.format(.compact)\n::ffff:cb00:7163\n\u003e\u003e\u003e ip6.format(.verbose)\n0000:0000:0000:0000:0000:ffff:cb00:7163\n```\n\n### Dealing with scoped IPv6 addresses\n\n`Ipv6Addr` struct has optional `zone_id` field that contains the scope zone identifier\nif available. For example (V REPL session):\n\n```\n\u003e\u003e\u003e ip6_scoped := netaddr.Ipv6Addr.from_string('fe80::d08e:6658:38bd:6391%wlan0')!\n\u003e\u003e\u003e ip6_scoped\nfe80::d08e:6658:38bd:6391%wlan0\n\u003e\u003e\u003e ip6_scoped.zone_id\nOption('wlan0')\n\u003e\u003e\u003e zone_id := ip6_scoped.zone_id as string\n\u003e\u003e\u003e zone_id\nwlan0\n```\n\nFor creating scoped address from `big.Integer`, `u8`, `u16`, etc use the optional `zone_id`\nparameter. e.g.:\n\n```v okfmt\n// vfmt off\nnew := netaddr.Ipv6Addr.new(\n\t0xfe80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1234,\n\tzone_id: 'eth0'\n)!\nfrom_u8 := netaddr.Ipv6Addr.from_octets(\n\t[\n\t\tu8(0xfe), 0x80,\n\t\t0x0, 0x0,\n\t\t0x0, 0x0,\n\t\t0x0, 0x0,\n\t\t0x0, 0x0,\n\t\t0x0, 0x0,\n\t\t0x0, 0x0,\n\t\t0x12, 0x34\n\t]!,\n\tzone_id: 'eth0'\n)!\n// vfmt on\nprintln(new) // fe80::1234%eth0\nprintln(from_u8) // fe80::1234%eth0\n```\n\nAlso you can create new IPv6 address with zone_id from existing `Ipv6Addr` instance:\n\n```\n\u003e\u003e\u003e ip6 := netaddr.Ipv6Addr.from_string('fe80::d08e:6658:38bd:6391')!\n\u003e\u003e\u003e new_ip6 := ip6.with_scope('eth1')!\n\u003e\u003e\u003e new_ip6\nfe80::d08e:6658:38bd:6391%eth1\n```\n\nScoped IPv6 networks are supported, but `Ipv6Net` struct does not have own `zone_id`\nfield, refer to it's `network_address` as follows:\n\n```\n\u003e\u003e\u003e ip6net := netaddr.Ipv6Net.from_string('fe80::%eth1/64')!\n\u003e\u003e\u003e ip6net\nfe80::%eth1/64\n\u003e\u003e\u003e ip6net.network_address.zone_id\nOption('eth1')\n```\n\n### Getting global unicast IPv6 from EUI-48\n\nThis is a slightly synthetic example that shows how you can automatically get a global\nunicast IPv6 address for a host given the network prefix.\n\n```v okfmt\n// Known network prefix\nnetwork := netaddr.Ipv6Net.from_string('2001:0db8::/64')!\n// Lets generate random EUI-48\neui := netaddr.Eui48.random()\n// ipv6() method converts EUI-48 to Modified EUI-64 and appends it to prefix per RFC 4291\nip := eui.ipv6(network.network_address)!\nprintln(ip) // 2001:db8::8429:6bff:fedc:ef8b\n```\n\nNote that using EUI in IPv6 address may cause security issues. See\n[RFC 4941](https://datatracker.ietf.org/doc/html/rfc4941) for details.\n\n# License\n\n`netaddr` is released under LGPL 3.0 or later license.\n\nSPDX Lincese ID: `LGPL-3.0-or-later`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgechandesu%2Fnetaddr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgechandesu%2Fnetaddr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgechandesu%2Fnetaddr/lists"}