github.com/jspc/eggos@v0.5.1-0.20221028160421-556c75c878a5/inet/socket.go (about) 1 package inet 2 3 import ( 4 "syscall" 5 6 "github.com/jspc/eggos/kernel/isyscall" 7 8 "gvisor.dev/gvisor/pkg/tcpip" 9 "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" 10 "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" 11 "gvisor.dev/gvisor/pkg/tcpip/transport/udp" 12 "gvisor.dev/gvisor/pkg/waiter" 13 ) 14 15 func sysSocket(c *isyscall.Request) { 16 domain := c.Arg(0) 17 typ := c.Arg(1) 18 // proto := c.Arg(2) 19 if domain != syscall.AF_INET { 20 c.SetErrorNO(syscall.EINVAL) 21 return 22 } 23 if typ&syscall.SOCK_STREAM == 0 && typ&syscall.SOCK_DGRAM == 0 { 24 c.SetErrorNO(syscall.EINVAL) 25 return 26 } 27 28 var protoNum tcpip.TransportProtocolNumber 29 switch { 30 case typ&syscall.SOCK_STREAM != 0: 31 protoNum = tcp.ProtocolNumber 32 case typ&syscall.SOCK_DGRAM != 0: 33 protoNum = udp.ProtocolNumber 34 default: 35 panic(typ) 36 } 37 38 wq := new(waiter.Queue) 39 ep, err := nstack.NewEndpoint(protoNum, ipv4.ProtocolNumber, wq) 40 if err != nil { 41 c.SetError(e(err)) 42 return 43 } 44 45 sfile := allocSockFile(ep, wq) 46 c.SetRet(uintptr(sfile.fd)) 47 48 } 49 50 func sysListen(c *isyscall.Request) { 51 sf, err := findSockFile(c.Arg(0)) 52 if err != nil { 53 c.SetError(err) 54 return 55 } 56 err = sf.Listen(c.Arg(1)) 57 if err != nil { 58 c.SetError(err) 59 return 60 } 61 c.SetRet(0) 62 } 63 64 func sysBind(c *isyscall.Request) { 65 sf, err := findSockFile(c.Arg(0)) 66 if err != nil { 67 c.SetError(err) 68 return 69 } 70 err = sf.Bind(c.Arg(1), c.Arg(2)) 71 if err != nil { 72 c.SetError(err) 73 return 74 } 75 c.SetRet(0) 76 77 } 78 79 func sysAccept4(c *isyscall.Request) { 80 sf, err := findSockFile(c.Arg(0)) 81 if err != nil { 82 c.SetError(err) 83 return 84 } 85 fd, err := sf.Accept4(c.Arg(1), c.Arg(2), c.Arg(3)) 86 if err != nil { 87 c.SetError(err) 88 return 89 } 90 c.SetRet(uintptr(fd)) 91 92 } 93 94 func sysConnect(c *isyscall.Request) { 95 sf, err := findSockFile(c.Arg(0)) 96 if err != nil { 97 c.SetError(err) 98 return 99 } 100 uaddr := c.Arg(1) 101 uaddrlen := c.Arg(2) 102 err = sf.Connect(uaddr, uaddrlen) 103 c.SetError(err) 104 } 105 106 func sysSetsockopt(c *isyscall.Request) { 107 sf, err := findSockFile(c.Arg(0)) 108 if err != nil { 109 c.SetError(err) 110 return 111 } 112 err = sf.Setsockopt(c.Arg(1), c.Arg(2), c.Arg(3), c.Arg(4)) 113 // if err != nil { 114 // err = isyscall.EPANIC 115 // } 116 c.SetError(err) 117 } 118 119 func sysGetsockopt(c *isyscall.Request) { 120 sf, err := findSockFile(c.Arg(0)) 121 if err != nil { 122 c.SetError(err) 123 return 124 } 125 err = sf.Getsockopt(c.Arg(1), c.Arg(2), c.Arg(3), c.Arg(4)) 126 if err != nil { 127 c.SetError(err) 128 return 129 } 130 c.SetRet(0) 131 } 132 133 func sysGetsockname(c *isyscall.Request) { 134 sf, err := findSockFile(c.Arg(0)) 135 if err != nil { 136 c.SetError(err) 137 return 138 } 139 err = sf.Getsockname(c.Arg(1), c.Arg(2)) 140 // if err != nil { 141 // err = isyscall.EPANIC 142 // } 143 c.SetError(err) 144 } 145 146 func sysGetpeername(c *isyscall.Request) { 147 sf, err := findSockFile(c.Arg(0)) 148 if err != nil { 149 c.SetError(err) 150 return 151 } 152 err = sf.Getpeername(c.Arg(1), c.Arg(2)) 153 // if err != nil { 154 // err = isyscall.EPANIC 155 // } 156 c.SetError(err) 157 } 158 159 func ntohs(n uint16) uint16 { 160 return (n >> 8 & 0xff) | (n&0xff)<<8 161 } 162 163 func htons(n uint16) uint16 { 164 return ntohs(n) 165 } 166 167 func init() { 168 isyscall.Register(syscall.SYS_SOCKET, sysSocket) 169 isyscall.Register(syscall.SYS_BIND, sysBind) 170 isyscall.Register(syscall.SYS_LISTEN, sysListen) 171 isyscall.Register(syscall.SYS_ACCEPT4, sysAccept4) 172 isyscall.Register(syscall.SYS_CONNECT, sysConnect) 173 isyscall.Register(syscall.SYS_SETSOCKOPT, sysSetsockopt) 174 isyscall.Register(syscall.SYS_GETSOCKOPT, sysGetsockopt) 175 isyscall.Register(syscall.SYS_GETSOCKNAME, sysGetsockname) 176 isyscall.Register(syscall.SYS_GETPEERNAME, sysGetpeername) 177 }