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") // }