Created
August 10, 2022 20:57
-
-
Save Oppodelldog/84c4b5b7ac051b36895bf5d618efe368 to your computer and use it in GitHub Desktop.
win routing - find intersecting routing entries (IPv4)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net" | |
"reflect" | |
"syscall" | |
"unsafe" | |
) | |
func main() { | |
var routes, err = NewRouteTable().GetRoutes() | |
if err != nil { | |
panic(err) | |
} | |
var nets []net.IPNet | |
for _, route := range routes { | |
ipNet := net.IPNet{ | |
IP: route.GetForwardDest(), | |
Mask: route.GetForwardMask(), | |
} | |
nets = append(nets, ipNet) | |
} | |
for i1 := 0; i1 < len(nets); i1++ { | |
for i2 := 0; i2 < len(nets); i2++ { | |
if i1 == i2 { | |
continue | |
} | |
if reflect.DeepEqual(nets[i1].IP, net.IP([]byte{0, 0, 0, 0})) { | |
continue | |
} | |
if reflect.DeepEqual(nets[i2].IP, net.IP([]byte{0, 0, 0, 0})) { | |
continue | |
} | |
if reflect.DeepEqual(nets[i1].Mask, net.IPMask([]byte{255, 255, 255, 255})) { | |
continue | |
} | |
if reflect.DeepEqual(nets[i2].Mask, net.IPMask([]byte{255, 255, 255, 255})) { | |
continue | |
} | |
if reflect.DeepEqual(nets[i1].IP, nets[i2].IP) { | |
continue | |
} | |
if netsIntersect(nets[i1], nets[i2]) { | |
fmt.Println("network intersection between ", nets[i1], " and ", nets[i2]) | |
} | |
} | |
} | |
} | |
func netsIntersect(n1, n2 net.IPNet) bool { | |
return n1.Contains(n2.IP) || n2.Contains(n1.IP) | |
} | |
type Table struct { | |
iphlpapi *syscall.LazyDLL | |
getIpForwardTable *syscall.LazyProc | |
createIpForwardEntry *syscall.LazyProc | |
deleteIpForwardEntry *syscall.LazyProc | |
} | |
type TableRow struct { | |
ForwardDest [4]byte | |
ForwardMask [4]byte | |
ForwardPolicy uint32 | |
ForwardNextHop [4]byte | |
ForwardIfIndex uint32 | |
ForwardType uint32 | |
ForwardProto uint32 | |
ForwardAge uint32 | |
ForwardNextHopAS uint32 | |
ForwardMetric1 uint32 | |
ForwardMetric2 uint32 | |
ForwardMetric3 uint32 | |
ForwardMetric4 uint32 | |
ForwardMetric5 uint32 | |
} | |
func (rr *TableRow) GetForwardDest() net.IP { | |
var ip = make(net.IP, 4) | |
copy(ip, rr.ForwardDest[:]) | |
return ip | |
} | |
func (rr *TableRow) GetForwardMask() net.IPMask { | |
var ip = make(net.IPMask, 4) | |
copy(ip, rr.ForwardMask[:]) | |
return ip | |
} | |
func (rr *TableRow) GetForwardNextHop() net.IP { | |
var ip = make(net.IP, 4) | |
copy(ip, rr.ForwardNextHop[:]) | |
return ip | |
} | |
func NewRouteTable() *Table { | |
iphlpapi := syscall.NewLazyDLL("iphlpapi.dll") | |
getIpForwardTable := iphlpapi.NewProc("GetIpForwardTable") | |
return &Table{ | |
iphlpapi: iphlpapi, | |
getIpForwardTable: getIpForwardTable, | |
} | |
} | |
func (rt *Table) GetRoutes() ([]TableRow, error) { | |
var bufLen uint32 | |
rt.getIpForwardTable.Call(uintptr(0), uintptr(unsafe.Pointer(&bufLen)), 0) | |
var r1 uintptr | |
var buf = make([]byte, bufLen) | |
r1, _, _ = rt.getIpForwardTable.Call(uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&bufLen)), 0) | |
if r1 != 0 { | |
return nil, fmt.Errorf("failed to get the routing table, return value:%v", r1) | |
} | |
var ( | |
num = *(*uint32)(unsafe.Pointer(&buf[0])) | |
routes = make([]TableRow, num) | |
sr = uintptr(unsafe.Pointer(&buf[0])) + unsafe.Sizeof(num) | |
rowSize = unsafe.Sizeof(TableRow{}) | |
expectedBufferSize = int(bufLen) | |
actualBufferSize = int(unsafe.Sizeof(num) + rowSize*uintptr(num)) | |
) | |
if expectedBufferSize < actualBufferSize { | |
return nil, fmt.Errorf("buffer exceeded the expected size, expected: %v, actual: %v", expectedBufferSize, actualBufferSize) | |
} | |
for i := 0; i < int(num); i++ { | |
routes[i] = *((*TableRow)(unsafe.Pointer(sr + (rowSize * uintptr(i))))) | |
} | |
return routes, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment