PS2SDK
PS2 Homebrew Libraries
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
14 IRX_ID("Netcnf_Interface", 2, 30);
15 #endif
16 // Based on the module from SCE SDK 3.1.0.
17 
18 // TODO EE alignment 64
19 typedef 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
29 typedef 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 
73 typedef 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 
84 static void sceNetcnfifInterfaceStart(void *userdata);
85 static void sceNetcnfifInterfaceStop(void);
86 static void sceNetcnfifDataInit(sceNetcnfifData_t *data);
87 static void sceNetcnfifEnvInit(sceNetCnfEnv_t *env, void *mem_area, int size, int f_no_decode);
88 static int sceNetcnfifReadEnv(sceNetcnfifData_t *data, sceNetCnfEnv_t *e, int type);
89 static int sceNetcnfifWriteEnv(sceNetCnfEnv_t *e, sceNetcnfifData_t *data, int type);
90 static int sceNetcnfifSendEE(unsigned int data, unsigned int addr, unsigned int size);
91 static int sceNetcnfifDmaCheck(int id);
92 static void sce_callback_initialize(void);
93 static int sce_callback_open(const char *device, const char *pathname, int flags, int mode, int *filesize);
94 static int sce_callback_read(int fd, const char *device, const char *pathname, void *buf, int offset, int size);
95 static int sce_callback_close(int fd);
96 static int my_create_heap(void);
97 static void *my_alloc(int size);
98 static void my_free(void *ptr);
99 static void my_delete_heap(void);
100 
101 extern struct irx_export_table _exp_netcnfif;
102 // Unofficial: move to bss
103 static void *mem_area;
104 // Unofficial: move to bss
105 static int mem_area_size;
106 // Unofficial: move to bss
107 static void *g_heap;
108 static int g_tid;
109 static sceNetCnfEnv_t env;
110 static sceNetcnfifData_t data;
111 static char dp[0x100];
112 static int rpc_buf[1024];
113 static SifRpcServerData_t sd;
114 static SifRpcDataQueue_t qd;
115 static int ns_count;
116 static route_t gateway;
117 static nameserver_t dns1;
118 static nameserver_t dns2;
119 static int oldstat;
120 static SifRpcClientData_t gcd;
121 static int gbuf[1024];
122 
123 static 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 
133 static 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 
248 static 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 
258 int _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 
263 static 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 
423 static 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 
433 static 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 
445 static 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 
466 static 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 
475 static 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 
507 static 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 
598 static 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 
617 static 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 
627 static 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 
638 static 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 
675 static 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 
688 static 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 
730 static 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 
762 static 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 
776 static 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 
834 static 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 
1022 static 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 
1075 static 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 
1107 static 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 
1126 static int sceNetcnfifDmaCheck(int id)
1127 {
1128  return sceSifDmaStat(id) >= 0;
1129 }
1130 
1131 static 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 
1151 static 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 
1167 static 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 
1185 static 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 
1191 static 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 
1199 static void *my_alloc(int size)
1200 {
1201  return AllocHeapMemory(g_heap, size);
1202 }
1203 
1204 static void my_free(void *ptr)
1205 {
1206  if ( ptr )
1207  FreeHeapMemory(g_heap, ptr);
1208 }
1209 
1210 static void my_delete_heap(void)
1211 {
1212  DeleteHeap(g_heap);
1213  g_heap = 0;
1214 }
sceNetCnfEnv
Definition: netcnf.h:187
_ModuleInfo::newflags
u16 newflags
Definition: loadcore.h:36
sceNetCnfPair
Definition: netcnf.h:160
sceNetCnfCommand
Definition: netcnf.h:28
sceNetCnfRoot
Definition: netcnf.h:173
sceNetCnfCallback
Definition: netcnf.h:51
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
sceNetcnfifArg
Definition: netcnfif.c:73
nameserver
Definition: netcnf.h:228
sceNetCnfInterface
Definition: netcnf.h:84
route
Definition: netcnf.h:222
qd
static SifRpcDataQueue_t qd
Definition: rpc_server.c:33
irx_export_table
Definition: irx.h:90
_iop_thread
Definition: thbase.h:39
t_SifDmaTransfer
Definition: sifdma.h:52
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
t_SifRpcServerData
Definition: sifrpc-common.h:98
t_SifRpcDataQueue
Definition: sifrpc-common.h:153
t_SifRpcClientData
Definition: sifrpc-common.h:134
sceNetCnfList
Definition: netcnf.h:14
__attribute__
Definition: gif_registers.h:38
_ModuleInfo
Definition: loadcore.h:31