{"id":13413639,"url":"https://github.com/songgao/water","last_synced_at":"2025-05-13T17:13:40.878Z","repository":{"id":7653858,"uuid":"9014825","full_name":"songgao/water","owner":"songgao","description":"A simple TUN/TAP library written in native Go.","archived":false,"fork":false,"pushed_at":"2024-07-30T17:38:50.000Z","size":106,"stargazers_count":2023,"open_issues_count":30,"forks_count":300,"subscribers_count":56,"default_branch":"master","last_synced_at":"2025-04-25T15:48:35.186Z","etag":null,"topics":["go","networking","tap","tun"],"latest_commit_sha":null,"homepage":"","language":"Go","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/songgao.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":"2013-03-25T20:06:52.000Z","updated_at":"2025-04-25T06:05:00.000Z","dependencies_parsed_at":"2022-08-05T07:30:16.882Z","dependency_job_id":"60df454f-7d9c-4e2d-8215-a99ebbee00c7","html_url":"https://github.com/songgao/water","commit_stats":{"total_commits":100,"total_committers":17,"mean_commits":5.882352941176471,"dds":0.55,"last_synced_commit":"2b4b6d7c09d80835e5f13f6b040d69f00a158b24"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songgao%2Fwater","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songgao%2Fwater/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songgao%2Fwater/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songgao%2Fwater/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/songgao","download_url":"https://codeload.github.com/songgao/water/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253990498,"owners_count":21995776,"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":["go","networking","tap","tun"],"created_at":"2024-07-30T20:01:45.172Z","updated_at":"2025-05-13T17:13:35.866Z","avatar_url":"https://github.com/songgao.png","language":"Go","funding_links":[],"categories":["HarmonyOS","Go","网络","Networking","\u003cspan id=\"网络-networking\"\u003e网络 Networking\u003c/span\u003e","網絡","网络相关库","Relational Databases"],"sub_categories":["Windows Manager","音译","Transliteration","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","高級控制台界面","Advanced Console UIs","Strings","Uncategorized","暂未分类这些库被放在这里是因为其他类别似乎都不适合。","暂未分类","交流","高级控制台界面"],"readme":"# water\n\n`water` is a native Go library for [TUN/TAP](http://en.wikipedia.org/wiki/TUN/TAP) interfaces.\n\n`water` is designed to be simple and efficient. It\n\n* wraps almost only syscalls and uses only Go standard types;\n* exposes standard interfaces; plays well with standard packages like `io`, `bufio`, etc..\n* does not handle memory management (allocating/destructing slice). It's up to user to decide whether/how to reuse buffers.\n\n~~`water/waterutil` has some useful functions to interpret MAC frame headers and IP packet headers. It also contains some constants such as protocol numbers and ethernet frame types.~~\n\nSee https://github.com/songgao/packets for functions for parsing various packets.\n\n## Supported Platforms\n\n* Linux\n* Windows (experimental; APIs might change)\n* macOS (point-to-point TUN only)\n\n## Installation\n```\ngo get -u github.com/songgao/water\ngo get -u github.com/songgao/water/waterutil\n```\n\n## Documentation\n[http://godoc.org/github.com/songgao/water](http://godoc.org/github.com/songgao/water)\n\n## Example\n\n### TAP on Linux:\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\n\t\"github.com/songgao/packets/ethernet\"\n\t\"github.com/songgao/water\"\n)\n\nfunc main() {\n\tconfig := water.Config{\n\t\tDeviceType: water.TAP,\n\t}\n\tconfig.Name = \"O_O\"\n\n\tifce, err := water.New(config)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tvar frame ethernet.Frame\n\n\tfor {\n\t\tframe.Resize(1500)\n\t\tn, err := ifce.Read([]byte(frame))\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tframe = frame[:n]\n\t\tlog.Printf(\"Dst: %s\\n\", frame.Destination())\n\t\tlog.Printf(\"Src: %s\\n\", frame.Source())\n\t\tlog.Printf(\"Ethertype: % x\\n\", frame.Ethertype())\n\t\tlog.Printf(\"Payload: % x\\n\", frame.Payload())\n\t}\n}\n```\n\nThis piece of code creates a `TAP` interface, and prints some header information for every frame. After pull up the `main.go`, you'll need to bring up the interface and assign an IP address. All of these need root permission.\n\n```bash\nsudo go run main.go\n```\n\nIn a new terminal:\n\n```bash\nsudo ip addr add 10.1.0.10/24 dev O_O\nsudo ip link set dev O_O up\n```\n\nWait until the output `main.go` terminal, try sending some ICMP broadcast message:\n```bash\nping -c1 -b 10.1.0.255\n```\n\nYou'll see output containing the IPv4 ICMP frame:\n```\n2016/10/24 03:18:16 Dst: ff:ff:ff:ff:ff:ff\n2016/10/24 03:18:16 Src: 72:3c:fc:29:1c:6f\n2016/10/24 03:18:16 Ethertype: 08 00\n2016/10/24 03:18:16 Payload: 45 00 00 54 00 00 40 00 40 01 25 9f 0a 01 00 0a 0a 01 00 ff 08 00 01 c1 08 49 00 01 78 7d 0d 58 00 00 00 00 a2 4c 07 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37\n```\n\n### TUN on macOS\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\n\t\"github.com/songgao/water\"\n)\n\nfunc main() {\n\tifce, err := water.New(water.Config{\n\t\tDeviceType: water.TUN,\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tlog.Printf(\"Interface Name: %s\\n\", ifce.Name())\n\n\tpacket := make([]byte, 2000)\n\tfor {\n\t\tn, err := ifce.Read(packet)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tlog.Printf(\"Packet Received: % x\\n\", packet[:n])\n\t}\n}\n```\n\nRun it!\n\n```bash\n$ sudo go run main.go\n```\n\nThis is a point-to-point only interface. Use `ifconfig` to see its attributes. You need to bring it up and assign IP addresses (apparently replace `utun2` if needed):\n\n```bash\n$ sudo ifconfig utun2 10.1.0.10 10.1.0.20 up\n```\n\nNow send some ICMP packets to the interface:\n\n```bash\n$ ping 10.1.0.20\n```\n\nYou'd see the ICMP packets printed out:\n\n```\n2017/03/20 21:17:30 Interface Name: utun2\n2017/03/20 21:17:40 Packet Received: 45 00 00 54 e9 1d 00 00 40 01 7d 6c 0a 01 00 0a 0a 01 00 14 08 00 ee 04 21 15 00 00 58 d0 a9 64 00 08 fb a5 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37\n```\n\n#### Caveats\n\n1. Only Point-to-Point user TUN devices are supported. TAP devices are *not* supported natively by macOS.\n2. Custom interface names are not supported by macOS. Interface names are automatically generated serially, using the `utun\u003c#\u003e` naming convention.\n\n### TAP on Windows:\n\nTo use it with windows, you will need to install a [tap driver](https://github.com/OpenVPN/tap-windows6), or [OpenVPN client](https://github.com/OpenVPN/openvpn) for windows.\n\nIt's compatible with the Linux code.\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\n\t\"github.com/songgao/packets/ethernet\"\n\t\"github.com/songgao/water\"\n)\n\nfunc main() {\n\tifce, err := water.New(water.Config{\n\t\tDeviceType: water.TAP,\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tvar frame ethernet.Frame\n\n\tfor {\n\t\tframe.Resize(1500)\n\t\tn, err := ifce.Read([]byte(frame))\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tframe = frame[:n]\n\t\tlog.Printf(\"Dst: %s\\n\", frame.Destination())\n\t\tlog.Printf(\"Src: %s\\n\", frame.Source())\n\t\tlog.Printf(\"Ethertype: % x\\n\", frame.Ethertype())\n\t\tlog.Printf(\"Payload: % x\\n\", frame.Payload())\n\t}\n}\n```\n\nSame as Linux version, but you don't need to bring up the device by hand, the only thing you need is to assign an IP address to it.\n\n```dos\ngo run main.go\n```\n\nIt will output a lot of lines because of some windows services and dhcp.\nYou will need admin right to assign IP.\n\nIn a new cmd (admin right):\n\n```dos\n# Replace with your device name, it can be achieved by ifce.Name().\nnetsh interface ip set address name=\"Ehternet 2\" source=static addr=10.1.0.10 mask=255.255.255.0 gateway=none\n```\n\nThe `main.go` terminal should be silenced after IP assignment, try sending some ICMP broadcast message:\n\n```dos\nping 10.1.0.255\n```\n\nYou'll see output containing the IPv4 ICMP frame same as the Linux version.\n\n#### Specifying interface name\n\nIf you are going to use multiple TAP devices on the Windows, there is a way to specify an interface name to select the exact device that you need:\n\n```go\n\tifce, err := water.New(water.Config{\n\t\tDeviceType: water.TAP,\n\t\tPlatformSpecificParams: water.PlatformSpecificParams{\n\t\t\tComponentID:   \"tap0901\",\n\t\t\tInterfaceName: \"Ethernet 3\",\n\t\t\tNetwork:       \"192.168.1.10/24\",\n\t\t},\n\t})\n```\n\n## TODO\n* tuntaposx for TAP on Darwin\n\n## Alternatives\n`tuntap`: [https://code.google.com/p/tuntap/](https://code.google.com/p/tuntap/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsonggao%2Fwater","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsonggao%2Fwater","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsonggao%2Fwater/lists"}