| 83 | } |
| 84 | |
| 85 | func Main() error { |
| 86 | var args struct { |
| 87 | Tun string |
| 88 | Address string |
| 89 | Port uint16 |
| 90 | } |
| 91 | arg.MustParse(&args) |
| 92 | |
| 93 | // lock the OS thread in order to switch network namespaces |
| 94 | runtime.LockOSThread() |
| 95 | defer runtime.UnlockOSThread() |
| 96 | |
| 97 | // save a reference to our initial network namespace so we can get back |
| 98 | origns, err := netns.Get() |
| 99 | if err != nil { |
| 100 | return fmt.Errorf("error getting initial network namespace: %w", err) |
| 101 | } |
| 102 | defer origns.Close() |
| 103 | |
| 104 | // parse the mac address |
| 105 | maddr, err := net.ParseMAC(*mac) |
| 106 | if err != nil { |
| 107 | log.Fatalf("Bad MAC address: %v", *mac) |
| 108 | } |
| 109 | |
| 110 | // parse our IP address |
| 111 | localAddr := net.ParseIP(args.Address) |
| 112 | if localAddr == nil { |
| 113 | log.Fatalf("Bad IP address: %v", args.Address) |
| 114 | } |
| 115 | |
| 116 | var addrWithPrefix tcpip.AddressWithPrefix |
| 117 | var proto tcpip.NetworkProtocolNumber |
| 118 | if localAddr.To4() != nil { |
| 119 | addrWithPrefix = tcpip.AddrFromSlice(localAddr.To4()).WithPrefix() |
| 120 | proto = ipv4.ProtocolNumber |
| 121 | } else if localAddr.To16() != nil { |
| 122 | addrWithPrefix = tcpip.AddrFromSlice(localAddr.To16()).WithPrefix() |
| 123 | proto = ipv6.ProtocolNumber |
| 124 | } else { |
| 125 | log.Fatalf("Unknown IP type: %v", args.Address) |
| 126 | } |
| 127 | |
| 128 | // Create the stack with ip and tcp protocols, then add a tun-based |
| 129 | // NIC and address. |
| 130 | s := stack.New(stack.Options{ |
| 131 | NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol, arp.NewProtocol}, |
| 132 | TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol}, |
| 133 | }) |
| 134 | |
| 135 | // Create a new network namespace |
| 136 | newns, err := netns.New() |
| 137 | if err != nil { |
| 138 | return fmt.Errorf("error creating network namespace: %w", err) |
| 139 | } |
| 140 | defer newns.Close() |
| 141 | |
| 142 | // create a new tun device in the new namespace |