aboutsummaryrefslogtreecommitdiff
path: root/pkg/ipstack/ipstack_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/ipstack/ipstack_test.go')
-rw-r--r--pkg/ipstack/ipstack_test.go253
1 files changed, 253 insertions, 0 deletions
diff --git a/pkg/ipstack/ipstack_test.go b/pkg/ipstack/ipstack_test.go
new file mode 100644
index 0000000..941c4e9
--- /dev/null
+++ b/pkg/ipstack/ipstack_test.go
@@ -0,0 +1,253 @@
+package ipstack
+
+import (
+ "fmt"
+ ipv4header "github.com/brown-csci1680/iptcp-headers"
+ "net"
+ "net/netip"
+ "testing"
+ "time"
+)
+
+func TestInitialize(t *testing.T) {
+ lnxFilePath := "../../doc-example/r2.lnx"
+ err := Initialize(lnxFilePath)
+ if err != nil {
+ t.Error(err)
+ }
+ fmt.Printf("Interfaces:\n%s\n\n", SprintInterfaces())
+ fmt.Printf("Neighbors:\n%s\n", SprintNeighbors())
+ fmt.Printf("RoutingTable:\n%s\n", SprintRoutingTable())
+
+ fmt.Println("TestInitialize successful")
+ t.Cleanup(func() { CleanUp() })
+}
+
+func TestInterfaceUpThenDown(t *testing.T) {
+ lnxFilePath := "../../doc-example/r2.lnx"
+ err := Initialize(lnxFilePath)
+ if err != nil {
+ t.Error(err)
+ }
+
+ iface, err := GetInterfaceByName("if0")
+ if err != nil {
+ t.Error(err)
+ }
+
+ InterfaceUp(iface)
+ if iface.State == false {
+ t.Error("iface state should be true")
+ }
+
+ fmt.Printf("Interfaces:\n%s\n", SprintInterfaces())
+
+ time.Sleep(5 * time.Millisecond) // allow time to print
+
+ InterfaceDown(iface)
+ if iface.State == true {
+ t.Error("iface state should be false")
+ }
+
+ time.Sleep(5 * time.Millisecond) // allow time to print
+
+ fmt.Printf("Interfaces:\n%s\n", SprintInterfaces())
+
+ fmt.Println("TestInterfaceUpThenDown successful")
+ t.Cleanup(func() { CleanUp() })
+}
+
+func TestInterfaceUpThenDownTwice(t *testing.T) {
+ lnxFilePath := "../../doc-example/r2.lnx"
+ err := Initialize(lnxFilePath)
+ if err != nil {
+ t.Error(err)
+ }
+
+ iface, err := GetInterfaceByName("if0")
+ if err != nil {
+ t.Error(err)
+ }
+
+ InterfaceUp(iface)
+ if iface.State == false {
+ t.Error("iface state should be true")
+ }
+
+ fmt.Printf("Interfaces:\n%s\n", SprintInterfaces())
+
+ time.Sleep(5 * time.Millisecond) // allow time to print
+
+ fmt.Println("putting interface down")
+ InterfaceDown(iface)
+ if iface.State == true {
+ t.Error("iface state should be false")
+ }
+
+ time.Sleep(3 * time.Millisecond)
+
+ fmt.Println("putting interface back up for 3 iterations")
+ InterfaceUp(iface)
+ if iface.State == false {
+ t.Error("iface state should be true")
+ }
+ time.Sleep(3 * time.Millisecond) // allow time to print
+
+ fmt.Println("putting interface down")
+ InterfaceDown(iface)
+ if iface.State == true {
+ t.Error("iface state should be false")
+ }
+
+ time.Sleep(5 * time.Millisecond) // allow time to print
+
+ fmt.Printf("Interfaces:\n%s\n", SprintInterfaces())
+
+ fmt.Println("TestInterfaceUpThenDownTwice successful")
+ t.Cleanup(func() { CleanUp() })
+}
+
+func TestSendIPToNeighbor(t *testing.T) {
+ lnxFilePath := "../../doc-example/r2.lnx"
+ err := Initialize(lnxFilePath)
+ if err != nil {
+ t.Error(err)
+ }
+
+ // get the first neighbor of this interface
+ iface, err := GetInterfaceByName("if0")
+ if err != nil {
+ t.Error(err)
+ }
+ neighbors, err := GetNeighborsToInterface("if0")
+ if err != nil {
+ t.Error(err)
+ }
+
+ // setup a neighbor listener socket
+ testNeighbor := neighbors[0]
+ // close the socket so we can listen on it
+ err = testNeighbor.SendSocket.Close()
+ if err != nil {
+ t.Error(err)
+ }
+
+ fmt.Printf("Interfaces:\n%s\n", SprintInterfaces())
+ fmt.Printf("Neighbors:\n%s\n", SprintNeighbors())
+
+ listenString := testNeighbor.UdpAddr.String()
+ fmt.Println("listening on " + listenString)
+ listenAddr, err := net.ResolveUDPAddr("udp4", listenString)
+ if err != nil {
+ t.Error(err)
+ }
+ recvSocket, err := net.ListenUDP("udp4", listenAddr)
+ if err != nil {
+ t.Error(err)
+ }
+ testNeighbor.SendSocket = *recvSocket
+
+ sent := false
+ go func() {
+ buffer := make([]byte, MAX_IP_PACKET_SIZE)
+ fmt.Println("wating to read from UDP socket")
+ _, sourceAddr, err := recvSocket.ReadFromUDP(buffer)
+ if err != nil {
+ t.Error(err)
+ }
+ fmt.Println("read from UDP socket")
+ hdr, err := ipv4header.ParseHeader(buffer)
+ if err != nil {
+ t.Error(err)
+ }
+ headerSize := hdr.Len
+ headerBytes := buffer[:headerSize]
+ checksumFromHeader := uint16(hdr.Checksum)
+ computedChecksum := ValidateChecksum(headerBytes, checksumFromHeader)
+
+ var checksumState string
+ if computedChecksum == checksumFromHeader {
+ checksumState = "OK"
+ } else {
+ checksumState = "FAIL"
+ }
+ message := buffer[headerSize:]
+ fmt.Printf("Received IP packet from %s\nHeader: %v\nChecksum: %s\nMessage: %s\n",
+ sourceAddr.String(), hdr, checksumState, string(message))
+ if err != nil {
+ t.Error(err)
+ }
+
+ sent = true
+ }()
+
+ time.Sleep(10 * time.Millisecond)
+
+ // send a message to the neighbor
+ fmt.Printf("sending message to neighbor\t%t\n", sent)
+ err = SendIP(*iface, *testNeighbor, 0, []byte("You are my firest neighbor!"))
+ if err != nil {
+ t.Error(err)
+ }
+
+ fmt.Printf("SENT message to neighbor\t%t\n", sent)
+ // give a little time for the message to be sent
+ time.Sleep(1000 * time.Millisecond)
+ if !sent {
+ t.Error("Message not sent")
+ t.Fail()
+ }
+
+ fmt.Println("TestSendIPToNeighbor successful")
+ t.Cleanup(func() { CleanUp() })
+}
+
+func TestRecvIP(t *testing.T) {
+ lnxFilePath := "../../doc-example/r2.lnx"
+ err := Initialize(lnxFilePath)
+ if err != nil {
+ t.Error(err)
+ }
+
+ // get the first neighbor of this interface to RecvIP from
+ iface, err := GetInterfaceByName("if0")
+ if err != nil {
+ t.Error(err)
+ }
+ InterfaceUp(iface)
+
+ // setup a random socket to send an ip packet from
+ listenAddr, err := net.ResolveUDPAddr("udp4", "127.0.0.1:6969")
+ sendSocket, err := net.ListenUDP("udp4", listenAddr)
+
+ // send a message to the neighbor
+ ifaceAsNeighbor := Neighbor{
+ VipAddr: iface.IpPrefix.Addr(),
+ UdpAddr: iface.UdpAddr,
+ SendSocket: iface.RecvSocket,
+ SocketChannel: iface.SocketChannel,
+ }
+ fakeIface := Interface{
+ Name: "if69",
+ IpPrefix: netip.MustParsePrefix("10.69.0.1/24"),
+ UdpAddr: netip.MustParseAddrPort("127.0.0.1:6969"),
+ RecvSocket: net.UDPConn{},
+ SocketChannel: nil,
+ State: true,
+ }
+ err = SendIP(fakeIface, ifaceAsNeighbor, 0, []byte("hello"))
+ if err != nil {
+ return
+ }
+
+ time.Sleep(10 * time.Millisecond)
+
+ // TODO: potenially make this a channel, so it actually checks values.
+ // For now, you must read the message from the console.
+
+ err = sendSocket.Close()
+ if err != nil {
+ t.Error(err)
+ }
+ t.Cleanup(func() { CleanUp() })
+}