sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
ps2ip.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 <types.h>
17#include <stdio.h>
18#include <intrman.h>
19#include <netman.h>
20#include <loadcore.h>
21#include <thbase.h>
22#include <sysclib.h>
23#include <thevent.h>
24#include <sysmem.h>
25#include <lwip/memp.h>
26
27#include "lwip/sys.h"
28#include "lwip/tcp.h"
29#include "lwip/tcpip.h"
30#include "lwip/prot/dhcp.h"
31#include "lwip/netif.h"
32#include "lwip/dhcp.h"
33#include "lwip/inet.h"
34#include "netif/etharp.h"
35
36#include "ps2ip_internal.h"
37
38/* lwIP 2.2.1's sockets.c writes errno via set_errno(); the IOP IRX has no
39 libc-provided errno storage, so we define it here. The ".data" section
40 name (with leading dot) is critical: a bare "data" attribute creates a
41 separate section that the IRX loader never allocates into IOP RAM, so
42 every set_errno() write would corrupt random memory. */
43int errno __attribute__((section(".data")));
44
45typedef struct pbuf PBuf;
46typedef struct netif NetIF;
47typedef struct ip4_addr IPAddr;
48
49static struct pbuf *TxHead, *TxTail;
50
51#define MODNAME "TCP/IP Stack"
52IRX_ID(MODNAME, 2, 3);
53
54extern struct irx_export_table _exp_ps2ip;
55
56#if NOSYS
57static int iTimerARP=0;
58
59#if defined(PS2IP_DHCP)
60static int iTimerDHCP=0;
61#endif //defined(PS2IP_DHCP)
62#endif
63
64int
65ps2ip_getconfig(char* pszName,t_ip_info* pInfo)
66{
67 NetIF* pNetIF=netif_find(pszName);
68
69 if (pNetIF==NULL)
70 {
71
72 //Net interface not found.
73
74 memset(pInfo,0,sizeof(*pInfo));
75 return 0;
76 }
77 strcpy(pInfo->netif_name,pszName);
78 pInfo->ipaddr.s_addr=pNetIF->ip_addr.addr;
79 pInfo->netmask.s_addr=pNetIF->netmask.addr;
80 pInfo->gw.s_addr=pNetIF->gw.addr;
81
82 memcpy(pInfo->hw_addr,pNetIF->hwaddr,sizeof(pInfo->hw_addr));
83
84#if LWIP_DHCP
85 struct dhcp *dhcp = netif_dhcp_data(pNetIF);
86
87 if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF))
88 {
89 pInfo->dhcp_enabled=1;
90 pInfo->dhcp_status=dhcp->state;
91 }
92 else
93 {
94 pInfo->dhcp_enabled=0;
95 pInfo->dhcp_status=DHCP_STATE_OFF;
96 }
97
98#else
99
100 pInfo->dhcp_enabled=0;
101
102#endif
103
104 return 1;
105}
106
107
108int
109ps2ip_setconfig(const t_ip_info* pInfo)
110{
111 NetIF* pNetIF=netif_find(pInfo->netif_name);
112
113 if (pNetIF==NULL)
114 {
115 return 0;
116 }
117
118#if LWIP_DHCP
119 struct dhcp *dhcp = netif_dhcp_data(pNetIF);
120
121 //Enable dhcp here
122
123 if (pInfo->dhcp_enabled)
124 {
125 if ((dhcp == NULL) || (dhcp->state == DHCP_STATE_OFF))
126 {
127 //Set initial IP address
128 netif_set_ipaddr(pNetIF,(const IPAddr*)&pInfo->ipaddr);
129 netif_set_netmask(pNetIF,(const IPAddr*)&pInfo->netmask);
130 netif_set_gw(pNetIF,(const IPAddr*)&pInfo->gw);
131
132 //Start DHCP client
133 dhcp_start(pNetIF);
134 }
135 }
136 else
137 {
138 if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF))
139 {
140 //Release DHCP lease
141 dhcp_release(pNetIF);
142
143 //Stop DHCP client
144 dhcp_stop(pNetIF);
145 }
146
147 netif_set_ipaddr(pNetIF,(const IPAddr*)&pInfo->ipaddr);
148 netif_set_netmask(pNetIF,(const IPAddr*)&pInfo->netmask);
149 netif_set_gw(pNetIF,(const IPAddr*)&pInfo->gw);
150 }
151#else
152 netif_set_ipaddr(pNetIF,(const IPAddr*)&pInfo->ipaddr);
153 netif_set_netmask(pNetIF,(const IPAddr*)&pInfo->netmask);
154 netif_set_gw(pNetIF,(const IPAddr*)&pInfo->gw);
155#endif
156
157 return 1;
158}
159
160static void InitDone(void* pvArg)
161{
162 dbgprintf("InitDone: TCPIP initialized\n");
163 sys_sem_signal((sys_sem_t*)pvArg);
164}
165
166#if NOSYS
167static void TimerThread(void* pvArg)
168{
169 while (1)
170 {
171 //TCP timer.
172 tcp_tmr();
173
174 //ARP timer.
175 iTimerARP+=TCP_TMR_INTERVAL;
176 if (iTimerARP>=ARP_TMR_INTERVAL)
177 {
178 iTimerARP-=ARP_TMR_INTERVAL;
179 etharp_tmr();
180 }
181
182#if defined(PS2IP_DHCP)
183
184 //DHCP timer.
185
186 iTimerDHCP+=TCP_TMR_INTERVAL;
187 if ((iTimerDHCP-TCP_TMR_INTERVAL)/DHCP_FINE_TIMER_MSECS!=iTimerDHCP/DHCP_FINE_TIMER_MSECS)
188 {
189 dhcp_fine_tmr();
190 }
191
192 if (iTimerDHCP>=DHCP_COARSE_TIMER_SECS*1000)
193 {
194 iTimerDHCP-=DHCP_COARSE_TIMER_SECS*1000;
195 dhcp_coarse_tmr();
196 }
197#endif
198
199 DelayThread(TCP_TMR_INTERVAL*250);
200 }
201}
202
203static inline void InitTimer(void)
204{
205 iop_thread_t Thread={TH_C, (u32)"PS2IP-timer", TimerThread, 0x300, 0x16};
206 int iTimerThreadID=CreateThread(&Thread);
207
208 if (iTimerThreadID<0)
209 {
210 printf("InitTimer: Fatal error - Failed to create tcpip timer-thread!\n");
211 }
212
213 //Start timer-thread
214 StartThread(iTimerThreadID, NULL);
215}
216#endif
217
218err_t
219ps2ip_input(PBuf* pInput,NetIF* pNetIF)
220{
221 err_t result;
222
223 if((result = pNetIF->input(pInput, pNetIF)) != ERR_OK)
224 pbuf_free(pInput);
225
226 return result;
227}
228
229int _exit(int argc, char *argv[])
230{
231 (void)argc;
232 (void)argv;
233
234 return MODULE_NO_RESIDENT_END; // return "not resident"!
235}
236
237static struct netif NIF;
238
239static void LinkStateUp(void){
240 tcpip_callback((void*)&netif_set_link_up, &NIF);
241}
242
243static void LinkStateDown(void){
244 tcpip_callback((void*)&netif_set_link_down, &NIF);
245}
246
247static void *AllocRxPacket(unsigned int size, void **payload)
248{
249 struct pbuf* pbuf;
250
251 if((pbuf = pbuf_alloc(PBUF_RAW, size, PBUF_POOL)) != NULL)
252 {
253 *payload = pbuf->payload;
254 }
255
256 return pbuf;
257}
258
259static void FreeRxPacket(void *packet)
260{
261 pbuf_free(packet);
262}
263
264static void EnQRxPacket(void *packet)
265{
266 ps2ip_input(packet, &NIF);
267}
268
269static int NextTxPacket(void **payload)
270{
271 int len;
272
273 if(TxTail != NULL)
274 {
275 *payload = TxTail->payload;
276 len = TxTail->len;
277 } else
278 len = 0;
279
280 return len;
281}
282
283static void DeQTxPacket(void)
284{
285 struct pbuf *toFree;
286 int OldState;
287
288 toFree = NULL;
289
290 CpuSuspendIntr(&OldState);
291 if(TxTail != NULL)
292 {
293 toFree = TxTail;
294
295 if(TxTail == TxHead) {
296 //Last in queue.
297 TxTail = NULL;
298 TxHead = NULL;
299 } else {
300 TxTail = TxTail->next;
301 }
302 }
303 CpuResumeIntr(OldState);
304
305 if(toFree != NULL)
306 {
307 toFree->next = NULL;
308 pbuf_free(toFree);
309 }
310}
311
312static void EnQTxPacket(struct pbuf *tx)
313{
314 int OldState;
315
316 CpuSuspendIntr(&OldState);
317
318 if(TxHead != NULL)
319 TxHead->next = tx;
320
321 TxHead = tx;
322 tx->next = NULL;
323
324 if(TxTail == NULL) //Queue empty
325 TxTail = TxHead;
326
327 CpuResumeIntr(OldState);
328}
329
330static err_t
331SMapLowLevelOutput(struct netif *pNetIF, struct pbuf* pOutput)
332{
333 err_t result;
334
335 (void)pNetIF;
336
337 result = ERR_OK;
338 if(pOutput->tot_len > pOutput->len)
339 {
340 struct pbuf* pbuf;
341
342 pbuf_ref(pOutput); //Increment reference count because LWIP must free the PBUF, not the driver!
343 if((pbuf = pbuf_coalesce(pOutput, PBUF_RAW)) != pOutput)
344 { //No need to increase reference count because pbuf_coalesce() does it.
345 EnQTxPacket(pbuf);
346 NetManNetIFXmit();
347 } else
348 result = ERR_MEM;
349 } else {
350 pbuf_ref(pOutput); //This will be freed later.
351 EnQTxPacket(pOutput);
352 NetManNetIFXmit();
353 }
354
355 return result;
356}
357
358//Should be called at the beginning of the program to set up the network interface.
359static err_t SMapIFInit(struct netif* pNetIF)
360{
361 TxHead = NULL;
362 TxTail = NULL;
363
364 pNetIF->name[0]='s';
365 pNetIF->name[1]='m';
366 pNetIF->output=&etharp_output;
367 pNetIF->linkoutput=&SMapLowLevelOutput;
370 pNetIF->mtu=1500;
371
372 //Get MAC address.
373 NetManIoctl(NETMAN_NETIF_IOCTL_ETH_GET_MAC, NULL, 0, pNetIF->hwaddr, sizeof(pNetIF->hwaddr));
374// DEBUG_PRINTF("MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",pNetIF->hwaddr[0],pNetIF->hwaddr[1],pNetIF->hwaddr[2],
375// pNetIF->hwaddr[3],pNetIF->hwaddr[4],pNetIF->hwaddr[5]);
376
377 return ERR_OK;
378}
379
380static inline int InitializeLWIP(void){
381 sys_sem_t Sema;
382 int result;
383
384 dbgprintf("PS2IP: Module Loaded.\n");
385
386 if ((result = RegisterLibraryEntries(&_exp_ps2ip))!=0)
387 {
388 printf("PS2IP: RegisterLibraryEntries returned: %d\n", result);
389 } else {
390 sys_sem_new(&Sema, 0);
391 dbgprintf("PS2IP: Calling tcpip_init\n");
392 tcpip_init(InitDone,&Sema);
393
394 sys_arch_sem_wait(&Sema, 0);
395 sys_sem_free(&Sema);
396
397 dbgprintf("PS2IP: tcpip_init called\n");
398#if NOSYS
399 InitTimer();
400#endif
401
402 dbgprintf("PS2IP: System Initialised\n");
403
404 result = 0;
405 }
406
407 return result;
408}
409
410static inline int InitLWIPStack(IPAddr *IP, IPAddr *NM, IPAddr *GW){
411 int result;
412 static struct NetManNetProtStack stack={
413 &LinkStateUp,
414 &LinkStateDown,
415 &AllocRxPacket,
416 &FreeRxPacket,
417 &EnQRxPacket,
418 &NextTxPacket,
419 &DeQTxPacket,
420 NULL,
421 NULL
422 };
423
424 if((result = InitializeLWIP()) != 0)
425 return result;
426
427 netif_add(&NIF, IP, NM, GW, NULL, &SMapIFInit, tcpip_input);
428 netif_set_default(&NIF);
429
430 NetManRegisterNetworkStack(&stack);
431 netif_set_up(&NIF);
432
433 return 0;
434}
435
436int _start(int argc, char *argv[]){
437 IPAddr IP, NM, GW;
438
439 //Parse IP address arguments.
440 if(argc>=4)
441 {
442 dbgprintf("SMAP: %s %s %s\n", argv[1],argv[2],argv[3]);
443 IP.addr=inet_addr(argv[1]);
444 NM.addr=inet_addr(argv[2]);
445 GW.addr=inet_addr(argv[3]);
446 }
447 else
448 {
449 //Set some defaults.
450 IP4_ADDR(&IP,192,168,0,80);
451 IP4_ADDR(&NM,255,255,255,0);
452 IP4_ADDR(&GW,192,168,0,1);
453 }
454
455 return InitLWIPStack(&IP, &NM, &GW)==0?MODULE_RESIDENT_END:MODULE_NO_RESIDENT_END;
456}
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition tcpip.h:328
#define NETIF_MAX_HWADDR_LEN
Definition tcpip.h:1109
void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg)
Definition tcpip.c:659
err_t tcpip_callback(tcpip_callback_fn function, void *ctx)
Definition tcpip.c:323
err_t tcpip_input(struct pbuf *p, struct netif *inp)
Definition tcpip.c:297
@ ERR_OK
Definition err.h:55
@ ERR_MEM
Definition err.h:57
#define NETIF_FLAG_ETHERNET
Definition tcpip.h:1141
#define NETIF_FLAG_ETHARP
Definition tcpip.h:1137
#define NETIF_FLAG_BROADCAST
Definition tcpip.h:1127
void netif_set_link_down(struct netif *netif)
Definition netif.c:1056
struct netif * netif_find(const char *name)
Definition netif.c:1755
struct netif * netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input)
Definition netif.c:287
void netif_set_default(struct netif *netif)
Definition netif.c:849
void netif_set_link_up(struct netif *netif)
Definition netif.c:1018
void netif_set_up(struct netif *netif)
Definition netif.c:871
struct pbuf * pbuf_coalesce(struct pbuf *p, pbuf_layer layer)
Definition pbuf.c:1318
void pbuf_ref(struct pbuf *p)
Definition pbuf.c:833
u8 pbuf_free(struct pbuf *p)
Definition pbuf.c:729
@ PBUF_POOL
Definition tcpip.h:229
@ PBUF_RAW
Definition tcpip.h:200
void sys_sem_free(sys_sem_t *sem)
Definition sys_arch.c:334
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
Definition sys_arch.c:289
void sys_sem_signal(sys_sem_t *sem)
Definition sys_arch.c:329
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition sys_arch.c:263
int CpuResumeIntr(int state)
Definition intrman.c:217
int CpuSuspendIntr(int *state)
Definition intrman.c:195
@ NETMAN_NETIF_IOCTL_ETH_GET_MAC
Definition netman.h:83
u8 hwaddr_len
Definition tcpip.h:1347
netif_output_fn output
Definition tcpip.h:1296
netif_input_fn input
Definition tcpip.h:1290
ip_addr_t ip_addr
Definition tcpip.h:1277
char name[2]
Definition tcpip.h:1353
u8 hwaddr[NETIF_MAX_HWADDR_LEN]
Definition tcpip.h:1349
u8 flags
Definition tcpip.h:1351
netif_linkoutput_fn linkoutput
Definition tcpip.h:1301
u16 mtu
Definition tcpip.h:1345
Definition tcpip.h:234
void * payload
Definition tcpip.h:239
struct pbuf * next
Definition tcpip.h:236
u16 tot_len
Definition tcpip.h:248
u16 len
Definition tcpip.h:251