Windows router

76 阅读4分钟
route print
route print | more +0

netsh interface ipv4 show interfaces
netsh interface ipv4 set interface "以太网 3" forwarding=enabled
netsh interface ipv4 set interface "INTERFACE_NAME" forwarding=disabled

route add 8.8.8.8 mask 255.255.255.255 192.168.16.1 metric 25 if <接口号>
route add 8.8.8.8 mask 255.255.255.255 192.168.16.1 metric 25 if 9

route delete 8.8.8.8
using System;
using System.Net;
using System.Runtime.InteropServices;

namespace RouteForwarder
{
    static class RouteTableManager
    {
        public enum MIB_IPFORWARD_TYPE : uint
        {
            MIB_IPROUTE_TYPE_OTHER = 1,
            MIB_IPROUTE_TYPE_INVALID = 2,
            MIB_IPROUTE_TYPE_DIRECT = 3,
            MIB_IPROUTE_TYPE_INDIRECT = 4
        }

        public enum MIB_IPPROTO : uint
        {
            MIB_IPPROTO_OTHER = 1,
            MIB_IPPROTO_LOCAL = 2,
            MIB_IPPROTO_NETMGMT = 3,
            MIB_IPPROTO_ICMP = 4,
            MIB_IPPROTO_EGP = 5,
            MIB_IPPROTO_GGP = 6,
            MIB_IPPROTO_HELLO = 7,
            MIB_IPPROTO_RIP = 8,
            MIB_IPPROTO_IS_IS = 9,
            MIB_IPPROTO_ES_IS = 10,
            MIB_IPPROTO_CISCO = 11,
            MIB_IPPROTO_BBN = 12,
            MIB_IPPROTO_OSPF = 13,
            MIB_IPPROTO_BGP = 14,
            MIB_IPPROTO_NT_AUTOSTATIC = 10002,
            MIB_IPPROTO_NT_STATIC = 10006,
            MIB_IPPROTO_NT_STATIC_NON_DOD = 10007
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_IPFORWARDROW
        {
            public uint dwForwardDest;        // 目标 IP 地址
            public uint dwForwardMask;        // 子网掩码
            public uint dwForwardPolicy;      // 多路径路由条件,未使用,指定为 0
            public uint dwForwardNextHop;     // 下一跳的 IP 地址
            public uint dwForwardIfIndex;     // 接口索引
            public MIB_IPFORWARD_TYPE dwForwardType;        // 路由类型
            public MIB_IPPROTO dwForwardProto;       // 路由协议
            public uint dwForwardAge;         // 路由年龄
            public uint dwForwardNextHopAS;   // 自治系统号,不相关时为 0
            public int dwForwardMetric1;      // 度量值,未使用时为 -1(以下同)
            public int dwForwardMetric2;
            public int dwForwardMetric3;
            public int dwForwardMetric4;
            public int dwForwardMetric5;
        }

        [DllImport("Iphlpapi.dll")]
        [return: MarshalAs(UnmanagedType.U4)]
        private static extern int CreateIpForwardEntry(ref MIB_IPFORWARDROW pRoute);

        [DllImport("Iphlpapi.dll")]
        private static extern int GetIpInterfaceEntry(ref MIB_IPINTERFACE_ROW row);

        public static uint IPToInt(string ipAddress)
        {
            string[] segments = ipAddress.Split('.');
            uint ipUint = (uint.Parse(segments[3]) << 24) | (uint.Parse(segments[2]) << 16) |
                          (uint.Parse(segments[1]) << 8) | uint.Parse(segments[0]);
            return ipUint;
        }

