aboutsummaryrefslogtreecommitdiff
path: root/pkg/ipstack/ipstack.go
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2023-10-09 06:00:08 +0000
committersotech117 <michael_foiani@brown.edu>2023-10-09 06:00:08 +0000
commit077d576becae10b35b84782d4070fbf2f5c0b7c8 (patch)
tree26a7f4c4f0219cf87ea70a004550bf2736a29321 /pkg/ipstack/ipstack.go
parent4966c054b3f462f6eaf24591c4ab1a945e72bb6f (diff)
good progress, fixing almost all of the red. in the process of ensuring the data structures are initialized correctly.
Diffstat (limited to 'pkg/ipstack/ipstack.go')
-rw-r--r--pkg/ipstack/ipstack.go193
1 files changed, 121 insertions, 72 deletions
diff --git a/pkg/ipstack/ipstack.go b/pkg/ipstack/ipstack.go
index 770fd17..abaa09f 100644
--- a/pkg/ipstack/ipstack.go
+++ b/pkg/ipstack/ipstack.go
@@ -2,102 +2,147 @@ package ipstack
import (
"fmt"
- ipv4header "github.com/brown-csci1680/iptcp-headers"
- "github.com/google/netstack/tcpip/header"
"github.com/pkg/errors"
- "../../pkg/lnxconfig"
- "log"
+ "iptcp/pkg/lnxconfig"
"net"
"net/netip"
- "os"
)
const (
- MAX_IP_PACKET_SIZE = 1400
+ MAX_IP_PACKET_SIZE = 1400
+ LOCAL_COST uint32 = 4294967295 // 2^32 - 1
+ STATIC_COST uint32 = 1
)
+// STRUCTS ---------------------------------------------------------------------
type Interface struct {
- Name string
- AssignedIP netip.Addr
- AssignedPrefix netip.Prefix
+ Name string
+ IpAddress netip.Addr
+ IpPrefix netip.Prefix
- UDPAddr netip.AddrPort
- State bool
- neighbors map[netip.AddrPort]netip.AddrPort
+ RecvSocket net.Conn
+ SocketChannel chan<- bool
+ State bool
}
-// type Host struct {
-// Interface Interface
-// Neighbors []Neighbor
-// }
-
-// type Router struct {
-// Interfaces []Interface
-// Neighbors []Neighbor
-// RIPNeighbors []Neighbor
-// }
+type Neighbor struct {
+ VipAddr netip.Addr
+ UdpAddr netip.AddrPort
-
-type Neighbor struct{
- DestAddr netip.Addr
- UDPAddr netip.AddrPort
-
- InterfaceName string
+ SendSocket net.Conn
+ SocketChannel chan<- bool
}
type RIPMessage struct {
- command uint8_t;
- numEntries uint8_t;
- entries []RIPEntry;
+ command uint8
+ numEntries uint8
+ entries []RIPEntry
}
type RIPEntry struct {
- addr netip.Addr;
- cost uint16_t;
- mask netip.Prefix;
+ addr netip.Addr
+ cost uint32
+ mask netip.Prefix
}
-myInterfaces := make([]Interface);
-myNeighbors := make(map[string]Neighbor)
-myRIPNeighbors := make(map[string]Neighbor)
-protocolHandlers := make(map[uint16]HandlerFunc)
-// routingTable := make(map[Address]Routing)
+type Hop struct {
+ Cost uint32
+ VipAsStr string
+}
-func Initialize(config IpConfig) (error) {
- if len(os.Args) != 2 {
- fmt.Printf("Usage: %s <configFile>\n", os.Args[0])
- os.Exit(1)
+// GLOBAL VARIABLES (data structures) ------------------------------------------
+var myInterfaces []Interface
+var myNeighbors = make(map[string]Neighbor)
+
+// var myRIPNeighbors = make(map[string]Neighbor)
+type HandlerFunc func(int, string, *[]byte) error
+
+var protocolHandlers = make(map[uint16]HandlerFunc)
+
+// var routingTable = routingtable.New()
+var routingTable = make(map[netip.Prefix]Hop)
+
+// reference: https://github.com/brown-csci1680/lecture-examples/blob/main/ip-demo/cmd/udp-ip-recv/main.go
+func createUDPConn(UdpAddr netip.AddrPort, conn *net.Conn) error {
+ listenString := UdpAddr.String()
+ listenAddr, err := net.ResolveUDPAddr("udp4", listenString)
+ if err != nil {
+ return errors.WithMessage(err, "Error resolving address->\t"+listenString)
}
- fileName := os.Args[1]
+ tmpConn, err := net.ListenUDP("udp4", listenAddr)
+ if err != nil {
+ return errors.WithMessage(err, "Could not bind to UDP port->\t"+listenString)
+ }
+ *conn = tmpConn
+
+ return nil
+}
+
+func Initialize(lnxFilePath string) error {
+ //if len(os.Args) != 2 {
+ // fmt.Printf("Usage: %s <configFile>\n", os.Args[0])
+ // os.Exit(1)
+ //}
+ //lnxFilePath := os.Args[1]
// Parse the file
- lnxConfig, err := lnxconfig.ParseConfig(fileName)
+ lnxConfig, err := lnxconfig.ParseConfig(lnxFilePath)
if err != nil {
- panic(err)
+ return errors.WithMessage(err, "Error parsing config file->\t"+lnxFilePath)
}
- // populate routing table???
+ // 1) initialize the interfaces on this node here and into the routing table
for _, iface := range lnxConfig.Interfaces {
- myInterfaces = append(myInterfaces, Interface{iface.Name, iface.AssignedIP, iface.AssignedPrefix, iface.UDPAddr, 0})
+ i := &Interface{
+ Name: iface.Name,
+ IpAddress: iface.AssignedIP,
+ IpPrefix: iface.AssignedPrefix,
+ RecvSocket: nil,
+ SocketChannel: nil,
+ State: false,
+ }
+ err := createUDPConn(iface.UDPAddr, &i.RecvSocket)
+ if err != nil {
+ return errors.WithMessage(err, "Error creating UDP socket for interface->\t"+iface.Name)
+ }
+ myInterfaces = append(myInterfaces, *i)
+
+ // add to routing table
+ ifacePrefix := netip.PrefixFrom(iface.AssignedIP, iface.AssignedPrefix.Bits())
+ routingTable[ifacePrefix] = Hop{STATIC_COST, iface.Name}
}
+ // 2) initialize the neighbors connected to the node
for _, neighbor := range lnxConfig.Neighbors {
- myNeighbors[neighbor.DestAddr.String()] = Neighbor{neighbor.DestAddr, neighbor.UDPAddr, neighbor.InterfaceName}
- }
+ n := &Neighbor{
+ VipAddr: neighbor.DestAddr,
+ UdpAddr: neighbor.UDPAddr,
+ SendSocket: nil,
+ }
+ err := createUDPConn(neighbor.UDPAddr, &n.SendSocket)
+ if err != nil {
+ return errors.WithMessage(err, "Error creating UDP socket for neighbor->\t"+neighbor.DestAddr.String())
+ }
+ // TODO: make a hash map
+ myNeighbors[neighbor.InterfaceName] = *n
- // add RIP neighbors
- for _, neighbor := range lnxConfig.RipNeighbors {
- myRIPNeighbors[neighbor.DestAddr.String()] = Neighbor{neighbor.DestAddr, neighbor.UDPAddr, neighbor.InterfaceName}
+ // add to routing table
+ neighborPrefix := netip.PrefixFrom(neighbor.DestAddr, 24)
+ routingTable[neighborPrefix] = Hop{LOCAL_COST, neighbor.InterfaceName}
}
+
+ return nil
}
+/*
+
func ListerToInterfaces() {
for _, iface := range myInterfaces {
go RecvIp(iface)
}
}
-func RecvIp(iface Interface) (error) {
+func RecvIp(iface Interface) error {
for {
buffer := make([]byte, MAX_IP_PACKET_SIZE)
_, sourceAddr, err := iface.udp.ReadFrom(buffer)
@@ -125,7 +170,7 @@ func RecvIp(iface Interface) (error) {
checksumState = "FAIL"
continue
}
-
+
// check ttl
ttl := data[8]
if ttl == 0 {
@@ -133,7 +178,6 @@ func RecvIp(iface Interface) (error) {
continue
}
-
destAddr := netip.AddrFrom(data[16:20])
protocolNum := data[9]
@@ -174,7 +218,7 @@ func ValidateChecksum(b []byte, fromHeader uint16) uint16 {
return checksum
}
-func SendIp(dst netip.Addr, port uint16, protocolNum uint16, data []byte, iface Interface) (error) {
+func SendIp(dst netip.Addr, port uint16, protocolNum uint16, data []byte, iface Interface) error {
bindLocalAddr, err := net.ResolveUDPAddr("udp4", iface.UDPAddr.String())
if err != nil {
log.Panicln("Error resolving address: ", err)
@@ -248,15 +292,10 @@ func ComputeChecksum(b []byte) uint16 {
return checksumInv
}
-func ForwardIP(data []byte) (error) {
-}
-
-type HandlerFunc = func help(*Packet, []interface{}) (error) {
-
- // do smth with packet
+func ForwardIP(data []byte) error {
}
-func AddRecvHandler(protocolNum uint8, callbackFunc HandlerFunc) (error) {
+func AddRecvHandler(protocolNum uint8, callbackFunc HandlerFunc) error {
if protocolHandlers[protocolNum] != nil {
fmt.Printf("Warning: Handler for protocol %d already exists", protocolNum)
}
@@ -264,7 +303,7 @@ func AddRecvHandler(protocolNum uint8, callbackFunc HandlerFunc) (error) {
return nil
}
-func RemoveRecvHandler(protocolNum uint8) (error) {
+func RemoveRecvHandler(protocolNum uint8) error {
// consider error
if protocolHandlers[protocolNum] == nil {
return errors.Errorf("No handler for protocol %d", protocolNum)
@@ -281,18 +320,28 @@ func RemoveRecvHandler(protocolNum uint8) (error) {
// newRIPMessage.entries = make([]RIPEntry, newRIPMessage.numEntries)
// }
-func PrintNeighbors() {
- for _, iface := range myNeighbors {
- fmt.Printf("%s\n", iface.addr.String())
- }
+func GetNeighbors() []netip.Addr {
+ return myNeighbors
}
+*/
func PrintInterfaces() {
for _, iface := range myInterfaces {
- fmt.Printf("%s\n", iface.addr.String())
+ fmt.Printf("%s\t%s\t%t\n", iface.Name, iface.IpPrefix.String(), iface.State)
}
}
-func GetNeighbors() ([]netip.Addr) {
- return myNeighbors
+
+func PrintNeighbors() {
+ for ifaceName, neighbor := range myNeighbors {
+ fmt.Printf("%s\t%s\t%s\n", ifaceName, neighbor.IpAddress.String(), neighbor.UdpAddr.String())
+ }
}
+func SprintRoutingTable() string {
+ message := ""
+ for prefix, hop := range routingTable {
+ message += fmt.Sprintf("%s\t%s\t%d\n", prefix.String(), hop.VipAsStr, hop.Cost)
+ }
+
+ return message
+}