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
|
package main
import (
"bufio"
"fmt"
"iptcp/pkg/ipstack"
"net/netip"
"os"
"strings"
)
func main() {
if len(os.Args) == 1 {
fmt.Printf("Usage: %s <configFile>\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)
case "exit":
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)
address, _ := netip.ParseAddr(ipAddr)
hop, err := ipstack.Route(address)
if err != nil {
fmt.Println(err)
continue
}
myAddr := hop.Interface.IpPrefix.Addr()
for _, neighbor := range ipstack.GetNeighbors()[hop.Interface.Name] {
if neighbor.VipAddr == address ||
neighbor.VipAddr == hop.VIP && hop.Type == "S" {
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 {
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 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
}
}
}
|