2 * AcessNative ld-acess dynamic linker
3 * - By John Hodge (thePowersGang)
11 # define DEBUG_S printf
14 # define DONT_INCLUDE_SYSCALL_NAMES
26 # include <sys/socket.h>
27 # include <netinet/in.h>
30 #include "../syscalls.h"
35 void SendData(void *Data, int Length);
36 int ReadData(void *Dest, int MaxLen, int Timeout);
41 SOCKET gSocket = INVALID_SOCKET;
43 # define INVALID_SOCKET -1
44 int gSocket = INVALID_SOCKET;
46 // Client ID to pass to server
47 // TODO: Implement such that each thread gets a different one
48 int giSyscall_ClientID = 0;
49 struct sockaddr_in gSyscall_ServerAddr;
52 void Request_Preinit(void)
55 memset((void *)&gSyscall_ServerAddr, '\0', sizeof(struct sockaddr_in));
56 gSyscall_ServerAddr.sin_family = AF_INET;
57 gSyscall_ServerAddr.sin_port = htons(SERVER_PORT);
58 gSyscall_ServerAddr.sin_addr.s_addr = htonl(0x7F000001);
61 int _InitSyscalls(void)
64 /* Open windows connection */
65 if (WSAStartup(0x0101, &gWinsock) != 0)
67 fprintf(stderr, "Could not open Windows connection.\n");
73 // Open TCP Connection
74 gSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
76 // Open UDP Connection
77 gSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
79 if (gSocket == INVALID_SOCKET)
81 fprintf(stderr, "Could not create socket.\n");
89 if( connect(gSocket, (struct sockaddr *)&gSyscall_ServerAddr, sizeof(struct sockaddr_in)) < 0 )
91 fprintf(stderr, "[ERROR -] Cannot connect to server (localhost:%i)\n", SERVER_PORT);
92 perror("_InitSyscalls");
94 fprintf(stderr, "[ERROR -] - WSAGetLastError said %i", WSAGetLastError());
105 // Set client address
106 memset((void *)&client, '\0', sizeof(struct sockaddr_in));
107 client.sin_family = AF_INET;
108 client.sin_port = htons(0);
109 client.sin_addr.s_addr = htonl(0x7F000001);
111 if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 )
113 fprintf(stderr, "Cannot bind address to socket.\n");
115 closesocket(gSocket);
126 tRequestAuthHdr auth;
127 auth.pid = giSyscall_ClientID;
129 SendData(&auth, sizeof(auth));
130 int len = ReadData(&auth, sizeof(auth), 5);
132 fprintf(stderr, "Timeout waiting for auth response\n");
135 giSyscall_ClientID = auth.pid;
138 // Ask server for a client ID
139 if( !giSyscall_ClientID )
147 SendData(&req, sizeof(req));
149 len = ReadData(&req, sizeof(req), 5);
151 fprintf(stderr, "Unable to connect to server (localhost:%i)\n", SERVER_PORT);
155 giSyscall_ClientID = req.ClientID;
163 * \brief Close the syscall socket
164 * \note Used in acess_fork to get a different port number
166 void _CloseSyscalls(void)
169 closesocket(gSocket);
176 int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
178 if( gSocket == INVALID_SOCKET )
184 Request->ClientID = giSyscall_ClientID;
188 for(i=0;i<RequestSize;i++)
190 printf("%02x ", ((uint8_t*)Request)[i]);
191 if( i % 16 == 15 ) printf("\n");
199 char *data = (char*)&Request->Params[Request->NParams];
200 DEBUG_S("Request #%i (%s) -", Request->CallID, casSYSCALL_NAMES[Request->CallID]);
201 for( i = 0; i < Request->NParams; i ++ )
203 switch(Request->Params[i].Type)
206 DEBUG_S(" 0x%08x", *(uint32_t*)data);
207 data += sizeof(uint32_t);
210 DEBUG_S(" 0x%016"PRIx64"", *(uint64_t*)data);
211 data += sizeof(uint64_t);
213 case ARG_TYPE_STRING:
214 DEBUG_S(" '%s'", (char*)data);
215 data += Request->Params[i].Length;
218 DEBUG_S(" %p:0x%x", (char*)data, Request->Params[i].Length);
219 if( !(Request->Params[i].Flags & ARG_FLAG_ZEROED) )
220 data += Request->Params[i].Length;
229 SendData(Request, RequestSize);
231 if( Request->CallID == SYS_EXIT ) return 0;
233 // Wait for a response (no timeout)
234 ReadData(Request, sizeof(*Request), 0);
236 size_t recvbytes = sizeof(*Request), expbytes = Request->MessageLength;
237 char *ptr = (void*)Request->Params;
238 while( recvbytes < expbytes )
240 size_t len = ReadData(ptr, expbytes - recvbytes, 1000);
247 if( recvbytes > expbytes ) {
254 char *data = (char*)&Request->Params[Request->NParams];
256 for( i = 0; i < Request->NParams; i ++ )
258 switch(Request->Params[i].Type)
261 DEBUG_S(" 0x%08x", *(uint32_t*)data);
262 data += sizeof(uint32_t);
265 DEBUG_S(" 0x%016"PRIx64"", *(uint64_t*)data);
266 data += sizeof(uint64_t);
268 case ARG_TYPE_STRING:
269 DEBUG_S(" '%s'", (char*)data);
270 data += Request->Params[i].Length;
273 DEBUG_S(" %p:0x%x", (char*)data, Request->Params[i].Length);
274 if( !(Request->Params[i].Flags & ARG_FLAG_ZEROED) )
275 data += Request->Params[i].Length;
285 void SendData(void *Data, int Length)
290 len = send(gSocket, Data, Length, 0);
292 len = sendto(gSocket, Data, Length, 0,
293 (struct sockaddr*)&gSyscall_ServerAddr, sizeof(gSyscall_ServerAddr));
296 if( len != Length ) {
297 fprintf(stderr, "[ERROR %i] ", giSyscall_ClientID);
303 int ReadData(void *Dest, int MaxLength, int Timeout)
308 struct timeval *timeoutPtr;
311 FD_SET(gSocket, &fds);
322 ret = select(gSocket+1, &fds, NULL, NULL, timeoutPtr);
324 fprintf(stderr, "[ERROR %i] ", giSyscall_ClientID);
325 perror("ReadData - select");
330 printf("[ERROR %i] Timeout reading from socket\n", giSyscall_ClientID);
331 return -2; // Timeout
335 ret = recv(gSocket, Dest, MaxLength, 0);
337 ret = recvfrom(gSocket, Dest, MaxLength, 0, NULL, 0);
341 fprintf(stderr, "[ERROR %i] ", giSyscall_ClientID);
346 fprintf(stderr, "[ERROR %i] Connection closed.\n", giSyscall_ClientID);
348 closesocket(gSocket);
355 DEBUG_S("%i bytes read from socket\n", ret);