package dhcp import ( "bufio" "os" "os/exec" "regexp" "strings" "github.com/nemunaire/repeater/internal/models" ) // parseDHCPLeases reads and parses DHCP lease file func parseDHCPLeases(path string) ([]models.DHCPLease, error) { var leases []models.DHCPLease file, err := os.Open(path) if err != nil { return leases, err } defer file.Close() scanner := bufio.NewScanner(file) var currentLease models.DHCPLease for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if strings.HasPrefix(line, "lease ") { ip := strings.Fields(line)[1] currentLease = models.DHCPLease{IP: ip} } else if strings.Contains(line, "hardware ethernet") { mac := strings.Fields(line)[2] mac = strings.TrimSuffix(mac, ";") currentLease.MAC = mac } else if strings.Contains(line, "client-hostname") { hostname := strings.Fields(line)[1] hostname = strings.Trim(hostname, `";`) currentLease.Hostname = hostname } else if line == "}" { if currentLease.IP != "" && currentLease.MAC != "" { leases = append(leases, currentLease) } currentLease = models.DHCPLease{} } } return leases, nil } // getARPInfo retrieves ARP table information using arp command // Returns a map of IP -> MAC address func getARPInfo() (map[string]string, error) { arpInfo := make(map[string]string) cmd := exec.Command("arp", "-a") output, err := cmd.Output() if err != nil { return arpInfo, err } lines := strings.Split(string(output), "\n") for _, line := range lines { if matches := regexp.MustCompile(`\(([^)]+)\) at ([0-9a-fA-F:]{17})`).FindStringSubmatch(line); len(matches) > 2 { ip := matches[1] mac := matches[2] arpInfo[ip] = mac } } return arpInfo, nil }