commit bb9c0e7e3d766c7927e20845db03b53b5119760c Author: tuna2134 Date: Tue Jun 30 11:31:07 2026 +0900 ok diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6523a7a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/etherip-client \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..45e8be1 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,44 @@ +/* +Copyright © 2026 Masato Kikuchi +*/ +package cmd + +import ( + "net" + "os" + + "git.neody.ad.jp/tuna2134/etherip-client/utils" + "github.com/spf13/cobra" +) + +var devName string +var localIP net.IP +var remoteIP net.IP +var linkName string + +var rootCmd = &cobra.Command{ + Use: "etherip-client", + Short: "Ethernet over IPv6(RFC3378)カーネルのクライアント", + RunE: runE, +} + +func runE(cmd *cobra.Command, args []string) error { + err := utils.AddDev(devName, localIP, remoteIP, linkName) + return err +} + +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + rootCmd.Flags().StringVarP(&devName, "devname", "d", "eip0", "作成するNICの名") + rootCmd.Flags().IPVarP(&localIP, "local", "l", nil, "自分の終端アドレス") + rootCmd.Flags().IPVarP(&remoteIP, "remote", "r", nil, "相手の終端アドレス") + rootCmd.Flags().StringVarP(&linkName, "link", "L", "", "アンダーレイのNIC名") +} + + diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e27b1cc --- /dev/null +++ b/go.mod @@ -0,0 +1,15 @@ +module git.neody.ad.jp/tuna2134/etherip-client + +go 1.26.4 + +require ( + github.com/vishvananda/netlink v1.3.1 + golang.org/x/sys v0.46.0 +) + +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/vishvananda/netns v0.0.5 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..987b659 --- /dev/null +++ b/go.sum @@ -0,0 +1,18 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= +github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= +github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= +github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/main.go b/main.go new file mode 100644 index 0000000..7843e5d --- /dev/null +++ b/main.go @@ -0,0 +1,10 @@ +/* +Copyright © 2026 Masato Kikuchi +*/ +package main + +import "git.neody.ad.jp/tuna2134/etherip-client/cmd" + +func main() { + cmd.Execute() +} diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..51aae0e --- /dev/null +++ b/test.sh @@ -0,0 +1 @@ +sudo ./etherip-client -d eip0 -l 2402:2f60:500:beef:be24:11ff:fe12:d655 -r 2401:5e40:1:462:6709:e050:dcc5:d592 -L ens18 \ No newline at end of file diff --git a/utils/addDev.go b/utils/addDev.go new file mode 100644 index 0000000..c1e4c65 --- /dev/null +++ b/utils/addDev.go @@ -0,0 +1,67 @@ +/* +Copyright © 2026 Masato Kikuchi +*/ + +package utils + +import ( + "encoding/binary" + "net" + + "github.com/vishvananda/netlink" + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +const ( + IFLA_ETHERIP6_UNSPEC = iota + IFLA_ETHERIP6_LOCAL + IFLA_ETHERIP6_REMOTE + IFLA_ETHERIP6_LINK + IFLA_ETHERIP6_HOP_LIMIT +) + +func u32(v uint32) []byte { + b := make([]byte, 4) + binary.NativeEndian.PutUint32(b, v) + return b +} + +func AddDev(DevName string, local net.IP, remote net.IP, linkName string) error { + req := nl.NewNetlinkRequest( + unix.RTM_NEWLINK, + unix.NLM_F_REQUEST|unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK, + ) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + req.AddData(msg) + + req.AddData(nl.NewRtAttr(unix.IFLA_IFNAME, []byte(DevName))) + + linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) + linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nl.ZeroTerminated("etherip6")) + + infoData := nl.NewRtAttr(nl.IFLA_INFO_DATA, nil) + infoData.AddRtAttr(IFLA_ETHERIP6_LOCAL, local.To16()) + infoData.AddRtAttr(IFLA_ETHERIP6_REMOTE, remote.To16()) + + if linkName != "" { + link, err := netlink.LinkByName(linkName) + if err != nil { + return err + } + infoData.AddRtAttr(IFLA_ETHERIP6_LINK, u32(uint32(link.Attrs().Index))) + } + + infoData.AddRtAttr(IFLA_ETHERIP6_HOP_LIMIT, []byte{255}) + + linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, infoData.Serialize()) + req.AddData(linkInfo) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + + if err != nil { + return err + } + return nil +} \ No newline at end of file