diff --git a/control.go b/control.go index 52a9e221..a37eeb6e 100644 --- a/control.go +++ b/control.go @@ -737,14 +737,39 @@ func handleInstallGetAddresses(w http.ResponseWriter, r *http.Request) { data.Interfaces = make(map[string]interface{}) for _, iface := range ifaces { - for i := range iface.Addresses { - ip, _, e := net.ParseCIDR(iface.Addresses[i]) - if e != nil { + addrs, err := iface.Addrs() + if err != nil { + httpError(w, http.StatusInternalServerError, "Failed to get addresses for interface %s: %s", iface.Name, err) + return + } + + jsonIface := netInterface{ + Name: iface.Name, + MTU: iface.MTU, + HardwareAddr: iface.HardwareAddr.String(), + } + + if iface.Flags != 0 { + jsonIface.Flags = iface.Flags.String() + } + + // we don't want link-local addresses in json, so skip them + for _, addr := range addrs { + ipnet, ok := addr.(*net.IPNet) + if !ok { + // not an IPNet, should not happen + httpError(w, http.StatusInternalServerError, "SHOULD NOT HAPPEN: got iface.Addrs() element %s that is not net.IPNet, it is %T", addr, addr) + return + } + // ignore link-local + if ipnet.IP.IsLinkLocalUnicast() { continue } - iface.Addresses[i] = ip.String() + jsonIface.Addresses = append(jsonIface.Addresses, ipnet.IP.String()) + } + if len(jsonIface.Addresses) != 0 { + data.Interfaces[iface.Name] = jsonIface } - data.Interfaces[iface.Name] = iface } w.Header().Set("Content-Type", "application/json") diff --git a/dhcp.go b/dhcp.go index 3e2cb31e..a67b0ef6 100644 --- a/dhcp.go +++ b/dhcp.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "net" "net/http" "strings" "time" @@ -75,8 +76,48 @@ func handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) { return } - for i := range ifaces { - response[ifaces[i].Name] = ifaces[i] + for _, iface := range ifaces { + if iface.Flags&net.FlagLoopback != 0 { + // it's a loopback, skip it + continue + } + if iface.Flags&net.FlagBroadcast == 0 { + // this interface doesn't support broadcast, skip it + continue + } + addrs, err := iface.Addrs() + if err != nil { + httpError(w, http.StatusInternalServerError, "Failed to get addresses for interface %s: %s", iface.Name, err) + return + } + + jsonIface := netInterface{ + Name: iface.Name, + MTU: iface.MTU, + HardwareAddr: iface.HardwareAddr.String(), + } + + if iface.Flags != 0 { + jsonIface.Flags = iface.Flags.String() + } + // we don't want link-local addresses in json, so skip them + for _, addr := range addrs { + ipnet, ok := addr.(*net.IPNet) + if !ok { + // not an IPNet, should not happen + httpError(w, http.StatusInternalServerError, "SHOULD NOT HAPPEN: got iface.Addrs() element %s that is not net.IPNet, it is %T", addr, addr) + return + } + // ignore link-local + if ipnet.IP.IsLinkLocalUnicast() { + continue + } + jsonIface.Addresses = append(jsonIface.Addresses, ipnet.IP.String()) + } + if len(jsonIface.Addresses) != 0 { + response[iface.Name] = jsonIface + } + } err = json.NewEncoder(w).Encode(response) diff --git a/helpers.go b/helpers.go index 0e4b1bf1..1bea694e 100644 --- a/helpers.go +++ b/helpers.go @@ -190,49 +190,26 @@ type netInterface struct { MTU int `json:"mtu"` HardwareAddr string `json:"hardware_address"` Addresses []string `json:"ip_addresses"` + Flags string `json:"flags"` } -// getValidNetInterfaces() returns interfaces that are eligible for DNS and/or DHCP -// invalid interface is either a loopback, ppp interface, or the one that doesn't allow broadcasts -func getValidNetInterfaces() ([]netInterface, error) { +// getValidNetInterfaces returns interfaces that are eligible for DNS and/or DHCP +// invalid interface is a ppp interface or the one that doesn't allow broadcasts +func getValidNetInterfaces() ([]net.Interface, error) { ifaces, err := net.Interfaces() if err != nil { return nil, fmt.Errorf("Couldn't get list of interfaces: %s", err) } - netIfaces := []netInterface{} + netIfaces := []net.Interface{} for i := range ifaces { - if ifaces[i].Flags&net.FlagLoopback != 0 { - // it's a loopback, skip it - continue - } - if ifaces[i].Flags&net.FlagBroadcast == 0 { - // this interface doesn't support broadcast, skip it - continue - } if ifaces[i].Flags&net.FlagPointToPoint != 0 { - // this interface is ppp, don't do dhcp over it + // this interface is ppp, we're not interested in this one continue } - iface := netInterface{ - Name: ifaces[i].Name, - MTU: ifaces[i].MTU, - HardwareAddr: ifaces[i].HardwareAddr.String(), - } - - addrs, err := ifaces[i].Addrs() - if err != nil { - return nil, fmt.Errorf("Failed to get addresses for interface %v: %s", ifaces[i].Name, err) - } - for _, addr := range addrs { - iface.Addresses = append(iface.Addresses, addr.String()) - } - if len(iface.Addresses) == 0 { - // this interface has no addresses, skip it - continue - } + iface := ifaces[i] netIfaces = append(netIfaces, iface) }