diff options
Diffstat (limited to 'cmd/vrouter/main.go')
-rw-r--r-- | cmd/vrouter/main.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/cmd/vrouter/main.go b/cmd/vrouter/main.go new file mode 100644 index 0000000..f338b80 --- /dev/null +++ b/cmd/vrouter/main.go @@ -0,0 +1,128 @@ +package main + +import ( + "bufio" + "fmt" + "iptcp/pkg/ipstack" + // "iptcp/pkg/tcpstack" + "net/netip" + "os" + "strings" + // "strconv" +) + +func main() { + // checks that a config file is passed as an argument + if len(os.Args) == 1 { + fmt.Printf("Usage: %s <configFile>\n", os.Args[0]) + os.Exit(1) + } + + // get config file name from command line argument + fileName := os.Args[2] + + // initialize the router with its config file + err := ipstack.Initialize(fileName) + if err != nil { + // return if there is an error + return + } + + // register the test protocol + ipstack.RegisterProtocolHandler(ipstack.TEST_PROTOCOL) + // register the rip protocol for the router + ipstack.RegisterProtocolHandler(ipstack.RIP_PROTOCOL) + // register the TCP protocol for the handler + ipstack.RegisterProtocolHandler(ipstack.TCP_PROTOCOL) + + + // create a scanner to read from stdin for command-line inputs + scanner := bufio.NewScanner(os.Stdin) + + for scanner.Scan() { + line := scanner.Text() + tokens := strings.Split(line, " ") + switch tokens[0] { + // print the interfaces + case "li": + fmt.Println("Name\tAddr/Prefix\tState") + fmt.Println(ipstack.SprintInterfaces()) + // print the neighbors + case "ln": + fmt.Println("Iface\tVIP\t\tUDPAddr") + fmt.Println(ipstack.SprintNeighbors()) + // print the routing table + case "lr": + fmt.Println("T\tPrefix\t\tNext Hop\tCost") + fmt.Println(ipstack.SprintRoutingTable()) + // exit the program + case "q": + ipstack.CleanUp() + os.Exit(0) + case "exit": + ipstack.CleanUp() + os.Exit(0) + default: + if len(line) > 4 { + // disable an interface + if line[:4] == "down" { + ifaceName := line[5:] + ipstack.InterfaceDownREPL(ifaceName) + } + + // attempts to send message to destination + 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) + + // get the longest prefix match for the destination + address, _ := netip.ParseAddr(ipAddr) + hop, err := ipstack.Route(address) + if err != nil { + fmt.Println(err) + continue + } + + myAddr := hop.Interface.IpPrefix.Addr() + // attempt to send the message to the destination + for _, neighbor := range ipstack.GetNeighbors()[hop.Interface.Name] { + if neighbor.VipAddr == address || + neighbor.VipAddr == hop.VIP { + // send the message to the neighbor + bytesWritten, err := ipstack.SendIP(&myAddr, neighbor, ipstack.TEST_PROTOCOL, messageToSendBytes, ipAddr, nil) + fmt.Printf("Sent %d bytes to %s\n", bytesWritten, neighbor.VipAddr.String()) + if err != nil { + fmt.Println(err) + } + } + } + } + } + if len(line) > 2 { + // enable an interface + if line[:2] == "up" { + // get interface name + ifaceName := line[3:] + ipstack.InterfaceUpREPL(ifaceName) + } + } else { + fmt.Println("Invalid command: ", line) + fmt.Println("Commands: ") + fmt.Println(" exit/q Terminate this program") + fmt.Println(" li List interfaces") + fmt.Println(" lr List routes") + fmt.Println(" ln List available neighbors") + fmt.Println(" up Enable an interface") + fmt.Println(" down Disable an interface") + fmt.Println(" send Send test packet") + } + continue + } + } +} |