        public static int CreateRoute(string destIPAddress, string destMask, string nextHopIPAddress, uint ifIndex, int metric)
        {
            MIB_IPFORWARDROW route = new MIB_IPFORWARDROW();
            route.dwForwardDest = IPToInt(destIPAddress);
            route.dwForwardMask = IPToInt(destMask);
            route.dwForwardNextHop = IPToInt(nextHopIPAddress);
            route.dwForwardIfIndex = ifIndex;
            route.dwForwardPolicy = 0;
            route.dwForwardType = MIB_IPFORWARD_TYPE.MIB_IPROUTE_TYPE_INDIRECT; // 间接路由,因为指定了下一跳
            route.dwForwardProto = MIB_IPPROTO.MIB_IPPROTO_NETMGMT;
            route.dwForwardAge = Convert.ToUInt32(0);
            route.dwForwardNextHopAS = Convert.ToUInt32(0);
            route.dwForwardMetric1 = metric;
            route.dwForwardMetric2 = -1;
            route.dwForwardMetric3 = -1;
            route.dwForwardMetric4 = -1;
            route.dwForwardMetric5 = -1;
            return CreateIpForwardEntry(ref route);
        }

        public struct MIB_IPINTERFACE_ROW
        {
            public uint Family;
            public ulong InterfaceLuid;
            public uint InterfaceIndex;
            public uint MaxReassemblySize;
            public ulong InterfaceIdentifier;
            public uint MinRouterAdvertisementInterval;
            public uint MaxRouterAdvertisementInterval;
            public byte AdvertisingEnabled;
            public byte ForwardingEnabled;
            public byte WeakHostSend;
            public byte WeakHostReceive;
            public byte UseAutomaticMetric;
            public byte UseNeighborUnreachabilityDetection;
            public byte ManagedAddressConfigurationSupported;
            public byte OtherStatefulConfigurationSupported;
            public byte AdvertiseDefaultRoute;
            public uint RouterDiscoveryBehavior;
            public uint DadTransmits;
            public uint BaseReachableTime;
            public uint RetransmitTime;
            public uint PathMtuDiscoveryTimeout;
            public uint LinkLocalAddressBehavior;
            public uint LinkLocalAddressTimeout;
            public uint ZoneIndice0, ZoneIndice1, ZoneIndice2, ZoneIndice3, ZoneIndice4, ZoneIndice5, ZoneIndice6, ZoneIndice7,
             ZoneIndice8, ZoneIndice9, ZoneIndice10, ZoneIndice11, ZoneIndice12, ZoneIndice13, ZoneIndice14, ZoneIndice15;
            public uint SitePrefixLength;
            public uint Metric;
            public uint NlMtu;
            public byte Connected;
            public byte SupportsWakeUpPatterns;
            public byte SupportsNeighborDiscovery;
            public byte SupportsRouterDiscovery;
            public uint ReachableTime;
            public byte TransmitOffload;
            public byte ReceiveOffload;
            public byte DisableDefaultRoutes;
        }

