diff options
Diffstat (limited to 'pkg/tcpstack/tcpstack.go')
-rw-r--r-- | pkg/tcpstack/tcpstack.go | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/pkg/tcpstack/tcpstack.go b/pkg/tcpstack/tcpstack.go new file mode 100644 index 0000000..ec451a7 --- /dev/null +++ b/pkg/tcpstack/tcpstack.go @@ -0,0 +1,232 @@ +package tcpstack + +// import ( +// // "encoding/binary" +// "fmt" +// // "syscall" +// "iptcp/pkg/ipstack" +// // ipv4header "github.com/brown-csci1680/iptcp-headers" +// // tcpheader "github.com/brown-csci1680/iptcp-headers" +// "github.com/google/netstack/tcpip/header" +// "github.com/pkg/errors" +// "iptcp/pkg/iptcp_utils" +// // "log" +// // "net" +// "net/netip" +// // "sync" +// // "time" +// "math/rand" +// "sync" +// "strings" +// ) + +// type ConnectionState string +// const ( +// Established ConnectionState = "ESTABLISHED" +// Listening ConnectionState = "LISTENING" +// Closed ConnectionState = "CLOSED" +// SYNSENT ConnectionState = "SYNSENT" +// MAX_WINDOW_SIZE = 65535 +// ) + +// // VTCPListener represents a listener socket (similar to Go’s net.TCPListener) +// type VTCPListener struct { +// LocalAddr string +// LocalPort uint16 +// RemoteAddr string +// RemotePort uint16 +// Socket int +// State ConnectionState +// } + +// // // VTCPConn represents a “normal” socket for a TCP connection between two endpoints (similar to Go’s net.TCPConn) +// type VTCPConn struct { +// LocalAddr string +// LocalPort uint16 +// RemoteAddr string +// RemotePort uint16 +// Socket int +// State ConnectionState +// Buffer []byte +// } + +// type SocketEntry struct { +// Socket int +// LocalIP string +// LocalPort uint16 +// RemoteIP string +// RemotePort uint16 +// State ConnectionState +// } + +// // create a socket map to print the local and remote ip and port as well as the state of the socket +// var VHostSocketMaps = make(map[string]map[string]*SocketEntry) +// var mapMutex = &sync.Mutex{} +// var socketsMade = 0 +// var myIP = ipstack.GetInterfaces()[0].IpPrefix.Addr() + +// // Listen Sockets +// func VListen(port uint16) (*VTCPListener, error) { +// // get my ip address +// // myIP := ipstack.GetInterfaces()[0].IpPrefix.Addr() +// listener := &VTCPListener{ +// Socket: socketsMade, +// State: Listening, +// LocalPort: port, +// LocalAddr: myIP.String(), +// } + +// vhostMap, ok := VHostSocketMaps[myIP.String()] +// if !ok { +// vhostMap = make(map[string]*SocketEntry) +// VHostSocketMaps[fmt.Sprintf("%s:%d", "", port)] = vhostMap +// } +// // add the socket to the socket map +// mapMutex.Lock() +// vhostMap[fmt.Sprintf("%s:%d", "", port)] = &SocketEntry{ +// Socket: socketsMade, +// LocalIP: "0.0.0.0", +// LocalPort: port, +// RemoteIP: "0.0.0.0", +// RemotePort: 0, +// State: Listening, +// } +// mapMutex.Unlock() +// socketsMade += 1 +// return listener, nil + +// } + +// func (l *VTCPListener) VAccept() (*VTCPConn, error) { + +// for { +// // wait for a SYN request +// // if there is a SYN request, create a new socket, send a SYN-ACK response, and return the socket +// myInterface := ipstack.GetInterfaces()[0] +// err := ipstack.RecvIP(myInterface, nil) +// if err != nil { +// return nil, err +// } else { +// break +// } +// } +// socketsMade += 1 +// conn := &VTCPConn{ +// } + +// // add the socket to the socket map +// // mapMutex.Lock() + +// return conn, nil +// // create a new socket +// // return the socket +// } + +// func GetRandomPort() uint16 { +// const ( +// minDynamicPort = 49152 +// maxDynamicPort = 65535 +// ) +// return uint16(rand.Intn(maxDynamicPort - minDynamicPort) + minDynamicPort) +// } + +// func VConnect(ip string, port uint16) (*VTCPConn, error) { +// // get my ip address +// // myIP := ipstack.GetInterfaces()[0].IpPrefix.Addr() +// // get random port +// portRand := GetRandomPort() +// // Create a new VTCPConn. +// conn := &VTCPConn{ +// LocalAddr: myIP.String(), +// LocalPort: portRand, +// RemoteAddr: ip, +// RemotePort: port, +// Socket: socketsMade, +// State: SYNSENT, +// Buffer: []byte{}, +// } +// // get the socket entry from the socket map in the given port +// vhostMap, ok := VHostSocketMaps[ip] +// if !ok { +// return nil, errors.New("socket not found") +// } + +// socketEntry, ok := vhostMap[fmt.Sprintf("%s:%d", ip, port)] +// if !ok { +// return nil, errors.New("socket not found") +// } + +// // if the socket is closed, return an error +// if socketEntry.State == Closed { +// return nil, errors.New("socket is closed") +// } + +// // lookup neighbor +// neighbors := ipstack.GetNeighbors()[ipstack.GetInterfaces()[0].Name] +// var neighbor *ipstack.Neighbor +// for _, n := range neighbors { +// if n.VipAddr.String() == ip { +// neighbor = n +// } +// } + +// // Send SYN request. +// if socketEntry.State == Listening { +// tcpHdr := &header.TCPFields{ +// SrcPort: portRand, +// DstPort: port, +// SeqNum: 1, +// AckNum: 0, +// DataOffset: 20, +// Flags: header.TCPFlagSyn, +// WindowSize: MAX_WINDOW_SIZE, +// Checksum: 0, +// UrgentPointer: 0, +// } +// payload := []byte{} +// ipParsed, err := netip.ParseAddr(ip) +// if err != nil { +// return nil, err +// } +// checksum := iptcp_utils.ComputeTCPChecksum(tcpHdr, myIP, ipParsed, []byte{}) +// tcpHdr.Checksum = checksum + +// tcpHeaderBytes := make(header.TCP, iptcp_utils.TcpHeaderLen) +// tcpHeaderBytes.Encode(tcpHdr) + +// ipPacketPayload := make([]byte, 0, len(tcpHeaderBytes)+len(payload)) +// ipPacketPayload = append(ipPacketPayload, tcpHeaderBytes...) +// ipPacketPayload = append(ipPacketPayload, []byte(payload)...) + + +// _, err = ipstack.SendIP(&myIP, neighbor, 6, ipPacketPayload, ip, nil) +// if err != nil { +// return nil, err +// } +// } + +// // wait for a SYN-ACK response in the socket buffer +// myIPinterface := ipstack.GetInterfaces()[0] +// for { +// err := ipstack.RecvIP(myIPinterface, nil) +// if err != nil { +// return nil, err +// } else { +// break +// } +// } + +// return conn, nil +// } + +// func SprintSockets() string { +// var socketStrings []string +// // for _, socket := range SocketMap { +// // socketStrings = append(socketStrings, fmt.Sprintf("%d\t%s\t%d\t%s\t%d\t%s", socket.Socket, socket.LocalIP, socket.LocalPort, socket.RemoteIP, socket.RemotePort, socket.State)) +// // } +// // only print the sockets in the map with myIP as the key +// for _, socket := range VHostSocketMaps[myIP.String()] { +// socketStrings = append(socketStrings, fmt.Sprintf("%d\t%s\t%d\t%s\t%d\t%s", socket.Socket, socket.LocalIP, socket.LocalPort, socket.RemoteIP, socket.RemotePort, socket.State)) +// } +// return strings.Join(socketStrings, "\t") +// }
\ No newline at end of file |