package main import ( "bufio" "fmt" "iptcp/pkg/ipstack" "net/netip" "os" "strings" ) func main() { if len(os.Args) == 1 { fmt.Printf("Usage: %s \n", os.Args[0]) os.Exit(1) } fileName := os.Args[2] err := ipstack.Initialize(fileName) if err != nil { return } ipstack.RegisterProtocolHandler(ipstack.TEST_PROTOCOL) scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := scanner.Text() switch line { case "li": fmt.Println("Name\tAddr/Prefix\tState") fmt.Println(ipstack.SprintInterfaces()) case "ln": fmt.Println("Iface\tVIP\tUDPAddr") fmt.Println(ipstack.SprintNeighbors()) case "lr": fmt.Println("T\tPrefix\tNext Hop\tCost") fmt.Println(ipstack.SprintRoutingTable()) case "q": ipstack.CleanUp() os.Exit(0) default: if len(line) > 4 { if line[:4] == "down" { ifaceName := line[5:] ipstack.InterfaceDownREPL(ifaceName) } if line[:4] == "send" { // get IP address and message that follows it IPAndMessage := strings.Split(line, " ") ipAddr := IPAndMessage[1] message := IPAndMessage[2:] // combine message into one string messageToSend := strings.Join(message, " ") messageToSendBytes := []byte(messageToSend) hop, err := ipstack.LongestPrefix(netip.MustParseAddr(ipAddr)) if err != nil { fmt.Println(err) continue } myAddr := hop.Interface.IpPrefix.Addr() for _, neighbor := range ipstack.GetNeighbors()[hop.Interface.Name] { // TODO: fix multiple send bug here on static route if neighbor.VipAddr == netip.MustParseAddr(ipAddr) || neighbor.VipAddr == hop.VIP && hop.Type == "S" { bytesWritten, err := ipstack.SendIP(&myAddr, neighbor, ipstack.TEST_PROTOCOL, messageToSendBytes, ipAddr, nil) if err != nil { fmt.Println(err) } else { fmt.Printf("Sent %d bytes to %s\n", bytesWritten, neighbor.VipAddr.String()) } } } } } if len(line) > 2 { if line[:2] == "up" { // get interface name ifaceName := line[3:] ipstack.InterfaceUpREPL(ifaceName) } } continue } } }