        public static int GetIpInterfaceEntry(uint interfaceIndex, out MIB_IPINTERFACE_ROW row)
        {
            row = new MIB_IPINTERFACE_ROW();
            row.Family = 2;
            //row.InterfaceLuid = 0;
            row.InterfaceIndex = interfaceIndex;
            return GetIpInterfaceEntry(ref row);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // 定义路由参数
            string destination = "192.168.2.0"; // 目标网络
            string mask = "255.255.255.0";      // 子网掩码
            string nextHop = "192.168.1.1";     // 下一跳 IP 地址
            uint interfaceIndex = 5; // 替换为您的网络接口名称
            int metric = 1;                     // 度量值

            if (interfaceIndex == 0)
            {
                Console.WriteLine("未找到指定的网络接口。");
                return;
            }

            RouteTableManager.MIB_IPINTERFACE_ROW ro = new RouteTableManager.MIB_IPINTERFACE_ROW();
            RouteTableManager.GetIpInterfaceEntry(interfaceIndex, out ro);

            // 添加路由
            int result = RouteTableManager.CreateRoute(destination, mask, nextHop, interfaceIndex, (int)ro.Metric);
            if (result == 0)
            {
                Console.WriteLine("路由添加成功。");
            }
            else
            {
                Console.WriteLine("添加路由失败,错误代码:{0}", result);
            }
        }

    }
}

package main

import (
	"encoding/binary"
	"fmt"
	"net"
	"unsafe"

	"golang.org/x/sys/windows"
)

type MIB_IPFORWARDROW struct {
	ForwardDest      uint32
	ForwardMask      uint32
	ForwardPolicy    uint32
	ForwardNextHop   uint32
	ForwardIfIndex   uint32
	ForwardType      uint32
	ForwardProto     uint32
	ForwardAge       uint32
	ForwardNextHopAS uint32
	ForwardMetric1   uint32
	ForwardMetric2   uint32
	ForwardMetric3   uint32
	ForwardMetric4   uint32
	ForwardMetric5   uint32
}

const (
	MIB_IPROUTE_TYPE_OTHER    = 1
	MIB_IPROUTE_TYPE_INVALID  = 2
	MIB_IPROUTE_TYPE_DIRECT   = 3
	MIB_IPROUTE_TYPE_INDIRECT = 4

	MIB_IPPROTO_OTHER   = 1
	MIB_IPPROTO_LOCAL   = 2
	MIB_IPPROTO_NETMGMT = 3
)

func getInterfaceIndexByName(name string) (uint32, error) {
	// 调用 GetAdaptersAddresses 获取网络接口信息
	var size uint32 = 15000
	buffer := make([]byte, size)
	adapters := (*windows.IpAdapterAddresses)(unsafe.Pointer(&buffer[0]))

	ret := windows.GetAdaptersAddresses(windows.AF_UNSPEC, 0, 0, adapters, &size)
	if ret != nil {
		return 0, windows.Errno(1)
	}

	for adapter := adapters; adapter != nil; adapter = adapter.Next {
		ifaceName := windows.UTF16PtrToString(adapter.FriendlyName)
		if ifaceName == name {
			return adapter.IfIndex, nil
		}
	}

	return 0, fmt.Errorf("未找到名称为 %s 的网络接口", name)
}

func main() {
	// 设置要添加的路由信息
	destIP := "192.168.1.0"  // 目标网络
	mask := "255.255.255.0"  // 子网掩码
	gateway := "192.168.1.1" // 网关地址
	ifaceName := "WLAN"      // 网络接口名称,需要根据实际情况修改
	// 获取网络接口索引
	ifIndex, err := getInterfaceIndexByName(ifaceName)
	if err != nil {
		fmt.Printf("获取接口索引失败: %v\n", err)
		return
	}

	// 将 IP 地址转换为 uint32
	destIPUint32 := ipToUint32(net.ParseIP(destIP))
	maskUint32 := ipToUint32(net.ParseIP(mask))
	gatewayUint32 := ipToUint32(net.ParseIP(gateway))

	route := MIB_IPFORWARDROW{
		ForwardDest:      destIPUint32,
		ForwardMask:      maskUint32,
		ForwardPolicy:    0,
		ForwardNextHop:   gatewayUint32,
		ForwardIfIndex:   ifIndex,
		ForwardType:      MIB_IPROUTE_TYPE_INDIRECT,
		ForwardProto:     MIB_IPPROTO_NETMGMT,
		ForwardAge:       0,
		ForwardNextHopAS: 0,
		ForwardMetric1:   uint32(35), // 路由度量值
		ForwardMetric2:   ^uint32(0),
		ForwardMetric3:   ^uint32(0),
		ForwardMetric4:   ^uint32(0),
		ForwardMetric5:   ^uint32(0),
	}

	// 加载 iphlpapi.dll 并获取 CreateIpForwardEntry 函数
	dll := windows.NewLazySystemDLL("iphlpapi.dll")
	procCreateIpForwardEntry := dll.NewProc("CreateIpForwardEntry")

	// 调用 CreateIpForwardEntry 函数
	ret, _, _ := procCreateIpForwardEntry.Call(uintptr(unsafe.Pointer(&route)))
	if ret != 0 {
		err := windows.Errno(ret)
		fmt.Printf("添加路由失败: %v\n", err.Error())
	} else {
		fmt.Println("路由添加成功。")
	}
}

func ipToUint32(ip net.IP) uint32 {
	ip = ip.To4()
	if ip == nil {
		return 0
	}
	return binary.LittleEndian.Uint32(ip)
}