PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
netcnfif.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 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
11#include "irx_imports.h"
12
13#ifdef _IOP
14IRX_ID("Netcnf_Interface", 2, 30);
15#endif
16// Based on the module from SCE SDK 3.1.0.
17
18// TODO EE alignment 64
19typedef struct __attribute__((aligned(16))) sceNetcnfifList
20{
21 int type;
22 int stat;
23 char sys_name[256];
24 char usr_name[256];
25 int padding[14];
26} sceNetcnfifList_t;
27
28// TODO EE alignment 64
29typedef struct __attribute__((aligned(16))) sceNetcnfifData
30{
31 char attach_ifc[256];
32 char attach_dev[256];
33 char dhcp_host_name[256];
34 char address[256];
35 char netmask[256];
36 char gateway[256];
37 char dns1_address[256];
38 char dns2_address[256];
39 char phone_numbers1[256];
40 char phone_numbers2[256];
41 char phone_numbers3[256];
42 char auth_name[256];
43 char auth_key[256];
44 char peer_name[256];
45 char vendor[256];
46 char product[256];
47 char chat_additional[256];
48 char outside_number[256];
49 char outside_delay[256];
50 int ifc_type;
51 int mtu;
52 int ifc_idle_timeout;
53 int dev_type;
54 int phy_config;
55 int dialing_type;
56 int dev_idle_timeout;
57 int p0;
58 u8 dhcp;
59 u8 dns1_nego;
60 u8 dns2_nego;
61 u8 f_auth;
62 u8 auth;
63 u8 pppoe;
64 u8 prc_nego;
65 u8 acc_nego;
66 u8 accm_nego;
67 u8 p1;
68 u8 p2;
69 u8 p3;
70 int p4[5];
71} sceNetcnfifData_t;
72
73typedef struct sceNetcnfifArg
74{
75 int data;
76 int f_no_decode;
77 int type;
78 int addr;
79 char fname[256];
80 char usr_name[256];
81 char new_usr_name[256];
83
84static void sceNetcnfifInterfaceStart(void *userdata);
85static void sceNetcnfifInterfaceStop(void);
86static void sceNetcnfifDataInit(sceNetcnfifData_t *data);
87static void sceNetcnfifEnvInit(sceNetCnfEnv_t *env, void *mem_area, int size, int f_no_decode);
88static int sceNetcnfifReadEnv(sceNetcnfifData_t *data, sceNetCnfEnv_t *e, int type);
89static int sceNetcnfifWriteEnv(sceNetCnfEnv_t *e, sceNetcnfifData_t *data, int type);
90static int sceNetcnfifSendEE(unsigned int data, unsigned int addr, unsigned int size);
91static int sceNetcnfifDmaCheck(int id);
92static void sce_callback_initialize(void);
93static int sce_callback_open(const char *device, const char *pathname, int flags, int mode, int *filesize);
94static int sce_callback_read(int fd, const char *device, const char *pathname, void *buf, int offset, int size);
95static int sce_callback_close(int fd);
96static int my_create_heap(void);
97static void *my_alloc(int size);
98static void my_free(void *ptr);
99static void my_delete_heap(void);
100
101extern struct irx_export_table _exp_netcnfif;
102// Unofficial: move to bss
103static void *mem_area;
104// Unofficial: move to bss
105static int mem_area_size;
106// Unofficial: move to bss
107static void *g_heap;
108static int g_tid;
109static sceNetCnfEnv_t env;
110static sceNetcnfifData_t data;
111static char dp[0x100];
112static int rpc_buf[1024];
113static SifRpcServerData_t sd;
114static SifRpcDataQueue_t qd;
115static int ns_count;
116static route_t gateway;
117static nameserver_t dns1;
118static nameserver_t dns2;
119static int oldstat;
120static SifRpcClientData_t gcd;
121static int gbuf[1024];
122
123static void usage(void)
124{
125 printf("Usage: netcnfif <option>\n");
126 printf(" <option>:\n");
127 printf(" thpri=<digit> - set thread priority\n");
128 printf(" thstack=<digit>KB - set thread stack size(Kbyte)\n");
129 printf(" thstack=<digit> - set thread stack size(byte)\n");
130 printf(" -help - print usage\n");
131}
132
133static int module_start(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi)
134{
135 int thpri;
136 int thstack;
137 int i;
138 int bp;
139 int retres1;
140 int retres2;
141 iop_thread_t th_param;
142
143 (void)startaddr;
144 thpri = 123;
145 thstack = 4096;
146 for ( i = 1; i < argc; i += 1 )
147 {
148 int xflg;
149
150 xflg = 1;
151 if ( !strncmp("thpri=", argv[i], 6) )
152 {
153 bp = 6;
154 if ( !isdigit(argv[i][bp]) )
155 {
156 usage();
157 return MODULE_NO_RESIDENT_END;
158 }
159 thpri = strtol(&argv[i][bp], 0, 10);
160 if ( (unsigned int)(thpri - 9) >= 0x73 )
161 {
162 usage();
163 return MODULE_NO_RESIDENT_END;
164 }
165 for ( ; argv[i][bp] && isdigit(argv[i][bp]); bp += 1 )
166 ;
167 if ( !argv[i][bp] )
168 {
169 xflg = 0;
170 }
171 }
172 else if ( !strncmp("thstack=", argv[i], 8) )
173 {
174 bp = 8;
175 if ( !isdigit(argv[i][bp]) )
176 {
177 usage();
178 return MODULE_NO_RESIDENT_END;
179 }
180 thstack = strtol(&argv[i][bp], 0, 10);
181 for ( ; argv[i][bp] && isdigit(argv[i][bp]); bp += 1 )
182 ;
183 if ( !strcmp(&argv[i][bp], "KB") )
184 {
185 thstack <<= 10;
186 xflg = 0;
187 }
188 }
189 else
190 {
191 usage();
192 return MODULE_NO_RESIDENT_END;
193 }
194 if ( xflg && argv[i][bp] )
195 {
196 usage();
197 return MODULE_NO_RESIDENT_END;
198 }
199 }
200 retres1 = RegisterLibraryEntries(&_exp_netcnfif);
201 if ( retres1 )
202 {
203 printf("netcnfif: RegisterLibraryEntries(%d)\n", retres1);
204 return MODULE_NO_RESIDENT_END;
205 }
206 retres2 = my_create_heap();
207 if ( retres2 >= 0 )
208 {
209 th_param.attr = TH_C;
210 th_param.thread = sceNetcnfifInterfaceStart;
211 th_param.priority = thpri;
212 th_param.stacksize = thstack;
213 th_param.option = 0;
214 g_tid = CreateThread(&th_param);
215 if ( g_tid >= 0 )
216 {
217 int retres3;
218
219 retres3 = StartThread(g_tid, 0);
220 if ( retres3 >= 0 )
221 {
222#if 0
223 return MODULE_REMOVABLE_END;
224#else
225 if ( mi && ((mi->newflags & 2) != 0) )
226 mi->newflags |= 0x10;
227 return MODULE_RESIDENT_END;
228#endif
229 }
230 printf("netcnfif: s_thread(%d)\n", retres3);
231 TerminateThread(g_tid);
232 DeleteThread(g_tid);
233 }
234 else
235 {
236 printf("netcnfif: c_thread(%d)\n", g_tid);
237 }
238 my_delete_heap();
239 }
240 else
241 {
242 printf("netcnfif: c_heap(%d)\n", retres2);
243 }
244 ReleaseLibraryEntries(&_exp_netcnfif);
245 return MODULE_NO_RESIDENT_END;
246}
247
248static int module_stop(void)
249{
250 sceNetcnfifInterfaceStop();
251 TerminateThread(g_tid);
252 DeleteThread(g_tid);
253 my_delete_heap();
254 ReleaseLibraryEntries(&_exp_netcnfif);
255 return MODULE_NO_RESIDENT_END;
256}
257
258int _start(int ac, char *av[], void *startaddr, ModuleInfo_t *mi)
259{
260 return (ac >= 0) ? module_start(ac, av, startaddr, mi) : module_stop();
261}
262
263static void *sceNetcnfifInterfaceServer(int fno, sceNetcnfifArg_t *buf, int size)
264{
265 int retres1;
266 sceNetCnfList_t *list_iop;
267 sceNetcnfifList_t *list_ee;
268 int i;
269 int dmatid2;
270 sceNetCnfCallback_t callback;
271
272 (void)size;
273 retres1 = 0;
274 switch ( fno )
275 {
276 case 0:
277 retres1 = sceNetCnfGetCount(buf->fname, buf->type);
278 break;
279 case 1:
280 retres1 = sceNetCnfGetCount(buf->fname, buf->type);
281 if ( retres1 < 0 )
282 break;
283 list_iop = (sceNetCnfList_t *)my_alloc(sizeof(sceNetCnfList_t) * retres1);
284 retres1 = -2;
285 if ( !list_iop )
286 break;
287 list_ee = (sceNetcnfifList_t *)my_alloc(sizeof(sceNetcnfifList_t) * buf->data);
288 if ( list_ee )
289 {
290 retres1 = sceNetCnfGetList(buf->fname, buf->type, list_iop);
291 if ( retres1 >= 0 )
292 {
293 int dmatid1;
294
295 for ( i = 0; i < buf->data && i < retres1; i += 1 )
296 {
297 // The following memcpy was inlined
298 memcpy(&list_ee[i], &list_iop[i], sizeof(sceNetCnfList_t));
299 }
300 dmatid1 = sceNetcnfifSendEE((unsigned int)list_ee, buf->addr, sizeof(sceNetcnfifList_t) * buf->data);
301 while ( sceNetcnfifDmaCheck(dmatid1) )
302 ;
303 }
304 my_free(list_iop);
305 my_free(list_ee);
306 }
307 else
308 {
309 my_free(list_iop);
310 retres1 = -2;
311 }
312 break;
313 case 2:
314 sceNetcnfifEnvInit(&env, mem_area, mem_area_size, buf->f_no_decode);
315 retres1 = sceNetCnfLoadEntry(buf->fname, buf->type, buf->usr_name, &env);
316 if ( retres1 < 0 )
317 break;
318 sceNetcnfifDataInit(&data);
319 retres1 = sceNetcnfifReadEnv(&data, &env, buf->type);
320 if ( retres1 < 0 )
321 break;
322 dmatid2 = sceNetcnfifSendEE((unsigned int)&data, buf->addr, sizeof(sceNetcnfifData_t));
323 while ( sceNetcnfifDmaCheck(dmatid2) )
324 ;
325 break;
326 case 3:
327 sceNetcnfifEnvInit(&env, mem_area, mem_area_size, buf->f_no_decode);
328 retres1 = sceNetcnfifWriteEnv(&env, &data, buf->type);
329 if ( retres1 >= 0 )
330 retres1 = sceNetCnfAddEntry(buf->fname, buf->type, buf->usr_name, &env);
331 break;
332 case 4:
333 sceNetcnfifEnvInit(&env, mem_area, mem_area_size, buf->f_no_decode);
334 retres1 = sceNetCnfLoadEntry(buf->fname, buf->type, buf->usr_name, &env);
335 if ( retres1 >= 0 )
336 {
337 env.mem_ptr = (void *)(((int)env.mem_ptr + 3) & ~3);
338 env.mem_base = env.mem_ptr;
339 retres1 = sceNetcnfifWriteEnv(&env, &data, buf->type);
340 if ( retres1 >= 0 )
341 retres1 = sceNetCnfEditEntry(buf->fname, buf->type, buf->usr_name, buf->new_usr_name, &env);
342 }
343 break;
344 case 5:
345 retres1 = sceNetCnfDeleteEntry(buf->fname, buf->type, buf->usr_name);
346 break;
347 case 6:
348 retres1 = sceNetCnfSetLatestEntry(buf->fname, buf->type, buf->usr_name);
349 break;
350 case 7:
351 retres1 = sceNetCnfDeleteAll(buf->fname);
352 break;
353 case 8:
354 retres1 = sceNetCnfCheckCapacity(buf->fname);
355 break;
356 case 9:
357 retres1 = sceNetCnfConvA2S(buf->fname, dp, sizeof(buf->fname));
358 break;
359 case 10:
360 sceNetcnfifEnvInit(&env, mem_area, mem_area_size, buf->f_no_decode);
361 retres1 = sceNetCnfCheckSpecialProvider(buf->fname, buf->type, buf->usr_name, &env);
362 break;
363 case 11:
364 callback.open = sce_callback_open;
365 callback.read = sce_callback_read;
366 callback.close = sce_callback_close;
367 callback.type = buf->type;
368 sce_callback_initialize();
369 sceNetCnfSetCallback(&callback);
370 break;
371 case 15:
372 sceNetCnfSetCallback(0);
373 break;
374 case 100:
375 buf->addr = (int)&data;
376 break;
377 case 101:
378 if ( mem_area )
379 {
380 break;
381 }
382 mem_area_size = buf->data;
383 mem_area = my_alloc(mem_area_size);
384 if ( !mem_area )
385 retres1 = -2;
386 break;
387 case 102:
388 if ( mem_area )
389 my_free(mem_area);
390 mem_area_size = 0;
391 mem_area = 0;
392 break;
393 case 103:
394 sceNetcnfifEnvInit(&env, mem_area, mem_area_size, buf->f_no_decode);
395 retres1 = sceNetcnfifWriteEnv(&env, &data, buf->type);
396 if ( retres1 < 0 )
397 break;
398 if ( env.root && env.root->pair_head && env.root->pair_head->ifc )
399 {
400 int redial_count;
401
402 redial_count = 0;
403 for ( i = 0; i < (int)(sizeof(env.root->pair_head->ifc->phone_numbers)
404 / sizeof(env.root->pair_head->ifc->phone_numbers[0]));
405 i += 1 )
406 {
407 if ( i < 3 && i >= 0 && env.root->pair_head->ifc->phone_numbers[i] )
408 redial_count += 1;
409 }
410 env.root->pair_head->ifc->redial_count = redial_count - 1;
411 if ( env.root->pair_head->ifc->pppoe != 1 && env.root->pair_head->ifc->type != 2 )
412 env.root->pair_head->ifc->type = env.root->pair_head->dev->type;
413 }
414 buf->addr = (int)&env;
415 break;
416 default:
417 break;
418 }
419 buf->data = retres1;
420 return buf;
421}
422
423static void sceNetcnfifInterfaceStart(void *userdata)
424{
425 (void)userdata;
426
427 sceSifInitRpc(0);
428 sceSifSetRpcQueue(&qd, GetThreadId());
429 sceSifRegisterRpc(&sd, 0x80001101, (SifRpcFunc_t)sceNetcnfifInterfaceServer, rpc_buf, 0, 0, &qd);
430 sceSifRpcLoop(&qd);
431}
432
433static void sceNetcnfifInterfaceStop(void)
434{
435 if ( mem_area )
436 {
437 my_free(mem_area);
438 mem_area_size = 0;
439 mem_area = 0;
440 }
441 sceSifRemoveRpc(&sd, &qd);
442 sceSifRemoveRpcQueue(&qd);
443}
444
445static void sceNetcnfifDataInit(sceNetcnfifData_t *data)
446{
447 memset(data, 0, sizeof(sceNetcnfifData_t));
448 data->ifc_type = -1;
449 data->mtu = -1;
450 data->ifc_idle_timeout = -1;
451 data->dev_type = -1;
452 data->phy_config = -1;
453 data->dialing_type = -1;
454 data->dev_idle_timeout = -1;
455 data->dhcp = -1;
456 data->dns1_nego = -1;
457 data->dns2_nego = -1;
458 data->f_auth = 0;
459 data->auth = 4;
460 data->pppoe = -1;
461 data->prc_nego = -1;
462 data->acc_nego = -1;
463 data->accm_nego = -1;
464}
465
466static void sceNetcnfifEnvInit(sceNetCnfEnv_t *env, void *mem_area, int size, int f_no_decode)
467{
468 memset(env, 0, sizeof(sceNetCnfEnv_t));
469 env->mem_ptr = mem_area;
470 env->mem_base = mem_area;
471 env->mem_last = (char *)mem_area + size;
472 env->f_no_decode = f_no_decode;
473}
474
475static int get_cmd(sceNetcnfifData_t *data, sceNetCnfCommand_t *p, int *ns_count)
476{
477 switch ( p->code )
478 {
479 case 1:
480 {
481 int retres;
482
483 switch ( *ns_count )
484 {
485 case 0:
486 retres =
487 sceNetCnfAddress2String(data->dns1_address, sizeof(data->dns1_address), &((nameserver_t *)p)->address);
488 break;
489 case 1:
490 retres =
491 sceNetCnfAddress2String(data->dns2_address, sizeof(data->dns2_address), &((nameserver_t *)p)->address);
492 break;
493 default:
494 return 0;
495 }
496 *ns_count += 1;
497 return retres;
498 }
499 case 3:
500 return sceNetCnfAddress2String(data->gateway, sizeof(data->gateway), &((route_t *)p)->re.gateway);
501 default:
502 break;
503 }
504 return 0;
505}
506
507static int get_attach(sceNetcnfifData_t *data, sceNetCnfInterface_t *p, int type)
508{
509 int cmd;
510 struct sceNetCnfCommand *cmd_head;
511
512 cmd = 0;
513 switch ( type )
514 {
515 case 1:
516 {
517 int i;
518
519 data->ifc_type = p->type;
520 data->dhcp = p->dhcp;
521 if ( p->dhcp_host_name )
522 strcpy(data->dhcp_host_name, (const char *)p->dhcp_host_name);
523 if ( p->address )
524 strcpy(data->address, (const char *)p->address);
525 if ( p->netmask )
526 strcpy(data->netmask, (const char *)p->netmask);
527 ns_count = 0;
528 for ( cmd_head = p->cmd_head; cmd_head; cmd_head = cmd_head->forw )
529 {
530 cmd = get_cmd(data, cmd_head, &ns_count);
531 if ( cmd < 0 )
532 return cmd;
533 }
534 for ( i = 0; i < (int)(sizeof(p->phone_numbers) / sizeof(p->phone_numbers[0])); i += 1 )
535 {
536 if ( !p->phone_numbers[i] )
537 {
538 continue;
539 }
540 switch ( i )
541 {
542 case 0:
543 strcpy(data->phone_numbers1, (const char *)p->phone_numbers[i]);
544 break;
545 case 1:
546 strcpy(data->phone_numbers2, (const char *)p->phone_numbers[i]);
547 break;
548 case 2:
549 strcpy(data->phone_numbers3, (const char *)p->phone_numbers[i]);
550 break;
551 }
552 }
553 if ( p->auth_name )
554 strcpy(data->auth_name, (const char *)p->auth_name);
555 if ( p->auth_key )
556 strcpy(data->auth_key, (const char *)p->auth_key);
557 if ( p->peer_name )
558 strcpy(data->peer_name, (const char *)p->peer_name);
559 data->dns1_nego = p->want.dns1_nego;
560 data->dns2_nego = p->want.dns2_nego;
561 data->f_auth = p->allow.f_auth;
562 data->auth = p->allow.auth;
563 data->pppoe = p->pppoe;
564 data->prc_nego = p->want.prc_nego;
565 data->acc_nego = p->want.acc_nego;
566 data->accm_nego = p->want.accm_nego;
567 data->mtu = p->mtu;
568 data->ifc_idle_timeout = p->idle_timeout;
569 }
570 break;
571 case 2:
572 {
573 data->dev_type = p->type;
574 if ( p->vendor )
575 strcpy(data->vendor, (const char *)p->vendor);
576 if ( p->product )
577 strcpy(data->product, (const char *)p->product);
578 data->phy_config = p->phy_config;
579 if (
580 !((char *)p->chat_additional)
581 || (cmd = sceNetCnfConvS2A((char *)p->chat_additional, data->chat_additional, sizeof(p->chat_additional)), cmd >= 0) )
582 {
583 if ( p->outside_number )
584 strcpy(data->outside_number, (const char *)p->outside_number);
585 if ( p->outside_delay )
586 strcpy(data->outside_delay, (const char *)p->outside_delay);
587 data->dialing_type = p->dialing_type;
588 data->dev_idle_timeout = p->idle_timeout;
589 }
590 break;
591 }
592 default:
593 break;
594 }
595 return cmd;
596}
597
598static int get_net(sceNetcnfifData_t *data, sceNetCnfRoot_t *p)
599{
600 struct sceNetCnfPair *pair;
601 int i;
602
603 i = 0;
604 for ( pair = p->pair_head; pair; pair = pair->forw )
605 {
606 sceNetcnfifDataInit(data);
607 strcpy(data->attach_ifc, (const char *)pair->attach_ifc);
608 strcpy(data->attach_dev, (const char *)pair->attach_dev);
609 if ( pair->ifc )
610 i = get_attach(data, pair->ifc, 1);
611 if ( pair->dev )
612 i = get_attach(data, pair->dev, 2);
613 }
614 return i;
615}
616
617static int sceNetcnfifReadEnv(sceNetcnfifData_t *data, sceNetCnfEnv_t *e, int type)
618{
619 if ( !type )
620 return get_net(data, e->root);
621 if ( type >= 0 && type < 3 )
622 return get_attach(data, e->ifc, type);
623 printf("[%s] unknown type (%d)\n", "sceNetcnfifReadEnv", type);
624 return 0;
625}
626
627static u8 *dup_string(sceNetCnfEnv_t *e, u8 *str)
628{
629 char *retval;
630
631 retval = (char *)sceNetCnfAllocMem(e, strlen((const char *)str) + 1, 0);
632 if ( !retval )
633 return 0;
634 strcpy(retval, (const char *)str);
635 return (u8 *)retval;
636}
637
638static void init_usrntcnf(sceNetCnfInterface_t *ifc)
639{
640 int i;
641
642 ifc->type = -1;
643 ifc->dhcp = -1;
644 ifc->dhcp_host_name = 0;
645 ifc->address = 0;
646 ifc->netmask = 0;
647 ifc->cmd_head = 0;
648 ifc->cmd_tail = 0;
649 for ( i = 0; i < 3; i += 1 )
650 {
651 ifc->phone_numbers[i] = 0;
652 }
653 ifc->want.dns1_nego = -1;
654 ifc->want.dns2_nego = -1;
655 ifc->pppoe = -1;
656 ifc->want.prc_nego = -1;
657 ifc->want.acc_nego = -1;
658 ifc->want.accm_nego = -1;
659 ifc->auth_name = 0;
660 ifc->auth_key = 0;
661 ifc->peer_name = 0;
662 ifc->allow.f_auth = 0;
663 ifc->allow.auth = 4;
664 ifc->mtu = -1;
665 ifc->phy_config = -1;
666 ifc->vendor = 0;
667 ifc->product = 0;
668 ifc->chat_additional = 0;
669 ifc->outside_number = 0;
670 ifc->outside_delay = 0;
671 ifc->dialing_type = -1;
672 ifc->idle_timeout = -1;
673}
674
675static int check_address(char *str)
676{
677 int retres;
678
679 retres = 0;
680 for ( ; *str; str += 1 )
681 {
682 if ( *str != '.' && *str != '0' )
683 retres = 1;
684 }
685 return retres;
686}
687
688static int put_gw(sceNetCnfEnv_t *e, const char *gw)
689{
690 int retres;
691
692 memset(&gateway, 0, sizeof(gateway));
693 gateway.cmd.code = 3;
694 gateway.cmd.back = e->ifc->cmd_tail;
695 if ( gateway.cmd.back )
696 gateway.cmd.back->forw = &gateway.cmd;
697 else
698 e->ifc->cmd_head = &gateway.cmd;
699 gateway.cmd.forw = 0;
700 e->ifc->cmd_tail = &gateway.cmd;
701 if ( gw )
702 {
703 retres = sceNetCnfName2Address(&gateway.re.dstaddr, 0);
704 if ( retres < 0 )
705 return retres;
706 retres = sceNetCnfName2Address(&gateway.re.gateway, gw);
707 if ( retres < 0 )
708 return retres;
709 retres = sceNetCnfName2Address(&gateway.re.genmask, 0);
710 if ( retres < 0 )
711 return retres;
712 gateway.re.flags |= 4u;
713 }
714 else
715 {
716 retres = sceNetCnfName2Address(&gateway.re.dstaddr, 0);
717 if ( retres < 0 )
718 return retres;
719 retres = sceNetCnfName2Address(&gateway.re.gateway, 0);
720 if ( retres < 0 )
721 return retres;
722 retres = sceNetCnfName2Address(&gateway.re.genmask, 0);
723 if ( retres < 0 )
724 return retres;
725 gateway.re.flags = 0;
726 }
727 return retres;
728}
729
730static int put_ns(sceNetCnfEnv_t *e, const char *ns, int ns_count)
731{
732 nameserver_t *ns1;
733 nameserver_t *ns2;
734
735 ns1 = 0;
736 switch ( ns_count )
737 {
738 case 1:
739 ns1 = &dns1;
740 ns2 = &dns1;
741 break;
742 case 2:
743 ns1 = &dns2;
744 ns2 = &dns2;
745 break;
746 default:
747 // Unofficial: return error instead of writing 1 to 0x00000008
748 return -1;
749 }
750 memset(ns2, 0, sizeof(nameserver_t));
751 ns1->cmd.code = 1;
752 ns1->cmd.back = e->ifc->cmd_tail;
753 if ( e->ifc->cmd_tail )
754 e->ifc->cmd_tail->forw = &ns1->cmd;
755 else
756 e->ifc->cmd_head = &ns1->cmd;
757 ns1->cmd.forw = 0;
758 e->ifc->cmd_tail = &ns1->cmd;
759 return sceNetCnfName2Address(&ns1->address, ns);
760}
761
762static int put_cmd(sceNetCnfEnv_t *e, sceNetcnfifData_t *data)
763{
764 int retres;
765
766 retres = !data->dhcp ? put_gw(e, (data->gateway[0] && check_address(data->gateway)) ? data->gateway : 0) : 0;
767 if ( data->dns1_address[0] && check_address(data->dns1_address) )
768 {
769 retres = put_ns(e, data->dns1_address, 1);
770 if ( data->dns2_address[0] && check_address(data->dns2_address) )
771 return put_ns(e, data->dns2_address, 2);
772 }
773 return retres;
774}
775
776static int root_link(sceNetCnfEnv_t *e, int type)
777{
778 struct sceNetCnfRoot *root;
779 struct sceNetCnfPair *p;
780 struct sceNetCnfPair *pair_tail;
781
782 if ( !e->ifc )
783 return 0;
784 root = e->root;
785 if ( !root )
786 {
787 e->root = (sceNetCnfRoot_t *)sceNetCnfAllocMem(e, sizeof(sceNetCnfRoot_t), 2);
788 if ( !e->root )
789 return -2;
790 e->root->version = 3;
791 e->root->redial_count = -1;
792 e->root->redial_interval = -1;
793 e->root->dialing_type = -1;
794 }
795 if ( !root || !root->pair_head )
796 {
797 p = (sceNetCnfPair_t *)sceNetCnfAllocMem(e, sizeof(sceNetCnfPair_t), 2);
798 if ( !p )
799 return -2;
800 switch ( type )
801 {
802 case 1:
803 p->ifc = e->ifc;
804 break;
805 case 2:
806 p->dev = e->ifc;
807 break;
808 default:
809 break;
810 }
811 pair_tail = e->root->pair_tail;
812 p->back = pair_tail;
813 if ( !pair_tail )
814 pair_tail = (sceNetCnfPair_t *)e->root;
815 pair_tail->forw = p;
816 p->forw = 0;
817 e->root->pair_tail = p;
818 return 0;
819 }
820 switch ( type )
821 {
822 case 1:
823 root->pair_head->ifc = e->ifc;
824 break;
825 case 2:
826 e->root->pair_head->dev = e->ifc;
827 break;
828 default:
829 break;
830 }
831 return 0;
832}
833
834static int put_attach(sceNetCnfEnv_t *e, sceNetcnfifData_t *data, int type)
835{
836 int retres;
837 int init_flag;
838 char chat_additional[256];
839
840 retres = 0;
841 if ( !e->ifc )
842 {
843 e->ifc = (sceNetCnfInterface_t *)sceNetCnfAllocMem(e, sizeof(sceNetCnfInterface_t), 2);
844 if ( !e->ifc )
845 return -2;
846 sceNetCnfInitIFC(e->ifc);
847 }
848 init_flag = 1;
849 init_usrntcnf(e->ifc);
850 switch ( type )
851 {
852 case 1:
853 if ( data->ifc_type != -1 )
854 {
855 init_flag = 0;
856 e->ifc->type = data->ifc_type;
857 }
858 if ( data->dhcp != 255 )
859 {
860 init_flag = 0;
861 e->ifc->dhcp = data->dhcp;
862 }
863 if ( data->dhcp_host_name[0] )
864 {
865 init_flag = 0;
866 e->ifc->dhcp_host_name = dup_string(e, (u8 *)data->dhcp_host_name);
867 }
868 if ( data->address[0] )
869 {
870 init_flag = 0;
871 e->ifc->address = dup_string(e, (u8 *)data->address);
872 }
873 if ( data->netmask[0] )
874 {
875 init_flag = 0;
876 e->ifc->netmask = dup_string(e, (u8 *)data->netmask);
877 }
878 retres = put_cmd(e, data);
879 if ( retres < 0 )
880 {
881 return retres;
882 }
883 if ( retres )
884 init_flag = 0;
885 if ( data->phone_numbers1[0] )
886 {
887 init_flag = 0;
888 e->ifc->phone_numbers[0] = dup_string(e, (u8 *)data->phone_numbers1);
889 }
890 if ( data->phone_numbers2[0] )
891 {
892 init_flag = 0;
893 e->ifc->phone_numbers[1] = dup_string(e, (u8 *)data->phone_numbers2);
894 }
895 if ( data->phone_numbers3[0] )
896 {
897 init_flag = 0;
898 e->ifc->phone_numbers[2] = dup_string(e, (u8 *)data->phone_numbers3);
899 }
900 if ( data->auth_name[0] )
901 {
902 init_flag = 0;
903 e->ifc->auth_name = dup_string(e, (u8 *)data->auth_name);
904 }
905 if ( data->auth_key[0] )
906 {
907 init_flag = 0;
908 e->ifc->auth_key = dup_string(e, (u8 *)data->auth_key);
909 }
910 if ( data->peer_name[0] )
911 {
912 init_flag = 0;
913 e->ifc->peer_name = dup_string(e, (u8 *)data->peer_name);
914 }
915 if ( data->dns1_nego != 255 )
916 {
917 init_flag = 0;
918 e->ifc->want.dns1_nego = data->dns1_nego;
919 }
920 if ( data->dns2_nego != 255 )
921 {
922 init_flag = 0;
923 e->ifc->want.dns2_nego = data->dns2_nego;
924 }
925 if ( data->f_auth )
926 {
927 init_flag = 0;
928 e->ifc->allow.f_auth = data->f_auth;
929 }
930 e->ifc->allow.auth = data->auth;
931 if ( data->pppoe != 255 )
932 {
933 init_flag = 0;
934 e->ifc->pppoe = data->pppoe;
935 }
936 if ( data->prc_nego != 255 )
937 {
938 init_flag = 0;
939 e->ifc->want.prc_nego = data->prc_nego;
940 }
941 if ( data->acc_nego != 255 )
942 {
943 init_flag = 0;
944 e->ifc->want.acc_nego = data->acc_nego;
945 }
946 if ( data->accm_nego != 255 )
947 {
948 init_flag = 0;
949 e->ifc->want.accm_nego = data->accm_nego;
950 }
951 if ( data->mtu != -1 )
952 {
953 init_flag = 0;
954 e->ifc->mtu = data->mtu;
955 }
956 if ( data->ifc_idle_timeout != -1 )
957 {
958 init_flag = 0;
959 e->ifc->idle_timeout = data->ifc_idle_timeout;
960 }
961 break;
962 case 2:
963 if ( data->dev_type != -1 )
964 {
965 init_flag = 0;
966 e->ifc->type = data->dev_type;
967 }
968 if ( data->vendor[0] )
969 {
970 init_flag = 0;
971 e->ifc->vendor = dup_string(e, (u8 *)data->vendor);
972 }
973 if ( data->product[0] )
974 {
975 init_flag = 0;
976 e->ifc->product = dup_string(e, (u8 *)data->product);
977 }
978 if ( data->phy_config != -1 )
979 {
980 init_flag = 0;
981 e->ifc->phy_config = data->phy_config;
982 }
983 if ( data->chat_additional[0] )
984 {
985 retres = sceNetCnfConvA2S(data->chat_additional, chat_additional, sizeof(data->chat_additional));
986 if ( retres < 0 )
987 return retres;
988 init_flag = 0;
989 e->ifc->chat_additional = dup_string(e, (u8 *)chat_additional);
990 }
991 if ( data->outside_number[0] )
992 {
993 init_flag = 0;
994 e->ifc->outside_number = dup_string(e, (u8 *)data->outside_number);
995 }
996 if ( data->outside_delay[0] )
997 {
998 init_flag = 0;
999 e->ifc->outside_delay = dup_string(e, (u8 *)data->outside_delay);
1000 }
1001 if ( data->dialing_type != -1 )
1002 {
1003 init_flag = 0;
1004 e->ifc->dialing_type = data->dialing_type;
1005 }
1006 if ( data->dev_idle_timeout != -1 )
1007 {
1008 init_flag = 0;
1009 e->ifc->idle_timeout = data->dev_idle_timeout;
1010 }
1011 break;
1012 default:
1013 break;
1014 }
1015 if ( init_flag )
1016 {
1017 e->ifc = 0;
1018 }
1019 return (!init_flag) ? ((!e->alloc_err) ? retres : -2) : -100;
1020}
1021
1022static int put_net(sceNetCnfEnv_t *e, sceNetcnfifData_t *data)
1023{
1024 struct sceNetCnfPair *p;
1025 struct sceNetCnfPair *pair_tail;
1026 int i;
1027 int attachres1;
1028 char display_name[256];
1029
1030 if ( !data->attach_ifc[0] || !data->attach_dev[0] )
1031 return -100;
1032 if ( !e->root )
1033 {
1034 e->root = (sceNetCnfRoot_t *)sceNetCnfAllocMem(e, sizeof(sceNetCnfRoot_t), 2);
1035 if ( !e->root )
1036 return -2;
1037 }
1038 e->root->version = 3;
1039 e->root->redial_count = -1;
1040 e->root->redial_interval = -1;
1041 e->root->dialing_type = -1;
1042 p = e->root->pair_head;
1043 if ( !p )
1044 {
1045 p = (sceNetCnfPair_t *)sceNetCnfAllocMem(e, sizeof(sceNetCnfPair_t), 2);
1046 if ( !p )
1047 return -2;
1048 pair_tail = e->root->pair_tail;
1049 p->back = pair_tail;
1050 if ( !pair_tail )
1051 pair_tail = (sceNetCnfPair_t *)e->root;
1052 pair_tail->forw = p;
1053 p->forw = 0;
1054 e->root->pair_tail = p;
1055 }
1056 strcpy(display_name, data->attach_ifc);
1057 strcat(display_name, " + ");
1058 strcat(display_name, data->attach_dev);
1059 p->display_name = dup_string(e, (u8 *)display_name);
1060 p->attach_ifc = dup_string(e, (u8 *)data);
1061 p->attach_dev = dup_string(e, (u8 *)data->attach_dev);
1062 for ( i = 0; i < 2; i += 1 )
1063 {
1064 e->ifc = 0;
1065 attachres1 = put_attach(e, data, i + 1);
1066 if ( attachres1 < 0 && attachres1 != -100 )
1067 break;
1068 attachres1 = root_link(e, i + 1);
1069 if ( attachres1 < 0 )
1070 break;
1071 }
1072 return (!e->alloc_err) ? attachres1 : -2;
1073}
1074
1075static int sceNetcnfifWriteEnv(sceNetCnfEnv_t *e, sceNetcnfifData_t *data, int type)
1076{
1077 int retres1;
1078
1079 retres1 = 0;
1080 switch ( type )
1081 {
1082 case 0:
1083 retres1 = put_net(e, data);
1084 break;
1085 case 1:
1086 case 2:
1087 case 3:
1088 {
1089 retres1 = put_attach(e, data, type);
1090 if ( retres1 < 0 )
1091 return retres1;
1092 retres1 = root_link(e, type);
1093 break;
1094 }
1095 default:
1096 printf("[%s] unknown type (%d)\n", "sceNetcnfifWriteEnv", type);
1097 break;
1098 }
1099 if ( retres1 >= 0 )
1100 {
1101 e->mem_ptr = (void *)(((int)e->mem_ptr + 3) & ~3);
1102 e->mem_base = e->mem_ptr;
1103 }
1104 return retres1;
1105}
1106
1107static int sceNetcnfifSendEE(unsigned int data, unsigned int addr, unsigned int size)
1108{
1109 int dmatid;
1110 SifDmaTransfer_t dmat;
1111
1112 dmat.src = (void *)data;
1113 dmat.dest = (void *)addr;
1114 dmat.size = (size & ~0x3F) + ((size & 0x3F) ? 64 : 0);
1115 dmat.attr = 0;
1116 dmatid = 0;
1117 while ( !dmatid )
1118 {
1119 CpuSuspendIntr(&oldstat);
1120 dmatid = sceSifSetDma(&dmat, 1);
1121 CpuResumeIntr(oldstat);
1122 }
1123 return dmatid;
1124}
1125
1126static int sceNetcnfifDmaCheck(int id)
1127{
1128 return sceSifDmaStat(id) >= 0;
1129}
1130
1131static void sce_callback_initialize(void)
1132{
1133 int i;
1134
1135 while ( 1 )
1136 {
1137 if ( sceSifBindRpc(&gcd, 0x80001101, 0) < 0 )
1138 {
1139 while ( 1 )
1140 ;
1141 }
1142 while ( sceSifCheckStatRpc(&gcd) )
1143 ;
1144 if ( gcd.server )
1145 break;
1146 for ( i = 0xFFFF; i != 0; i -= 1 )
1147 ;
1148 }
1149}
1150
1151static int sce_callback_open(const char *device, const char *pathname, int flags, int mode, int *filesize)
1152{
1153 gbuf[0] = flags;
1154 gbuf[1] = mode;
1155 gbuf[2] = strlen(device) + 1;
1156 gbuf[3] = strlen(pathname) + 1;
1157 memcpy(&gbuf[4], device, strlen(device) + 1);
1158 memcpy((char *)&gbuf[4] + strlen(device) + 1, pathname, strlen(pathname) + 1);
1159 if ( sceSifCallRpc(&gcd, 12, 0, gbuf, (strlen(pathname) + strlen(device) + 1 + 80) & ~0x3F, gbuf, 64, 0, 0) >= 0 )
1160 {
1161 *filesize = gbuf[1];
1162 return gbuf[0];
1163 }
1164 return -1;
1165}
1166
1167static int sce_callback_read(int fd, const char *device, const char *pathname, void *buf, int offset, int size)
1168{
1169 gbuf[0] = fd;
1170 gbuf[1] = strlen(device) + 1;
1171 gbuf[2] = strlen(pathname) + 1;
1172 gbuf[3] = offset;
1173 gbuf[4] = size;
1174 memcpy(&gbuf[5], device, strlen(device) + 1);
1175 memcpy((char *)&gbuf[5] + strlen(device) + 1, pathname, strlen(pathname) + 1);
1176 if (
1177 sceSifCallRpc(
1178 &gcd, 13, 0, gbuf, (strlen(pathname) + strlen(device) + 1 + 84) & ~0x3F, gbuf, (size + 67) & ~0x3F, 0, 0)
1179 < 0 )
1180 return -1;
1181 memcpy(buf, &gbuf[1], size);
1182 return gbuf[0];
1183}
1184
1185static int sce_callback_close(int fd)
1186{
1187 gbuf[0] = fd;
1188 return (sceSifCallRpc(&gcd, 14, 0, gbuf, 64, gbuf, 64, 0, 0) >= 0) ? gbuf[0] : -1;
1189}
1190
1191static int my_create_heap(void)
1192{
1193 if ( g_heap )
1194 return -2;
1195 g_heap = CreateHeap(1024, 1);
1196 return g_heap ? 0 : -1;
1197}
1198
1199static void *my_alloc(int size)
1200{
1201 return AllocHeapMemory(g_heap, size);
1202}
1203
1204static void my_free(void *ptr)
1205{
1206 if ( ptr )
1207 FreeHeapMemory(g_heap, ptr);
1208}
1209
1210static void my_delete_heap(void)
1211{
1212 DeleteHeap(g_heap);
1213 g_heap = 0;
1214}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
u16 newflags
Definition loadcore.h:36