1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
package main
import (
"bufio"
"fmt"
"iptcp/pkg/ipstack"
"net/netip"
"os"
"strings"
)
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)
// create a scanner to read from stdin for command-line inputs
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
line := scanner.Text()
switch line {
// 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.LongestPrefix(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)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Sent %d bytes to %s\n", bytesWritten, neighbor.VipAddr.String())
}
}
}
}
}
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
}
}
}
|