-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
212 additions
and
30 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[Unit] | ||
Description=Setup virtual ethernet interfaces (veth) | ||
Before=systemd-networkd.service | ||
|
||
[Service] | ||
Type=oneshot | ||
ExecStart=/usr/local/bin/setup_veth.sh | ||
RemainAfterExit=yes | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/bin/bash | ||
# Create 4 pairs of veth interfaces | ||
|
||
for i in {0..1}; do | ||
veth_in="calaos-${i}-0" | ||
veth_out="calaos-${i}-1" | ||
|
||
ip link add "$veth_in" type veth peer name "$veth_out" | ||
ip link set "$veth_in" up | ||
ip link set "$veth_out" up | ||
done |
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,153 @@ | ||
package models | ||
|
||
import "net" | ||
import ( | ||
"bufio" | ||
"encoding/json" | ||
"fmt" | ||
"os/exec" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
type NetIntf struct { | ||
Name string `json:"name"` | ||
IPv4 string `json:"ipv4"` | ||
Mask string `json:"mask"` | ||
Gateway string `json:"gateway"` | ||
IPv6 string `json:"ipv6"` | ||
MAC string `json:"mac"` | ||
IsLoopback bool `json:"is_loopback"` | ||
State string `json:"state"` | ||
} | ||
|
||
type DNSConfig struct { | ||
Interface string `json:"interface"` | ||
DNSServers []string `json:"dns_servers"` | ||
SearchDomains []string `json:"search_domains"` | ||
} | ||
|
||
type RawNetInterface struct { | ||
Name string `json:"Name"` | ||
Flags int `json:"Flags"` | ||
IPv4 string `json:"IPv4Address"` | ||
IPv4Mask int `json:"IPv4Mask"` | ||
IPv6 string `json:"IPv6LinkLocalAddress"` | ||
MAC string `json:"HardwareAddress"` | ||
State string `json:"KernelOperationalStateString"` | ||
Addresses []struct { | ||
Family int `json:"Family"` | ||
Scope string `json:"ScopeString"` | ||
Prefix int `json:"PrefixLength"` | ||
} `json:"Addresses"` | ||
Routes []struct { | ||
Family int `json:"Family"` | ||
Type string `json:"TypeString"` | ||
Gateway string `json:"Gateway"` | ||
Dest string `json:"Destination"` | ||
PrefixLen int `json:"DestinationPrefixLength"` | ||
} `json:"Routes"` | ||
} | ||
|
||
type RawDNSConfig struct { | ||
Link int `json:"Link"` | ||
CurrentDNS []string `json:"CurrentDNSServer"` | ||
SearchDomains []string `json:"Domains"` | ||
LLMNR string `json:"LLMNR"` | ||
MulticastDNS string `json:"MulticastDNS"` | ||
DNSSEC string `json:"DNSSEC"` | ||
InterfaceName string `json:"InterfaceName"` | ||
} | ||
|
||
func parseMask(prefixLen int) string { | ||
mask := (0xFFFFFFFF << (32 - prefixLen)) & 0xFFFFFFFF | ||
return fmt.Sprintf("%d.%d.%d.%d", (mask>>24)&0xFF, (mask>>16)&0xFF, (mask>>8)&0xFF, mask&0xFF) | ||
} | ||
|
||
func GetAllNetInterfaces() (nets []*NetIntf, err error) { | ||
ifaces, err := net.Interfaces() | ||
cmd := exec.Command("/usr/bin/networkctl", "list", "--json=short") | ||
output, err := cmd.Output() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
for _, iface := range ifaces { | ||
addrs, err := iface.Addrs() | ||
if err != nil { | ||
return nil, err | ||
var rawInterfaces []RawNetInterface | ||
if err := json.Unmarshal(output, &rawInterfaces); err != nil { | ||
return nil, err | ||
} | ||
|
||
for _, rawIntf := range rawInterfaces { | ||
netIntf := &NetIntf{ | ||
Name: rawIntf.Name, | ||
MAC: rawIntf.MAC, | ||
State: rawIntf.State, | ||
IsLoopback: (rawIntf.Flags & 0x8) != 0, // check IFF_LOOPBACK | ||
} | ||
|
||
intf := &NetIntf{ | ||
Name: iface.Name, | ||
IsLoopback: iface.Flags&net.FlagLoopback != 0, | ||
MAC: iface.HardwareAddr.String(), | ||
// Look for IPv4 address and mask | ||
for _, addr := range rawIntf.Addresses { | ||
if addr.Family == 2 { // IPv4 | ||
netIntf.IPv4 = fmt.Sprintf("%d.%d.%d.%d", addr.Scope[0], addr.Scope[1], addr.Scope[2], addr.Scope[3]) | ||
netIntf.Mask = parseMask(addr.Prefix) | ||
break | ||
} | ||
} | ||
|
||
for _, addr := range addrs { | ||
ipNet, ok := addr.(*net.IPNet) | ||
if !ok { | ||
continue | ||
// Look for IPv6 address | ||
for _, addr := range rawIntf.Addresses { | ||
if addr.Family == 10 { // IPv6 | ||
netIntf.IPv6 = rawIntf.IPv6 | ||
break | ||
} | ||
} | ||
|
||
// Skip IPv6 addresses | ||
if ipNet.IP.To4() == nil { | ||
intf.IPv6 = ipNet.IP.String() | ||
} else if ipNet.IP.To16() != nil { | ||
intf.IPv4 = ipNet.IP.String() | ||
// Look for default gateway | ||
for _, route := range rawIntf.Routes { | ||
if route.Type == "unicast" && route.Gateway != "" { | ||
netIntf.Gateway = route.Gateway | ||
break | ||
} | ||
} | ||
|
||
nets = append(nets, intf) | ||
nets = append(nets, netIntf) | ||
} | ||
|
||
return nets, nil | ||
} | ||
|
||
func GetDNSConfig() ([]*DNSConfig, error) { | ||
cmd := exec.Command("/usr/bin/resolvectl", "status") | ||
output, err := cmd.Output() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var dnsConfigs []*DNSConfig | ||
var currentConfig *DNSConfig | ||
|
||
scanner := bufio.NewScanner(strings.NewReader(string(output))) | ||
dnsServerRegex := regexp.MustCompile(`DNS Servers? ([\d.]+)`) | ||
interfaceRegex := regexp.MustCompile(`Link (\d+) \(([^)]+)\)`) | ||
|
||
for scanner.Scan() { | ||
line := scanner.Text() | ||
|
||
if strings.HasPrefix(line, "Global") { | ||
currentConfig = &DNSConfig{Interface: "global"} | ||
dnsConfigs = append(dnsConfigs, currentConfig) | ||
} else if matches := interfaceRegex.FindStringSubmatch(line); len(matches) == 3 { | ||
currentConfig = &DNSConfig{Interface: matches[2]} | ||
dnsConfigs = append(dnsConfigs, currentConfig) | ||
} | ||
|
||
if dnsServerRegex.MatchString(line) { | ||
server := dnsServerRegex.FindStringSubmatch(line)[1] | ||
currentConfig.DNSServers = append(currentConfig.DNSServers, server) | ||
} | ||
} | ||
|
||
if err := scanner.Err(); err != nil { | ||
return nil, err | ||
} | ||
|
||
return | ||
return dnsConfigs, nil | ||
} |