package main import ( "log" "syscall" "unsafe" "golang.org/x/sys/windows" ) var ( modws2_32 = windows.NewLazySystemDLL("ws2_32.dll") modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll") procWSACreateEvent = modws2_32.NewProc("WSACreateEvent") procNotifyAddrChange = modiphlpapi.NewProc("NotifyAddrChange") ) func main() { log.Printf("Library [ws2_32.dll] loaded at %#v", modws2_32.Handle()) log.Printf("Library [iphlpapi.dll] loaded at %#v", modiphlpapi.Handle()) log.Printf("Symbol [WSACreateEvent] loaded at %#v", procWSACreateEvent.Addr()) log.Printf("Symbol [NotifyAddrChange] loaded at %#v", procNotifyAddrChange.Addr()) var ( err error overlap *windows.Overlapped = &windows.Overlapped{} ) log.Println("Invoking WSACreateEvent()") overlap.HEvent, err = WSACreateEvent() if err != nil { log.Fatalf("failed to create internal windows event: %s", err) } else { log.Printf("Got handle at: %#v\n", overlap.HEvent) } event_loop: for { log.Println("Invoking NotifyAddrChange()") notifyHandle := windows.Handle(0) syscall.Syscall(uintptr(procNotifyAddrChange.Addr()), 2, uintptr(notifyHandle), uintptr(unsafe.Pointer(overlap)), 0) log.Println("Waiting for network changes") event, err := windows.WaitForSingleObject(overlap.HEvent, windows.INFINITE) switch event { case windows.WAIT_OBJECT_0: log.Println("Windows kernel notified of a network address change") // TODO(lh): Act upon interface changes default: log.Println(err) break event_loop } } windows.Close(overlap.HEvent) } func WSACreateEvent() (windows.Handle, error) { handlePtr, _, errNum := syscall.Syscall(procWSACreateEvent.Addr(), 0, 0, 0, 0) if handlePtr == 0 { return 0, errNum } else { return windows.Handle(handlePtr), nil } }