aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/vhost/main.go10
-rw-r--r--cmd/vrouter/main.go49
-rw-r--r--lnxfiles/doc-example/binaries.example.json17
-rw-r--r--lnxfiles/doc-example/nodes.json7
-rw-r--r--lnxfiles/loop/binaries.example.json23
-rw-r--r--lnxfiles/loop/nodes.json9
-rw-r--r--lnxfiles/r1h2/binaries.example.json11
-rw-r--r--lnxfiles/r1h2/nodes.json5
-rw-r--r--lnxfiles/r1h4/binaries.example.json17
-rw-r--r--lnxfiles/r1h4/nodes.json7
-rw-r--r--lnxfiles/r2h2/binaries.example.json14
-rw-r--r--lnxfiles/r2h2/nodes.json6
-rw-r--r--lnxfiles/r3h2/binaries.example.json17
-rw-r--r--lnxfiles/r3h2/nodes.json7
-rwxr-xr-xlnxfiles/vhostbin0 -> 3110339 bytes
-rwxr-xr-xlnxfiles/vrouterbin0 -> 3110339 bytes
-rw-r--r--pkg/ipstack/ipstack.go314
-rwxr-xr-xvhostbin3095650 -> 0 bytes
-rwxr-xr-xvrouterbin3095650 -> 0 bytes
19 files changed, 241 insertions, 272 deletions
diff --git a/cmd/vhost/main.go b/cmd/vhost/main.go
index dbf899a..26280ef 100644
--- a/cmd/vhost/main.go
+++ b/cmd/vhost/main.go
@@ -84,6 +84,16 @@ func main() {
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
}
diff --git a/cmd/vrouter/main.go b/cmd/vrouter/main.go
index cde49a8..02104c5 100644
--- a/cmd/vrouter/main.go
+++ b/cmd/vrouter/main.go
@@ -10,57 +10,61 @@ import (
)
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)
- // TODO @ MICHAEL: Dont know why its not running instantly
- //go func() {
- // for {
- // ipstack.RequestRip()
- // // takes time to compute I think
- // // TODO @ MICHAEL
- // time.Sleep(2 * time.Second)
- // }
- //}()
-
- // TODO @ MICHEAL
- // go ipstack.CheckAndUpdateRoutingTable()
-
+ // 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\tUDPAddr")
+ fmt.Println("Iface\tVIP\t\tUDPAddr")
fmt.Println(ipstack.SprintNeighbors())
+ // print the routing table
case "lr":
- fmt.Println("T\tPrefix\tNext Hop\tCost")
+ 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, " ")
@@ -71,15 +75,19 @@ func main() {
messageToSend := strings.Join(message, " ")
messageToSendBytes := []byte(messageToSend)
+ // get the longest prefix match for the destination
hop, err := ipstack.LongestPrefix(netip.MustParseAddr(ipAddr))
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 == netip.MustParseAddr(ipAddr) ||
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)
@@ -91,11 +99,22 @@ func main() {
}
}
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
}
diff --git a/lnxfiles/doc-example/binaries.example.json b/lnxfiles/doc-example/binaries.example.json
new file mode 100644
index 0000000..b6ff6d9
--- /dev/null
+++ b/lnxfiles/doc-example/binaries.example.json
@@ -0,0 +1,17 @@
+{
+ "h1": {
+ "binary_path": "./vhost"
+ },
+ "h2": {
+ "binary_path": "./vhost"
+ },
+ "h3": {
+ "binary_path": "./vhost"
+ },
+ "r1": {
+ "binary_path": "./vrouter"
+ },
+ "r2": {
+ "binary_path": "./vrouter"
+ }
+} \ No newline at end of file
diff --git a/lnxfiles/doc-example/nodes.json b/lnxfiles/doc-example/nodes.json
new file mode 100644
index 0000000..7b91355
--- /dev/null
+++ b/lnxfiles/doc-example/nodes.json
@@ -0,0 +1,7 @@
+{
+ "h1": "host",
+ "h2": "host",
+ "h3": "host",
+ "r1": "router",
+ "r2": "router"
+} \ No newline at end of file
diff --git a/lnxfiles/loop/binaries.example.json b/lnxfiles/loop/binaries.example.json
new file mode 100644
index 0000000..3d0d853
--- /dev/null
+++ b/lnxfiles/loop/binaries.example.json
@@ -0,0 +1,23 @@
+{
+ "h1": {
+ "binary_path": "./vhost"
+ },
+ "h2": {
+ "binary_path": "./vhost"
+ },
+ "r1": {
+ "binary_path": "./vrouter"
+ },
+ "r2": {
+ "binary_path": "./vrouter"
+ },
+ "r3": {
+ "binary_path": "./vrouter"
+ },
+ "r4": {
+ "binary_path": "./vrouter"
+ },
+ "r5": {
+ "binary_path": "./vrouter"
+ }
+} \ No newline at end of file
diff --git a/lnxfiles/loop/nodes.json b/lnxfiles/loop/nodes.json
new file mode 100644
index 0000000..2829f76
--- /dev/null
+++ b/lnxfiles/loop/nodes.json
@@ -0,0 +1,9 @@
+{
+ "h1": "host",
+ "h2": "host",
+ "r1": "router",
+ "r2": "router",
+ "r3": "router",
+ "r4": "router",
+ "r5": "router"
+} \ No newline at end of file
diff --git a/lnxfiles/r1h2/binaries.example.json b/lnxfiles/r1h2/binaries.example.json
new file mode 100644
index 0000000..1888a6b
--- /dev/null
+++ b/lnxfiles/r1h2/binaries.example.json
@@ -0,0 +1,11 @@
+{
+ "h1": {
+ "binary_path": "./vhost"
+ },
+ "h2": {
+ "binary_path": "./vhost"
+ },
+ "r1": {
+ "binary_path": "./vrouter"
+ }
+} \ No newline at end of file
diff --git a/lnxfiles/r1h2/nodes.json b/lnxfiles/r1h2/nodes.json
new file mode 100644
index 0000000..6accf5f
--- /dev/null
+++ b/lnxfiles/r1h2/nodes.json
@@ -0,0 +1,5 @@
+{
+ "h1": "host",
+ "h2": "host",
+ "r1": "router"
+} \ No newline at end of file
diff --git a/lnxfiles/r1h4/binaries.example.json b/lnxfiles/r1h4/binaries.example.json
new file mode 100644
index 0000000..81dd521
--- /dev/null
+++ b/lnxfiles/r1h4/binaries.example.json
@@ -0,0 +1,17 @@
+{
+ "h1": {
+ "binary_path": "./vhost"
+ },
+ "h2": {
+ "binary_path": "./vhost"
+ },
+ "h3": {
+ "binary_path": "./vhost"
+ },
+ "h4": {
+ "binary_path": "./vhost"
+ },
+ "r1": {
+ "binary_path": "./vrouter"
+ }
+} \ No newline at end of file
diff --git a/lnxfiles/r1h4/nodes.json b/lnxfiles/r1h4/nodes.json
new file mode 100644
index 0000000..1927005
--- /dev/null
+++ b/lnxfiles/r1h4/nodes.json
@@ -0,0 +1,7 @@
+{
+ "h1": "host",
+ "h2": "host",
+ "h3": "host",
+ "h4": "host",
+ "r1": "router"
+} \ No newline at end of file
diff --git a/lnxfiles/r2h2/binaries.example.json b/lnxfiles/r2h2/binaries.example.json
new file mode 100644
index 0000000..59223ba
--- /dev/null
+++ b/lnxfiles/r2h2/binaries.example.json
@@ -0,0 +1,14 @@
+{
+ "h1": {
+ "binary_path": "./vhost"
+ },
+ "h2": {
+ "binary_path": "./vhost"
+ },
+ "r1": {
+ "binary_path": "./vrouter"
+ },
+ "r2": {
+ "binary_path": "./vrouter"
+ }
+} \ No newline at end of file
diff --git a/lnxfiles/r2h2/nodes.json b/lnxfiles/r2h2/nodes.json
new file mode 100644
index 0000000..282ab86
--- /dev/null
+++ b/lnxfiles/r2h2/nodes.json
@@ -0,0 +1,6 @@
+{
+ "h1": "host",
+ "h2": "host",
+ "r1": "router",
+ "r2": "router"
+} \ No newline at end of file
diff --git a/lnxfiles/r3h2/binaries.example.json b/lnxfiles/r3h2/binaries.example.json
new file mode 100644
index 0000000..9079242
--- /dev/null
+++ b/lnxfiles/r3h2/binaries.example.json
@@ -0,0 +1,17 @@
+{
+ "h1": {
+ "binary_path": "./vhost"
+ },
+ "h2": {
+ "binary_path": "./vhost"
+ },
+ "r1": {
+ "binary_path": "./vrouter"
+ },
+ "r2": {
+ "binary_path": "./vrouter"
+ },
+ "r3": {
+ "binary_path": "./vrouter"
+ }
+} \ No newline at end of file
diff --git a/lnxfiles/r3h2/nodes.json b/lnxfiles/r3h2/nodes.json
new file mode 100644
index 0000000..27ea8c5
--- /dev/null
+++ b/lnxfiles/r3h2/nodes.json
@@ -0,0 +1,7 @@
+{
+ "h1": "host",
+ "h2": "host",
+ "r1": "router",
+ "r2": "router",
+ "r3": "router"
+} \ No newline at end of file
diff --git a/lnxfiles/vhost b/lnxfiles/vhost
new file mode 100755
index 0000000..b240f26
--- /dev/null
+++ b/lnxfiles/vhost
Binary files differ
diff --git a/lnxfiles/vrouter b/lnxfiles/vrouter
new file mode 100755
index 0000000..c89f6fe
--- /dev/null
+++ b/lnxfiles/vrouter
Binary files differ
diff --git a/pkg/ipstack/ipstack.go b/pkg/ipstack/ipstack.go
index 030b9c7..e3d9ca2 100644
--- a/pkg/ipstack/ipstack.go
+++ b/pkg/ipstack/ipstack.go
@@ -12,8 +12,6 @@ import (
"net/netip"
"sync"
"time"
- // "bytes"
- // "unicode"
)
const (
@@ -23,9 +21,9 @@ const (
MaxEntries = 64
INFINITY = 16
SIZE_OF_RIP_ENTRY = 12
- SIZE_OF_RIP_MESSAGE = 6
RIP_PROTOCOL = 200
TEST_PROTOCOL = 0
+ SIZE_OF_RIP_HEADER = 4
)
// STRUCTS ---------------------------------------------------------------------
@@ -64,8 +62,8 @@ type Hop struct {
}
// GLOBAL VARIABLES (data structures) ------------------------------------------
-var myVIP Interface
var myInterfaces []*Interface
+
var myNeighbors = make(map[string][]*Neighbor)
var myRIPNeighbors = make(map[string]*Neighbor)
@@ -78,6 +76,8 @@ var routingTable = make(map[netip.Prefix]Hop)
// ************************************** INIT FUNCTIONS **********************************************************
// reference: https://github.com/brown-csci1680/lecture-examples/blob/main/ip-demo/cmd/udp-ip-recv/main.go
+
+// createUDPListener creates a UDP listener.
func createUDPListener(UdpAddr netip.AddrPort, conn *net.UDPConn) error {
listenString := UdpAddr.String()
listenAddr, err := net.ResolveUDPAddr("udp4", listenString)
@@ -93,6 +93,7 @@ func createUDPListener(UdpAddr netip.AddrPort, conn *net.UDPConn) error {
return nil
}
+// initialize parse the lnxfile and initializes the data structures and listener routines
func Initialize(lnxFilePath string) error {
// Parse the file
lnxConfig, err := lnxconfig.ParseConfig(lnxFilePath)
@@ -100,7 +101,7 @@ func Initialize(lnxFilePath string) error {
return errors.WithMessage(err, "Error parsing config file->\t"+lnxFilePath)
}
- // 1) add each local if to the routing table, as dictated by its subnet
+ // 1) add each local "if" to the routing table, as dictated by its subnet
for _, iface := range lnxConfig.Interfaces {
prefix := netip.PrefixFrom(iface.AssignedIP, iface.AssignedPrefix.Bits())
i := &Interface{
@@ -111,16 +112,20 @@ func Initialize(lnxFilePath string) error {
SocketChannel: make(chan bool),
State: true,
}
- // Added this for printing purposes for REPL FYI, if you have a better way lmk
+ // create the UDP listener
err := createUDPListener(iface.UDPAddr, &i.RecvSocket)
if err != nil {
return errors.WithMessage(err, "Error creating UDP socket for interface->\t"+iface.Name)
}
+ // start the listener routine
go InterfaceListenerRoutine(i)
+
+ // add to the list of interfaces
myInterfaces = append(myInterfaces, i)
+ // add to the routing table
routingTable[prefix.Masked()] = Hop{LOCAL_COST, "L", i, prefix.Addr()}
}
@@ -162,10 +167,10 @@ func Initialize(lnxFilePath string) error {
}
}
- // add protocol handlers
return nil
}
+// defines the go routine that listens on the UDP socket
func InterfaceListenerRoutine(i *Interface) {
// decompose the interface
socket := i.RecvSocket
@@ -175,8 +180,9 @@ func InterfaceListenerRoutine(i *Interface) {
isUp := true
closed := false
- // go routine that hangs on the recv
// fmt.Println("MAKING GO ROUTINE TO LISTEN:\t", socket.LocalAddr().String())
+
+ // go routine that hangs on the recv
go func() {
defer func() {
fmt.Println("exiting go routine that listens on ", socket.LocalAddr().String())
@@ -193,7 +199,6 @@ func InterfaceListenerRoutine(i *Interface) {
// time.Sleep(1 * time.Millisecond)
err := RecvIP(i, &isUp)
if err != nil {
- // fmt.Println("Error receiving IP packet", err)
continue
}
}
@@ -201,6 +206,7 @@ func InterfaceListenerRoutine(i *Interface) {
for {
select {
+ // if the channel is closed, exit
case sig, ok := <-signal:
if !ok {
fmt.Println("channel closed, exiting")
@@ -209,6 +215,7 @@ func InterfaceListenerRoutine(i *Interface) {
}
// fmt.Println("received isUP SIGNAL with value", sig)
isUp = sig
+ // if the channel is not closed, continue
default:
continue
}
@@ -217,7 +224,9 @@ func InterfaceListenerRoutine(i *Interface) {
// ************************************** DOWN/UP FUNCTIONS ******************************************************
+// sets the interface to be up and sends a triggered update
func InterfaceUp(iface *Interface) {
+ // set the state to up and send the signal
iface.State = true
iface.SocketChannel <- true
@@ -246,12 +255,13 @@ func InterfaceUpREPL(ifaceName string) {
fmt.Println("Error getting interface by name", err)
return
}
+ // set the state to up and send the signal
InterfaceUp(iface)
}
-// we could do either of these but the REPL results in less work done in router and host
-
+// sets the interface to be down and sends a triggered update
func InterfaceDown(iface *Interface) {
+ // set the state to down and send the signal
iface.SocketChannel <- false
iface.State = false
@@ -269,6 +279,7 @@ func InterfaceDownREPL(ifaceName string) {
fmt.Println("Error getting interface by name", err)
return
}
+ // set the state to down and send the signal
InterfaceDown(iface)
}
@@ -283,31 +294,6 @@ func GetInterfaceByName(ifaceName string) (*Interface, error) {
return nil, errors.Errorf("No interface with name %s", ifaceName)
}
-func GetNeighborByIP(ipAddr string) (*Neighbor, error) {
- // iterate through the neighbors and return the one with the same ipAddr
- for _, neighbors := range myNeighbors {
- for _, neighbor := range neighbors {
- if neighbor.VipAddr.String() == ipAddr {
- return neighbor, nil
- }
- }
- }
-
- return nil, errors.Errorf("No interface with ip %s", ipAddr)
-}
-
-func GetNeighborsToInterface(ifaceName string) ([]*Neighbor, error) {
- if neighbors, ok := myNeighbors[ifaceName]; ok {
- return neighbors, nil
- }
-
- return nil, errors.Errorf("No interface with name %s", ifaceName)
-}
-
-func GetMyVIP() Interface {
- return myVIP
-}
-
func GetInterfaces() []*Interface {
return myInterfaces
}
@@ -322,22 +308,27 @@ func GetRoutes() map[netip.Prefix]Hop {
// ************************************** PRINT FUNCTIONS **********************************************************
+// returns a string representation of the myInterfaces data structure
func SprintInterfaces() string {
tmp := ""
for _, iface := range myInterfaces {
if iface.State {
+ // if the state is up, print UP
tmp += fmt.Sprintf("%s\t%s\t%s\n", iface.Name, iface.IpPrefix.String(), "UP")
} else {
+ // if the state is down, print DOWN
tmp += fmt.Sprintf("%s\t%s\t%s\n", iface.Name, iface.IpPrefix.String(), "DOWN")
}
}
return tmp
}
+// returns a string representation of the myNeighbors data structure
func SprintNeighbors() string {
tmp := ""
for _, iface := range myInterfaces {
if !iface.State {
+ // if the interface is down, skip it
continue
}
for _, n := range myNeighbors[iface.Name] {
@@ -347,12 +338,15 @@ func SprintNeighbors() string {
return tmp
}
+// returns a string representation of the routingTable data structure
func SprintRoutingTable() string {
tmp := ""
for prefix, hop := range routingTable {
if hop.Type == "L" {
- tmp += fmt.Sprintf("%s\t%s\tLOCAL:%s\t%d\n", hop.Type, prefix.String(), hop.Interface.Name, 0)
+ // if the hop is local, print LOCAL
+ tmp += fmt.Sprintf("%s\t%s\tLOCAL:%s\t%d\n", hop.Type, prefix.String(), hop.Interface.Name, hop.Cost)
} else if hop.Type == "S" {
+ // if the hop is static, don't print the cost
tmp += fmt.Sprintf("%s\t%s\t%s\t%s\n", hop.Type, prefix.String(), hop.VIP.String(), "-")
} else {
tmp += fmt.Sprintf("%s\t%s\t%s\t%d\n", hop.Type, prefix.String(), hop.VIP.String(), hop.Cost)
@@ -363,13 +357,17 @@ func SprintRoutingTable() string {
// ************************************** BASIC FUNCTIONS **********************************************************
+// cleans up the data structures and closes the UDP sockets
func CleanUp() {
fmt.Print("Cleaning up...\n")
+
// go through the interfaces, pop thread & close the UDP FDs
for _, iface := range myInterfaces {
+ // close the channel
if iface.SocketChannel != nil {
close(iface.SocketChannel)
}
+ // close the UDP FD
err := iface.RecvSocket.Close()
if err != nil {
continue
@@ -386,13 +384,14 @@ func CleanUp() {
time.Sleep(5 * time.Millisecond)
}
-// TODO: have it take TTL so we can decrement it when forwarding
+// SendIP sends an IP packet to a destination
func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, destIP string, hdr *ipv4header.IPv4Header) (int, error) {
+ // check if the interface is up
iface, err := GetInterfaceByName(dest.Name)
if !iface.State {
return -1, errors.Errorf("error SEND: %s is down", iface.Name)
}
-
+ // if the header is nil, create a new one
if hdr == nil {
hdr = &ipv4header.IPv4Header{
Version: 4,
@@ -410,6 +409,7 @@ func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, de
Options: []byte{},
}
} else {
+ // if the header is not nil, decrement the TTL
hdr = &ipv4header.IPv4Header{
Version: 4,
Len: 20, // Header length is always 20 when no IP options
@@ -448,13 +448,10 @@ func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, de
bytesToSend = append(bytesToSend, []byte(message)...)
sendAddr, err := net.ResolveUDPAddr("udp4", dest.UdpAddr.String())
- // tmpConn, err := net.DialUDP("udp4", nil, sendAddr)
- // get the interface of this neighbor
if err != nil {
return -1, errors.WithMessage(err, "Could not bind to UDP port->\t"+dest.UdpAddr.String())
}
- // bytesWritten, err := tmpConn.Write(bytesToSend)
// TODO: make this faster by removing call
bytesWritten, err := iface.RecvSocket.WriteToUDP(bytesToSend, sendAddr)
if err != nil {
@@ -465,33 +462,31 @@ func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, de
return bytesWritten, nil
}
+
+// RecvIP receives an IP packet from a source
func RecvIP(iface *Interface, isOpen *bool) error {
- buffer := make([]byte, MAX_IP_PACKET_SIZE) // TODO: fix wordking
+ buffer := make([]byte, MAX_IP_PACKET_SIZE) // TODO: fix wording
// Read on the UDP port
- // Too much printing so I commented it out
// fmt.Println("wating to read from UDP socket")
_, _, err := iface.RecvSocket.ReadFromUDP(buffer)
if err != nil {
return err
}
+ // check if the interface is up
if !*isOpen {
return errors.Errorf("error RECV: %s is down", iface.Name)
}
// Marshal the received byte array into a UDP header
- // NOTE: This does not validate the checksum or check any fields
- // (You'll need to do this part yourself)
hdr, err := ipv4header.ParseHeader(buffer)
if err != nil {
- // What should you if the message fails to parse?
- // Your node should not crash or exit when you get a bad message.
- // Instead, simply drop the packet and return to processing.
fmt.Println("Error parsing header", err)
return err
}
+ // checksum validation
headerSize := hdr.Len
headerBytes := buffer[:headerSize]
checksumFromHeader := uint16(hdr.Checksum)
@@ -522,11 +517,13 @@ func RecvIP(iface *Interface, isOpen *bool) error {
return nil
}
- // at this point, the packet is valid. next steps consider the forwarding of the packet
- // 2) check if the message is for me, if so, sendUP (aka call the correct handler)
//if hdr.Protocol != RIP_PROTOCOL {
// fmt.Println("I see a non-rip packet")
//}
+
+ // at this point, the packet is valid. next steps consider the forwarding of the packet
+
+ // 2) check if the message is for me, if so, sendUP (aka call the correct handler)
for _, myIface := range myInterfaces {
if hdr.Dst == myIface.IpPrefix.Addr() {
// see if there is a handler for this protocol
@@ -589,8 +586,8 @@ func RecvIP(iface *Interface, isOpen *bool) error {
// ************************************** RIP Routines *******************************************************
+// creates a byte array that represents a RIP message
func makeRipMessage(command uint16, entries []RIPEntry) []byte {
- SIZE_OF_RIP_HEADER := 2 * 2 // 2 uint16s
if command == 1 { // request message
buf := make([]byte, SIZE_OF_RIP_HEADER)
binary.BigEndian.PutUint16(buf[0:2], command)
@@ -599,19 +596,23 @@ func makeRipMessage(command uint16, entries []RIPEntry) []byte {
}
// else, command == 2, response message
+ // create the buffer
bufLen := SIZE_OF_RIP_HEADER + // sizeof uint16 is 2, we have two of them
len(entries)*SIZE_OF_RIP_ENTRY // each entry is 12
buf := make([]byte, bufLen)
+ // fill in the header
binary.BigEndian.PutUint16(buf[0:2], command)
binary.BigEndian.PutUint16(buf[2:4], uint16(len(entries)))
+ // fill in the entries
for i, entry := range entries {
- offset := 2*2 + i*SIZE_OF_RIP_ENTRY
+ offset := SIZE_OF_RIP_HEADER + i*SIZE_OF_RIP_ENTRY
binary.BigEndian.PutUint32(buf[offset:offset+4], entry.cost) // 0-3 = 4 bytes
copy(buf[offset+4:offset+8], entry.prefix.Addr().AsSlice()) // 4-7 = 4 bytes
+ // convert the prefix to a uint32
ipv4Netmask := uint32(0xffffffff)
ipv4Netmask <<= 32 - entry.prefix.Bits()
binary.BigEndian.PutUint32(buf[offset+8:offset+12], ipv4Netmask)
@@ -620,6 +621,7 @@ func makeRipMessage(command uint16, entries []RIPEntry) []byte {
return buf
}
+
func periodicUpdateRoutine() {
for {
// for each periodic update, we want to send our nodes in the table
@@ -781,7 +783,7 @@ func RegisterProtocolHandler(protocolNum int) bool {
func handleRIP(src *Interface, dest *Neighbor, message []byte, hdr *ipv4header.IPv4Header) error {
// parse the RIP message
- SIZE_OF_RIP_HEADER := 2 * 2
+ // SIZE_OF_RIP_HEADER := 2 * 2
command := int(binary.BigEndian.Uint16(message[0:2]))
switch command {
case 1:
@@ -962,206 +964,4 @@ func LongestPrefix(src netip.Addr) (Hop, error) {
}
}
return Hop{}, errors.Errorf("No route to ip %s on table.", src)
-}
-
-//
-//func SendRIPMessage(src Interface, dest *Neighbor, message *RIPMessage) error {
-// hdr := ipv4header.IPv4Header{
-// Version: 4,
-// Len: 20, // Header length is always 20 when no IP options
-// TOS: 0,
-// TotalLen: ipv4header.HeaderLen + 4 + len(message.entries)*SIZE_OF_RIP_ENTRY,
-// ID: 0,
-// Flags: 0,
-// FragOff: 0,
-// TTL: 32,
-// Protocol: RIP_PROTOCOL,
-// Checksum: 0, // Should be 0 until checksum is computed
-// Src: src.IpPrefix.Addr(),
-// Dst: netip.MustParseAddr(dest.VipAddr.String()),
-// Options: []byte{},
-// }
-//
-// headerBytes, err := hdr.Marshal()
-// if err != nil {
-// return err
-// }
-//
-// hdr.Checksum = int(ComputeChecksum(headerBytes))
-//
-// headerBytes, err = hdr.Marshal()
-// if err != nil {
-// log.Fatalln("Error marshalling header: ", err)
-// }
-//
-// bytesToSend := make([]byte, 0)
-// bytesToSend = append(bytesToSend, headerBytes...)
-//
-// // make the RIP message
-// //buf := make([]byte, SIZE_OF_RIP_MESSAGE+len(message.entries)*SIZE_OF_RIP_ENTRY)
-// //buf[0] = message.command
-// //buf[1] = message.numEntries
-//
-// buf := make([]byte, 4)
-// binary.BigEndian.PutUint16(buf[0:2], message.command)
-// binary.BigEndian.PutUint16(buf[2:], message.numEntries)
-//
-// bytesToSend = append(bytesToSend, buf...)
-//
-// for _, entry := range message.entries {
-// // offset := SIZE_OF_RIP_MESSAGE + i*SIZE_OF_RIP_ENTRY
-// // each field is 4 bytes
-// buf := make([]byte, SIZE_OF_RIP_ENTRY)
-// binary.BigEndian.PutUint32(buf, entry.address) // 0-3 = 4 bytes
-// binary.BigEndian.PutUint32(buf[3:8], entry.mask) // 4-7 = 4 bytes
-// binary.BigEndian.PutUint32(buf[8:], entry.cost) // 8-11 = 4 bytes
-//
-// bytesToSend = append(bytesToSend, buf...)
-// }
-//
-// // send RIP message
-// sendAddr, err := net.ResolveUDPAddr("udp4", dest.UdpAddr.String())
-// // tmpConn, err := net.DialUDP("udp4", nil, sendAddr)
-// if err != nil {
-// return errors.WithMessage(err, "Could not bind to UDP port->\t"+dest.UdpAddr.String())
-// }
-//
-// iface, err := GetInterfaceByName(dest.Name)
-// //_, err = tmpConn.Write(bytesToSend)
-// _, err = iface.RecvSocket.WriteToUDP(bytesToSend, sendAddr)
-// if err != nil {
-// return err
-// }
-//
-// return nil
-//}
-
-//func RequestRip() {
-// // create RIP message
-// message := NewRIPMessage(1, []RIPEntry{})
-//
-// // send RIP message to RIP neighbors
-// for _, neighbors := range myNeighbors {
-// for _, neighbor := range neighbors {
-// // check if neighbor is RIP neighbor
-// // if not, continue
-// for _, ripNeighbor := range myRIPNeighbors {
-// if neighbor.VipAddr.String() == ripNeighbor.String() {
-// // send RIP message
-// err := SendRIPMessage(myVIP, neighbor, message)
-// if err != nil {
-// continue
-// }
-// }
-// }
-// continue
-// }
-// }
-//}
-//
-//func BroadcastPeriodicUpdates() {
-// // for each periodic update, we want to send our nodes in the table
-// entries := make([]RIPEntry, len(routingTable))
-// for prefix, hop := range routingTable {
-// entries = append(entries,
-// RIPEntry{
-// address: ConvertIPToUint32(prefix.Addr().String()),
-// mask: uint32(prefix.Bits()),
-// cost: hop.Cost,
-// })
-// }
-// message := NewRIPMessage(2, entries)
-//
-// // send to each neighbor
-// for _, iface := range myInterfaces {
-// for _, n := range myNeighbors[iface.Name] {
-// err := SendRIPMessage(*iface, n, message)
-// if err != nil {
-// fmt.Printf("Error sending RIP message to %s\n", n.VipAddr.String())
-// continue
-// }
-// }
-// }
-//
-//}
-
-//// THIS MIGHT BE WRONG...
-//func SendUpdates() {
-// entries := make([]RIPEntry, len(routingTable))
-// // create RIP entries from its interfaces to one another
-// for _, iface := range myInterfaces {
-// for _, iface2 := range myInterfaces {
-// if iface.Name == iface2.Name {
-// continue
-// }
-// // TODO @ MICHAEL: fix this
-// // hardcoded way to get cost to 0, fix if you want a better way
-// entry := &RIPEntry{
-// address: ConvertIPToUint32(iface2.IpPrefix.Addr().String()),
-// cost: 17,
-// mask: ConvertIPToUint32(iface.IpPrefix.Addr().String()),
-// }
-// entries = append(entries, *entry)
-//
-// entry = &RIPEntry{
-// address: ConvertIPToUint32(iface.IpPrefix.Addr().String()),
-// cost: 17,
-// mask: ConvertIPToUint32(iface2.IpPrefix.Addr().String()),
-// }
-// entries = append(entries, *entry)
-// }
-// }
-//
-// // create RIP entries from its neighbors
-// for _, neighbors := range myNeighbors {
-// for _, neighbor := range neighbors {
-// ipUint32 := ConvertIPToUint32(neighbor.VipAddr.String())
-// var neighborUint32 uint32
-// for _, interfaces := range myInterfaces {
-// if ifaceContainsIP(*interfaces, neighbor.VipAddr) {
-// neighborUint32 = ConvertIPToUint32(interfaces.IpPrefix.Addr().String())
-// break
-// }
-// }
-//
-// // create RIP entry
-// entry := &RIPEntry{
-// address: ipUint32,
-// cost: LOCAL_COST,
-// mask: neighborUint32,
-// }
-//
-// // add to entries and create RIP message
-// entries = append(entries, *entry)
-// message := NewRIPMessage(2, entries)
-//
-// // send RIP message
-// for _, Interfaces := range myInterfaces {
-// if Interfaces.Name == neighbor.Name {
-// err := SendRIPMessage(myVIP, neighbor, message)
-// if err != nil {
-// continue
-// }
-// }
-// }
-//
-// }
-// }
-//}
-
-// TODO @ MICHEAL: Handle links going down and link recovery
-// func CheckAndUpdateRoutingTable() {
-// for {
-// time.Sleep(12 * time.Second)
-// for prefix, hop := range routingTable {
-// // delete route if not refreshed in 12 seconds
-// // not sure if there is a better way to do this
-// if hop.Type == "R" {
-// delete(routingTable, prefix)
-// SendUpdates()
-// }
-// }
-// }
-// }
-
-// TODO @ MICHAEL: Triggered Updates and Split Horizon with Poisoned Reverse
+} \ No newline at end of file
diff --git a/vhost b/vhost
deleted file mode 100755
index 1d2d12f..0000000
--- a/vhost
+++ /dev/null
Binary files differ
diff --git a/vrouter b/vrouter
deleted file mode 100755
index 1329ee6..0000000
--- a/vrouter
+++ /dev/null
Binary files differ