aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go.mod8
-rw-r--r--go.sum8
-rw-r--r--pkg/protocol.go226
3 files changed, 186 insertions, 56 deletions
diff --git a/go.mod b/go.mod
index 73b8244..9654e0e 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,10 @@ module golang-sockets
go 1.20
-require github.com/pkg/errors v0.9.1 // indirect \ No newline at end of file
+require (
+ github.com/brown-csci1680/ipstack-utils v0.0.0-20231005044334-c7ffd5865555 // indirect
+ github.com/brown-csci1680/iptcp-headers v0.0.0-20230924161227-ebbbbba41fe3 // indirect
+ github.com/google/btree v1.1.2 // indirect
+ github.com/google/netstack v0.0.0-20191123085552-55fcc16cd0eb // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+)
diff --git a/go.sum b/go.sum
index 7c401c3..df151ff 100644
--- a/go.sum
+++ b/go.sum
@@ -1,2 +1,10 @@
+github.com/brown-csci1680/ipstack-utils v0.0.0-20231005044334-c7ffd5865555 h1:kwaT/pW/qygqaZK16BjBAFOPPGUr7KIrFgHP0+bSDvQ=
+github.com/brown-csci1680/ipstack-utils v0.0.0-20231005044334-c7ffd5865555/go.mod h1:UHyYaYk+dy6gEgdRmqsGYMD8BneHZssv9fwFxpcWCW0=
+github.com/brown-csci1680/iptcp-headers v0.0.0-20230924161227-ebbbbba41fe3 h1:PUo5fMism8wbu7tzkPfZ0ct67Cku+7/yl3R91O4Kdnk=
+github.com/brown-csci1680/iptcp-headers v0.0.0-20230924161227-ebbbbba41fe3/go.mod h1:2h3+zpHmxlxasdarUy1VdGdmsjPNxA2/ONaOfBglInY=
+github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
+github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
+github.com/google/netstack v0.0.0-20191123085552-55fcc16cd0eb h1:/YcrD0GSdU5gtckXHVjSEd0Y6VgboNW7VYyImZS3y6g=
+github.com/google/netstack v0.0.0-20191123085552-55fcc16cd0eb/go.mod h1:r/rILWg3r1Qy9G1IFMhsqWLq2GjwuYoTuPgG7ckMAjk=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
diff --git a/pkg/protocol.go b/pkg/protocol.go
index 10cf058..9358099 100644
--- a/pkg/protocol.go
+++ b/pkg/protocol.go
@@ -7,7 +7,10 @@ import (
"os"
"bufio"
"time"
- "github.com/brown-cs1680-f23/iptcp-jailpt2/pkg/lnxconfig"
+ "github.com/pkg/errors"
+ ipv4header "github.com/brown-csci1680/iptcp-headers"
+ "github.com/google/netstack/tcpip/header"
+ "github.com/brown-csci1680/ipstack-utils"
)
const (
@@ -21,8 +24,20 @@ type Interface struct {
UDPAddr netip.AddrPort
State uint8_t
+ neighbors map[netip.AddrPort]netip.AddrPort
}
+// type Host struct {
+// Interface Interface
+// Neighbors []Neighbor
+// }
+
+// type Router struct {
+// Interfaces []Interface
+// Neighbors []Neighbor
+// RIPNeighbors []Neighbor
+// }
+
type Neighbor struct{
DestAddr netip.Addr
@@ -62,7 +77,7 @@ func Initialize(config IpConfig) (error) {
panic(err)
}
- // populate routing table
+ // populate routing table???
for _, iface := range lnxConfig.Interfaces {
myInterfaces = append(myInterfaces, Interface{iface.Name, iface.AssignedIP, iface.AssignedPrefix, iface.UDPAddr, 0})
}
@@ -77,63 +92,164 @@ func Initialize(config IpConfig) (error) {
}
}
-func RecvIp(data []byte) (error) {
- // deconstruct packet
+func ListerToInterfaces() {
+ for _, iface := range myInterfaces {
+ go RecvIp(iface)
+ }
+}
+
+func RecvIp(iface Interface) (error) {
+ for {
+ buffer := make([]byte, MAX_IP_PACKET_SIZE)
+ _, sourceAddr, err := iface.udp.ReadFrom(buffer)
+ if err != nil {
+ log.Panicln("Error reading from UDP socket ", err)
+ }
+
+ hdr, err := ipv4header.ParseHeader(buffer)
+
+ if err != nil {
+ fmt.Println("Error parsing header", err)
+ continue
+ }
+
+ 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"
+ continue
+ }
+
+ // check ttl
+ ttl := data[8]
+ if ttl == 0 {
+ fmt.Println("TTL is 0")
+ continue
+ }
+
+
+ destAddr := netip.AddrFrom(data[16:20])
+ protocolNum := data[9]
+
+ if destAddr == iface.addr {
+ // send to handler
+ protocolHandlers[protocolNum](data)
+ // message := buffer[headerSize:]
+
+ // fmt.Printf("Received IP packet from %s\nHeader: %v\nChecksum: %s\nMessage: %s\n",
+ // sourceAddr.String(), hdr, checksumState, string(message))
+ } else {
+ // decrement ttl and update checksum
+ data[8] = ttl - 1
+ data[10] = 0
+ data[11] = 0
+ newChecksum := int(ComputeChecksum(data[:headerSize]))
+ data[10] = newChecksum >> 8
+ data[11] = newChecksum & 0xff
+
+ // check neighbors
+ for _, neighbor := range iface.neighbors {
+ if neighbor == destAddr {
+ // send to neighbor
+ // SendIp(destAddr, protocolNum, data)
+ }
+ }
+
+ // check forwarding table
+
+ }
+
+ }
+}
+
+func ValidateChecksum(b []byte, fromHeader uint16) uint16 {
+ checksum := header.Checksum(b, fromHeader)
+
+ return checksum
+}
- // check ip checksum
- checksum := netip.Checksum(data)
- if checksum != 0 {
- return errors.Errorf("Checksum failed: %d", checksum)
+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)
}
- // check ttl
- ttl := data[8]
- if ttl == 0 {
- return errors.Errorf("TTL is 0")
+ addrString := fmt.Sprintf("%s:%s", dst, port)
+ remoteAddr, err := net.ResolveUDPAddr("udp4", addrString)
+ if err != nil {
+ log.Panicln("Error resolving address: ", err)
}
- destAddr := netip.AddrFrom(data[16:20])
- protocolNum := data[9]
+ fmt.Printf("Sending to %s:%d\n",
+ remoteAddr.IP.String(), remoteAddr.Port)
- // decrement ttl and update checksum
- data[8] = ttl - 1
- data[10] = 0
- data[11] = 0
- newChecksum := netip.Checksum(data)
- data[10] = newChecksum >> 8
- data[11] = newChecksum & 0xff
+ // Bind on the local UDP port: this sets the source port
+ // and creates a conn
+ conn, err := net.ListenUDP("udp4", bindLocalAddr)
+ if err != nil {
+ log.Panicln("Dial: ", err)
+ }
- SendIp(destAddr, protocolNum, data)
-}
+ // Start filling in the header
+ message := data[20:]
+ hdr := ipv4header.IPv4Header{
+ Version: data[0] >> 4,
+ Len: 20, // Header length is always 20 when no IP options
+ TOS: data[1],
+ TotalLen: ipv4header.HeaderLen + len(message),
+ ID: data[4],
+ Flags: data[6] >> 5,
+ FragOff: data[6] & 0x1f,
+ TTL: data[8],
+ Protocol: data[9],
+ Checksum: 0, // Should be 0 until checksum is computed
+ Src: netip.MustParseAddr(iface.addr.String()),
+ Dst: netip.MustParseAddr(dst.String()),
+ Options: []byte{},
+ }
-func SendIp(dst netip.Addr, protocolNum uint16, data []byte) (error) {
- // check if dst is local
- islocal := false
- for _, iface := range myNeighbors {
- if iface.addr == dst {
- islocal = true
- break
- }
+ // Assemble the header into a byte array
+ headerBytes, err := hdr.Marshal()
+ if err != nil {
+ log.Fatalln("Error marshalling header: ", err)
}
- if islocal {
- // send to local handler
- protocolHandlers[protocolNum](data)
- } else {
- // send to forwarding table
- // lookup forwarding table
- // toHop, err := lookupForwardingTable(dst)
- // if err != nil {
- // routeRip()
- // }
+ // Compute the checksum (see below)
+ // Cast back to an int, which is what the Header structure expects
+ hdr.Checksum = int(ComputeChecksum(headerBytes))
- // // send to toHop interface
- // for _, iface := range myInterfaces {
- // if iface.addr == toHop {
- // iface.udp.Write(data)
- // break
- // }
- // }
+ headerBytes, err = hdr.Marshal()
+ if err != nil {
+ log.Fatalln("Error marshalling header: ", err)
+ }
+
+ bytesToSend := make([]byte, 0, len(headerBytes)+len(message))
+ bytesToSend = append(bytesToSend, headerBytes...)
+ bytesToSend = append(bytesToSend, []byte(message)...)
+
+ // Send the message to the "link-layer" addr:port on UDP
+ bytesWritten, err := conn.WriteToUDP(bytesToSend, remoteAddr)
+ if err != nil {
+ log.Panicln("Error writing to socket: ", err)
+ }
+ fmt.Printf("Sent %d bytes\n", bytesWritten)
+}
+
+func ComputeChecksum(b []byte) uint16 {
+ checksum := header.Checksum(b, 0)
+ checksumInv := checksum ^ 0xffff
+
+ return checksumInv
+}
+
+func ForwardIP(data []byte) (error) {
}
type HandlerFunc = func help(*Packet, []interface{}) (error) {
@@ -158,13 +274,13 @@ func RemoveRecvHandler(protocolNum uint8) (error) {
return nil
}
-func routeRip(data []byte) (error) {
- // deconstruct packet
- newRIPMessage := RIPMessage{}
- newRIPMessage.command = data[0]
- newRIPMessage.numEntries = data[1]
- newRIPMessage.entries = make([]RIPEntry, newRIPMessage.numEntries)
-}
+// func routeRip(data []byte) (error) {
+// // deconstruct packet
+// newRIPMessage := RIPMessage{}
+// newRIPMessage.command = data[0]
+// newRIPMessage.numEntries = data[1]
+// newRIPMessage.entries = make([]RIPEntry, newRIPMessage.numEntries)
+// }
func PrintNeighbors() {
for _, iface := range myNeighbors {