sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
ps2ipc.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
15
16#include <tamtypes.h>
17#include <string.h>
18#include <kernel.h>
19#include <sifrpc.h>
20#include <iopcontrol.h>
21
22#include <ps2ips.h>
23#include <ps2ip_rpc.h>
24
25static int lock_sema;
26static SifRpcClientData_t _ps2ip;
27static struct {
28 union {
29 s32 result;
30 s32 s; //Generic socket parameter.
31 cmd_pkt cmd_pkt; //Generic command packet, used by multiple functions.
37 t_ip_info ip_info;
38 char netif_name[8];
44 char hostname[256];
45 gethostbyname_res_pkt gethostbyname_res_pkt;
46 dns_setserver_pkt dns_setserver_pkt;
47 dns_getserver_res_pkt dns_getserver_res_pkt;
48 u8 numdns;
49 u8 buffer[512];
50 };
51} _rpc_buffer __attribute__((aligned(64)));
52static int _intr_data[32] __attribute__((aligned(64)));
53
54/* Copied from LWIP (lwip/opt.h, lwip/ip4_addr.h, lwip/ip_addr.h - real,
55 * verified-matching values/macros for the plain-IPv4, LWIP_DNS_API_
56 * DECLARE_STRUCTS-style build this file already assumed), to be
57 * independent of the full LWIP source - same intent as this file's own
58 * pre-existing "Copied from LWIP" comment below, extended to also
59 * cover the pieces that used to arrive as a side effect of the
60 * (superseded) blanket #include <tcpip.h>. */
61#ifndef DNS_MAX_SERVERS
62#define DNS_MAX_SERVERS 2
63#endif
64#ifndef IPADDR_ANY
65#define IPADDR_ANY ((u32)0x00000000UL)
66#endif
67#ifndef IPADDR4_INIT
68#define IPADDR4_INIT(u32val) { u32val }
69#endif
70#ifndef ip_addr_copy
71#define ip_addr_copy(dest, src) ((dest).addr = (src).addr)
72#endif
73
74#ifndef LWIP_DNS_API_DECLARE_STRUCTS
75struct hostent
76{
77 char *h_name;
78 char **h_aliases;
79 int h_addrtype;
80 int h_length;
81 char **h_addr_list;
82};
83#endif
84
85static ip_addr_t dns_servers[DNS_MAX_SERVERS];
86
87//Copied from LWIP, to be independent of the full LWIP source.
88/* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
89const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
90#ifndef IP4_ADDR_ANY
91#define IP4_ADDR_ANY (&ip_addr_any)
92#endif
93
94/* The following are defined in ps2ipc_ps2sdk.c */
95extern void _ps2sdk_ps2ipc_init(void);
96extern void _ps2sdk_ps2ipc_deinit(void);
97
98int ps2ip_init(void)
99{
100 ee_sema_t sema;
101 if (HasIopRebootedSinceLastCall())
102 ps2ip_deinit();
103
104 if (_ps2ip.server)
105 return 0;
106
107 while(1)
108 {
109 if(sceSifBindRpc(&_ps2ip, PS2IP_IRX, 0) < 0)
110 return -1;
111
112 if(_ps2ip.server != NULL)
113 break;
114
115 nopdelay();
116 }
117
118 sema.init_count = 1;
119 sema.max_count = 1;
120 sema.option = (u32)"ps2ipc";
121 sema.attr = 0;
122 lock_sema = CreateSema(&sema);
123
124 _ps2sdk_ps2ipc_init();
125
126 return 0;
127}
128
129void ps2ip_deinit(void)
130{
131 _ps2sdk_ps2ipc_deinit();
132
133 if (lock_sema > 0)
134 DeleteSema(lock_sema);
135 lock_sema = 0;
136
137 memset(&_ps2ip, 0, sizeof(_ps2ip));
138}
139
140int ps2ipc_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
141{
142 int result;
143 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
144
145 if(!_ps2ip.server) return -1;
146
147 WaitSema(lock_sema);
148
149 pkt->socket = s;
150
151 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_ACCEPT, 0, (void*)pkt, sizeof(s32), (void*)pkt, sizeof(cmd_pkt), NULL, NULL) < 0)
152 {
153 SignalSema(lock_sema);
154 return -1;
155 }
156
157 if(addr != NULL)
158 {
159 if((socklen_t)pkt->len < *addrlen) *addrlen = (socklen_t)pkt->len;
160 memcpy((void *)addr, (void *)&pkt->sockaddr, *addrlen);
161 }
162
163 result = pkt->socket;
164
165 SignalSema(lock_sema);
166
167 return result;
168}
169
170int ps2ipc_bind(int s, const struct sockaddr *name, socklen_t namelen)
171{
172 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
173 int result;
174
175 if(!_ps2ip.server) return -1;
176
177 WaitSema(lock_sema);
178
179 pkt->socket = s;
180 pkt->len = namelen;
181 memcpy((void *)&pkt->sockaddr, (void *)name, sizeof(struct sockaddr));
182
183 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_BIND, 0, (void*)pkt, sizeof(cmd_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
184 {
185 SignalSema(lock_sema);
186 return -1;
187 }
188
189 result = _rpc_buffer.result;
190
191 SignalSema(lock_sema);
192
193 return result;
194}
195
196int ps2ipc_disconnect(int s)
197{
198 int result;
199
200 if(!_ps2ip.server) return -1;
201
202 WaitSema(lock_sema);
203
204 _rpc_buffer.s = s;
205
206 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_DISCONNECT, 0, (void*)&_rpc_buffer.s, sizeof(s32), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
207 {
208 SignalSema(lock_sema);
209 return -1;
210 }
211
212 result = _rpc_buffer.result;
213
214 SignalSema(lock_sema);
215
216 return result;
217}
218
219int ps2ipc_connect(int s, const struct sockaddr *name, socklen_t namelen)
220{
221 int result;
222 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
223
224 if(!_ps2ip.server) return -1;
225
226 WaitSema(lock_sema);
227
228 pkt->socket = s;
229 pkt->len = namelen;
230 memcpy((void *)&pkt->sockaddr, (void *)name, sizeof(struct sockaddr));
231
232 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_CONNECT, 0, (void*)pkt, sizeof(cmd_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
233 {
234 SignalSema(lock_sema);
235 return -1;
236 }
237
238 result = _rpc_buffer.result;
239
240 SignalSema(lock_sema);
241
242 return result;
243}
244
245int ps2ipc_listen(int s, int backlog)
246{
247 int result;
248 listen_pkt *pkt = &_rpc_buffer.listen_pkt;
249
250 if(!_ps2ip.server) return -1;
251
252 WaitSema(lock_sema);
253
254 pkt->s = s;
255 pkt->backlog = backlog;
256
257 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_LISTEN, 0, (void*)pkt, sizeof(listen_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
258 {
259 SignalSema(lock_sema);
260 return -1;
261 }
262
263 result = _rpc_buffer.result;
264
265 SignalSema(lock_sema);
266
267 return result;
268}
269
270static void recv_intr(void *data_raw)
271{
272 rests_pkt *rests = UNCACHED_SEG(data_raw);
273 int i;
274
275 if(rests->ssize)
276 for(i = 0; i < rests->ssize; i++)
277 rests->sbuf[i] = rests->sbuffer[i];
278
279 if(rests->esize)
280 for(i = 0; i < rests->esize; i++)
281 rests->ebuf[i] = rests->ebuffer[i];
282}
283
284
285int ps2ipc_recv(int s, void *mem, int len, unsigned int flags)
286{
287 int result;
288 s_recv_pkt *send_pkt = &_rpc_buffer.s_recv_pkt;
289 r_recv_pkt *recv_pkt = &_rpc_buffer.r_recv_pkt;
290
291 if(!_ps2ip.server) return -1;
292
293 WaitSema(lock_sema);
294
295 send_pkt->socket = s;
296 send_pkt->length = len;
297 send_pkt->flags = flags;
298 send_pkt->ee_addr = mem;
299 send_pkt->intr_data = _intr_data;
300
301 if( !IS_UNCACHED_SEG(mem))
302 sceSifWriteBackDCache(mem, len);
303
304 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_RECV, 0, (void*)send_pkt, sizeof(s_recv_pkt),
305 (void*)recv_pkt, sizeof(r_recv_pkt), recv_intr, _intr_data) < 0)
306 {
307 SignalSema(lock_sema);
308 return -1;
309 }
310
311 result = recv_pkt->ret;
312
313 SignalSema(lock_sema);
314
315 return result;
316}
317
318int ps2ipc_recvfrom(int s, void *mem, int len, unsigned int flags,
319 struct sockaddr *from, socklen_t *fromlen)
320{
321 int result;
322 s_recv_pkt *send_pkt = &_rpc_buffer.s_recv_pkt;
323 r_recv_pkt *recv_pkt = &_rpc_buffer.r_recv_pkt;
324
325 if(!_ps2ip.server) return -1;
326
327 WaitSema(lock_sema);
328
329 send_pkt->socket = s;
330 send_pkt->length = len;
331 send_pkt->flags = flags;
332 send_pkt->ee_addr = mem;
333 send_pkt->intr_data = _intr_data;
334
335 if( !IS_UNCACHED_SEG(mem))
336 sceSifWriteBackDCache(mem, len);
337
338 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_RECVFROM, 0, (void*)send_pkt, sizeof(s_recv_pkt),
339 (void*)recv_pkt, sizeof(r_recv_pkt), recv_intr, _intr_data) < 0)
340 {
341 SignalSema(lock_sema);
342 return -1;
343 }
344
345 memcpy((void *)from, (void *)&recv_pkt->sockaddr, sizeof(struct sockaddr));
346 *fromlen = sizeof(struct sockaddr);
347
348 result = recv_pkt->ret;
349
350 SignalSema(lock_sema);
351
352 return result;
353}
354
355int ps2ipc_send(int s, const void *dataptr, int size, unsigned int flags)
356{
357 int result;
358 send_pkt *pkt = &_rpc_buffer.send_pkt;
359 int miss;
360
361 WaitSema(lock_sema);
362
363 pkt->socket = s;
364 pkt->length = size;
365 pkt->flags = flags;
366 pkt->ee_addr = (void *)dataptr;
367
368 if((u32)dataptr & 0x3f)
369 {
370 miss = 64 - ((u32)dataptr & 0x3f);
371 if(miss > size) miss = size;
372
373 } else {
374
375 miss = 0;
376 }
377
378 pkt->malign = miss;
379
380 if( !IS_UNCACHED_SEG(dataptr))
381 sceSifWriteBackDCache((void *)dataptr, size);
382
383 memcpy((void *)pkt->malign_buff, UNCACHED_SEG(dataptr), miss);
384
385 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_SEND, 0, (void*)pkt, sizeof(send_pkt),
386 (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
387 {
388 SignalSema(lock_sema);
389 return -1;
390 }
391
392 result = _rpc_buffer.result;
393
394 SignalSema(lock_sema);
395
396 return result;
397}
398
399int ps2ipc_sendto(int s, const void *dataptr, int size, unsigned int flags,
400 const struct sockaddr *to, socklen_t tolen)
401{
402 int result;
403 send_pkt *pkt = &_rpc_buffer.send_pkt;
404 int miss;
405
406 (void)tolen;
407
408 WaitSema(lock_sema);
409
410 pkt->socket = s;
411 pkt->length = size;
412 pkt->flags = flags;
413 pkt->ee_addr = (void *)dataptr;
414 memcpy((void *)&pkt->sockaddr, (void *)to, sizeof(struct sockaddr));
415
416 if((u32)dataptr & 0x3f)
417 {
418 miss = 64 - ((u32)dataptr & 0x3f);
419 if(miss > size) miss = size;
420
421 } else {
422
423 miss = 0;
424 }
425
426 pkt->malign = miss;
427
428 if( !IS_UNCACHED_SEG(dataptr))
429 sceSifWriteBackDCache((void *)dataptr, size);
430
431 memcpy((void *)pkt->malign_buff, UNCACHED_SEG(dataptr), miss);
432
433 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_SENDTO, 0, (void*)pkt, sizeof(send_pkt),
434 (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
435 {
436 SignalSema(lock_sema);
437 return -1;
438 }
439
440 result = _rpc_buffer.result;
441
442 SignalSema(lock_sema);
443
444 return result;
445}
446
447int ps2ipc_socket(int domain, int type, int protocol)
448{
449 int result;
450 socket_pkt *pkt = &_rpc_buffer.socket_pkt;
451
452 if(!_ps2ip.server) return -1;
453
454 WaitSema(lock_sema);
455
456 pkt->domain = domain;
457 pkt->type = type;
458 pkt->protocol = protocol;
459
460 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_SOCKET, 0, (void*)pkt, sizeof(socket_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
461 {
462 SignalSema(lock_sema);
463 return -1;
464 }
465
466 result = _rpc_buffer.result;
467
468 SignalSema(lock_sema);
469
470 return result;
471}
472
473int ps2ipc_ps2ip_setconfig(const t_ip_info *ip_info)
474{
475 int result;
476
477 if(!_ps2ip.server) return -1;
478
479 WaitSema(lock_sema);
480
481 // return config
482 memcpy(&_rpc_buffer.ip_info, ip_info, sizeof(t_ip_info));
483
484 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_SETCONFIG, 0, (void*)&_rpc_buffer.ip_info, sizeof(t_ip_info), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
485 {
486 SignalSema(lock_sema);
487 return -1;
488 }
489
490 result = _rpc_buffer.result;
491
492 SignalSema(lock_sema);
493
494 return result;
495}
496
497int ps2ipc_ps2ip_getconfig(char *netif_name, t_ip_info *ip_info)
498{
499 if(!_ps2ip.server) return -1;
500
501 WaitSema(lock_sema);
502
503 // call with netif name
504 strlcpy(_rpc_buffer.netif_name, netif_name, sizeof(_rpc_buffer.netif_name));
505
506 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_GETCONFIG, 0, (void*)_rpc_buffer.netif_name, sizeof(_rpc_buffer.netif_name), (void*)&_rpc_buffer.ip_info, sizeof(t_ip_info), NULL, NULL) < 0)
507 {
508 SignalSema(lock_sema);
509 return -1;
510 }
511
512 // return config
513 memcpy(ip_info, &_rpc_buffer.ip_info, sizeof(t_ip_info));
514
515 SignalSema(lock_sema);
516
517 return 1;
518}
519
520/* Marshal between the caller's struct fd_set (newlib, ~128 bytes on EE)
521 * and the on-the-wire ps2ip_rpc_fd_set (MEMP_NUM_NETCONN/8 bytes, fixed
522 * size on both sides). Bit-by-bit copy avoids any reliance on
523 * sizeof(struct fd_set) matching across the RPC boundary. */
524static void ps2ipc_pack_fdset(ps2ip_rpc_fd_set *dst, struct fd_set *src, int maxfdp1)
525{
526 int i;
527 memset(dst, 0, sizeof(*dst));
528 if (src == NULL) return;
529 if (maxfdp1 > (int)(sizeof(dst->fd_bits) * 8))
530 maxfdp1 = (int)(sizeof(dst->fd_bits) * 8);
531 for (i = 0; i < maxfdp1; i++) {
532 if (FD_ISSET(i, src)) {
533 dst->fd_bits[i >> 3] |= (unsigned char)(1U << (i & 7));
534 }
535 }
536}
537
538static void ps2ipc_unpack_fdset(struct fd_set *dst, const ps2ip_rpc_fd_set *src, int maxfdp1)
539{
540 int i;
541 if (dst == NULL) return;
542 FD_ZERO(dst);
543 if (maxfdp1 > (int)(sizeof(src->fd_bits) * 8))
544 maxfdp1 = (int)(sizeof(src->fd_bits) * 8);
545 for (i = 0; i < maxfdp1; i++) {
546 if (src->fd_bits[i >> 3] & (1U << (i & 7))) {
547 FD_SET(i, dst);
548 }
549 }
550}
551
552int ps2ipc_select(int maxfdp1, struct fd_set *readset, struct fd_set *writeset, struct fd_set *exceptset, struct timeval *timeout)
553{
554 int result;
555 select_pkt *pkt = &_rpc_buffer.select_pkt;
556
557 if(!_ps2ip.server) return -1;
558
559 WaitSema(lock_sema);
560
561 pkt->maxfdp1 = maxfdp1;
562 pkt->readset_p = (void *)readset;
563 pkt->writeset_p = (void *)writeset;
564 pkt->exceptset_p = (void *)exceptset;
565 pkt->timeout_p = timeout;
566 if( timeout )
567 {
568 pkt->timeout_sec = (s32)timeout->tv_sec;
569 pkt->timeout_usec = (s32)timeout->tv_usec;
570 }
571
572 ps2ipc_pack_fdset(&pkt->readset, readset, maxfdp1);
573 ps2ipc_pack_fdset(&pkt->writeset, writeset, maxfdp1);
574 ps2ipc_pack_fdset(&pkt->exceptset, exceptset, maxfdp1);
575
576 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_SELECT, 0, (void*)pkt, sizeof(select_pkt), (void*)pkt, sizeof(select_pkt), NULL, NULL) < 0)
577 {
578 SignalSema(lock_sema);
579 return -1;
580 }
581
582 if( timeout )
583 {
584 timeout->tv_sec = pkt->timeout_sec;
585 timeout->tv_usec = pkt->timeout_usec;
586 }
587
588 ps2ipc_unpack_fdset(readset, &pkt->readset, maxfdp1);
589 ps2ipc_unpack_fdset(writeset, &pkt->writeset, maxfdp1);
590 ps2ipc_unpack_fdset(exceptset, &pkt->exceptset, maxfdp1);
591
592 result = pkt->result;
593
594 SignalSema(lock_sema);
595
596 return result;
597}
598
599int ps2ipc_ioctl(int s, long cmd, void *argp)
600{
601 int result;
602 ioctl_pkt *pkt = &_rpc_buffer.ioctl_pkt;
603
604 if(!_ps2ip.server) return -1;
605
606 WaitSema(lock_sema);
607
608 pkt->s = s;
609 pkt->cmd = (s32)cmd;
610 pkt->argp = argp;
611 if( argp )
612 pkt->value = *(s32*)argp;
613
614 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_IOCTL, 0, (void*)pkt, sizeof(ioctl_pkt), (void*)pkt, sizeof(ioctl_pkt), NULL, NULL) < 0)
615 {
616 SignalSema(lock_sema);
617 return -1;
618 }
619
620 if( argp )
621 *(s32*)argp = pkt->value;
622
623 result = pkt->result;
624
625 SignalSema(lock_sema);
626
627 return result;
628}
629
630int ps2ipc_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
631{
632 int result;
633 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
634
635 if(!_ps2ip.server) return -1;
636
637 WaitSema(lock_sema);
638
639 pkt->socket = s;
640
641 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_GETSOCKNAME, 0, (void*)pkt, sizeof(pkt->socket), (void*)pkt, sizeof(cmd_pkt), NULL, NULL) < 0)
642 {
643 SignalSema(lock_sema);
644 return -1;
645 }
646
647 if((socklen_t)pkt->len < *namelen) *namelen = (socklen_t)pkt->len;
648 memcpy((void *)name, (void *)&pkt->sockaddr, *namelen);
649
650 result = pkt->socket;
651
652 SignalSema(lock_sema);
653
654 return result;
655}
656
657int ps2ipc_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
658{
659 int result;
660 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
661
662 if(!_ps2ip.server) return -1;
663
664 WaitSema(lock_sema);
665
666 pkt->socket = s;
667
668 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_GETPEERNAME, 0, (void*)pkt, sizeof(pkt->socket), (void*)pkt, sizeof(cmd_pkt), NULL, NULL) < 0)
669 {
670 SignalSema(lock_sema);
671 return -1;
672 }
673
674 if((socklen_t)pkt->len < *namelen) *namelen = (socklen_t)pkt->len;
675 memcpy((void *)name, (void *)&pkt->sockaddr, *namelen);
676
677 result = pkt->socket;
678
679 SignalSema(lock_sema);
680
681 return result;
682}
683
684int ps2ipc_getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)
685{
686 getsockopt_pkt *pkt = &_rpc_buffer.getsockopt_pkt;
687 getsockopt_res_pkt *res_pkt = &_rpc_buffer.getsockopt_res_pkt;
688 int result;
689
690 if(!_ps2ip.server) return -1;
691
692 WaitSema(lock_sema);
693
694 pkt->s = s;
695 pkt->level = level;
696 pkt->optname = optname;
697
698 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_GETSOCKOPT, 0, (void*)pkt, sizeof(getsockopt_pkt), (void*)res_pkt, sizeof(getsockopt_res_pkt), NULL, NULL) < 0)
699 {
700 SignalSema(lock_sema);
701 return -1;
702 }
703
704 if(res_pkt->optlen < *optlen) *optlen = res_pkt->optlen;
705 memcpy((void*)optval, res_pkt->buffer, *optlen);
706
707 result = res_pkt->result;
708
709 SignalSema(lock_sema);
710
711 return result;
712}
713
714int ps2ipc_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
715{
716 setsockopt_pkt *pkt = &_rpc_buffer.setsockopt_pkt;
717 int result;
718
719 if(!_ps2ip.server) return -1;
720
721 WaitSema(lock_sema);
722
723 pkt->s = s;
724 pkt->level = level;
725 pkt->optname = optname;
726 pkt->optlen = optlen;
727
728 memcpy(pkt->buffer, optval, optlen);
729
730 if (sceSifCallRpc(&_ps2ip, PS2IPS_ID_SETSOCKOPT, 0, (void*)pkt, sizeof(setsockopt_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
731 {
732 SignalSema(lock_sema);
733 return -1;
734 }
735
736 result = _rpc_buffer.result;
737
738 SignalSema(lock_sema);
739
740 return result;
741}
742
743#ifdef PS2IP_DNS
744struct hostent *ps2ipc_gethostbyname(const char *name)
745{
746 gethostbyname_res_pkt *res_pkt = &_rpc_buffer.gethostbyname_res_pkt;
747 struct hostent *result;
748 static ip_addr_t addr;
749 static ip_addr_t *addr_list[2];
750 static struct hostent hostent;
751
752 if(!_ps2ip.server) return NULL;
753
754 WaitSema(lock_sema);
755
756 result = NULL;
757 strlcpy(_rpc_buffer.hostname, name, sizeof(_rpc_buffer.hostname));
758 if(sceSifCallRpc(&_ps2ip, PS2IPS_ID_GETHOSTBYNAME, 0, (void*)_rpc_buffer.hostname, sizeof(_rpc_buffer.hostname), (void*)res_pkt, sizeof(gethostbyname_res_pkt), NULL, NULL) >=0)
759 {
760 if(res_pkt->result == 0)
761 {
762 hostent.h_addrtype = res_pkt->hostent.h_addrtype;
763 hostent.h_length = res_pkt->hostent.h_length;
764 hostent.h_name = (char*)name;
765 hostent.h_aliases = NULL;
766 memcpy(&addr, &res_pkt->hostent.h_addr, sizeof(addr));
767 addr_list[0] = &addr;
768 addr_list[1] = NULL;
769 hostent.h_addr_list = (char**)&addr_list;
770 result = &hostent;
771 }
772 }
773
774 SignalSema(lock_sema);
775
776 return result;
777}
778
779void ps2ipc_dns_setserver(u8 numdns, const ip_addr_t *dnsserver)
780{
781 dns_setserver_pkt *pkt = &_rpc_buffer.dns_setserver_pkt;
782
783 if(!_ps2ip.server) return;
784
785 WaitSema(lock_sema);
786
787 pkt->numdns = numdns;
788 pkt->dnsserver = (dnsserver != NULL) ? (*dnsserver) : *IP4_ADDR_ANY;
789
790 sceSifCallRpc(&_ps2ip, PS2IPS_ID_DNS_SETSERVER, 0, (void*)pkt, sizeof(dns_setserver_pkt), NULL, 0, NULL, NULL);
791
792 if (numdns < DNS_MAX_SERVERS)
793 dns_servers[numdns] = (dnsserver != NULL) ? (*dnsserver) : *IP4_ADDR_ANY;
794
795 SignalSema(lock_sema);
796}
797
798const ip_addr_t *ps2ipc_dns_getserver(u8 numdns)
799{
800 dns_getserver_res_pkt *res_pkt = &_rpc_buffer.dns_getserver_res_pkt;
801 ip_addr_t *dns;
802
803 if ((!_ps2ip.server) || (numdns >= DNS_MAX_SERVERS))
804 return IP4_ADDR_ANY;
805
806 WaitSema(lock_sema);
807
808 _rpc_buffer.numdns = numdns;
809 dns = &dns_servers[numdns];
810
811 //If this fails, use the cached copy.
812 if(sceSifCallRpc(&_ps2ip, PS2IPS_ID_DNS_GETSERVER, 0, (void*)&_rpc_buffer.numdns, sizeof(u8), (void*)res_pkt, sizeof(dns_getserver_res_pkt), NULL, NULL) >=0)
813 ip_addr_copy(*dns, res_pkt->dnsserver);
814
815 SignalSema(lock_sema);
816
817 return dns;
818}
819#endif
#define IPADDR_ANY
Definition tcpip.h:289
#define IP4_ADDR_ANY
Definition tcpip.h:1053
Definition mem.c:336
u8 malign_buff[64]
Definition ps2ip_rpc.h:123
Definition time.h:30