給定 **目標 IP**、**路由器子網遮罩**、**路由器網路位址**。
判斷:`(目標 IP AND 子網遮罩) == 路由器網路位址` → 可經由該路由轉發。
public static class RoutingHelper
{
///
/// 判斷目標 IP 是否落在路由器網段內
///
public static bool CanRoute(string targetIp, string subnetMask, string networkAddress)
{
var tip = ParseIp(targetIp);
var mask = ParseIp(subnetMask);
var net = ParseIp(networkAddress);
for (int i = 0; i < 4; i++)
{
if ((tip[i] & mask[i]) != net[i])
return false;
}
return true;
}
private static byte[] ParseIp(string ip)
{
var parts = ip.Split('.');
if (parts.Length != 4) throw new ArgumentException("IP 格式錯誤");
var bytes = new byte[4];
for (int i = 0; i < 4; i++)
bytes[i] = byte.Parse(parts[i]);
return bytes;
}
}
// 使用範例
// 目標: 130.50.15.9
// 路由器: 255.255.252.0 / 130.50.15.0
// 130.50.15.9 & 255.255.252.0 = 130.50.12.0 != 130.50.15.0 → 不可路由
bool ok = RoutingHelper.CanRoute("130.50.15.9", "255.255.252.0", "130.50.15.0"); // false
public static bool CanRouteCIDR(string targetIp, string cidr) // e.g. "130.50.12.0/22"
{
var parts = cidr.Split('/');
var netAddr = ParseIp(parts[0]);
int prefixLen = int.Parse(parts[1]);
// 建立遮罩
var mask = new byte[4];
for (int i = 0; i < prefixLen; i++)
mask[i / 8] |= (byte)(0x80 >> (i % 8));
var tip = ParseIp(targetIp);
for (int i = 0; i < 4; i++)
if ((tip[i] & mask[i]) != netAddr[i]) return false;
return true;
}
public class Router
{
private readonly List _routes = new();
public void AddRoute(string networkCidr, string nextHop, string interfaceName)
{
_routes.Add(new RouteEntry(networkCidr, nextHop, interfaceName));
}
public RouteEntry Lookup(string targetIp)
{
// 最長前綴匹配:先按前綴長度降序排序
return _routes
.OrderByDescending(r => r.PrefixLength)
.FirstOrDefault(r => r.Match(targetIp));
}
}
public class RouteEntry
{
public byte[] Network { get; }
public byte[] Mask { get; }
public int PrefixLength { get; }
public string NextHop { get; }
public string Interface { get; }
public RouteEntry(string cidr, string nextHop, string iface)
{
var parts = cidr.Split('/');
Network = ParseIp(parts[0]);
PrefixLength = int.Parse(parts[1]);
NextHop = nextHop;
Interface = iface;
Mask = new byte[4];
for (int i = 0; i < PrefixLength; i++)
Mask[i / 8] |= (byte)(0x80 >> (i % 8));
}
public bool Match(string targetIp)
{
var tip = ParseIp(targetIp);
for (int i = 0; i < 4; i++)
if ((tip[i] & Mask[i]) != Network[i]) return false;
return true;
}
}
路由判斷本質是 **位元級 AND 運算 + 比較**。掌握 `byte[]` 解析、CIDR 遮罩生成、**最長前綴匹配 (LPM)** 排序查找,即可實作完整路由表查詢邏輯。生產級路由器仍建議使用 **BPF / eBPF / DPDK / P4** 等資料平面技術以達到線速轉發。