PS2SDK
PS2 Homebrew Libraries
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
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
38typedef struct pbuf PBuf;
39typedef struct netif NetIF;
40typedef struct ip4_addr IPAddr;
41
42static struct pbuf *TxHead, *TxTail;
43
44#define MODNAME "TCP/IP Stack"
45IRX_ID(MODNAME, 2, 3);
46
47extern struct irx_export_table _exp_ps2ip;
48
49#if NOSYS
50static int iTimerARP=0;
51
52#if defined(PS2IP_DHCP)
53static int iTimerDHCP=0;
54#endif //defined(PS2IP_DHCP)
55#endif
56
57int
58ps2ip_getconfig(char* pszName,t_ip_info* pInfo)
59{
60 NetIF* pNetIF=netif_find(pszName);
61
62 if (pNetIF==NULL)
63 {
64
65 //Net interface not found.
66
67 memset(pInfo,0,sizeof(*pInfo));
68 return 0;
69 }
70 strcpy(pInfo->netif_name,pszName);
71 pInfo->ipaddr.s_addr=pNetIF->ip_addr.addr;
72 pInfo->netmask.s_addr=pNetIF->netmask.addr;
73 pInfo->gw.s_addr=pNetIF->gw.addr;
74
75 memcpy(pInfo->hw_addr,pNetIF->hwaddr,sizeof(pInfo->hw_addr));
76
77#if LWIP_DHCP
78 struct dhcp *dhcp = netif_dhcp_data(pNetIF);
79
80 if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF))
81 {
82 pInfo->dhcp_enabled=1;
83 pInfo->dhcp_status=dhcp->state;
84 }
85 else
86 {
87 pInfo->dhcp_enabled=0;
88 pInfo->dhcp_status=DHCP_STATE_OFF;
89 }
90
91#else
92
93 pInfo->dhcp_enabled=0;
94
95#endif
96
97 return 1;
98}
99
100
101int
102ps2ip_setconfig(const t_ip_info* pInfo)
103{
104 NetIF* pNetIF=netif_find(pInfo->netif_name);
105
106 if (pNetIF==NULL)
107 {
108 return 0;
109 }
110
111#if LWIP_DHCP
112 struct dhcp *dhcp = netif_dhcp_data(pNetIF);
113
114 //Enable dhcp here
115
116 if (pInfo->dhcp_enabled)
117 {
118 if ((dhcp == NULL) || (dhcp->state == DHCP_STATE_OFF))
119 {
120 //Set initial IP address
121 netif_set_ipaddr(pNetIF,(const IPAddr*)&pInfo->ipaddr);
122 netif_set_netmask(pNetIF,(const IPAddr*)&pInfo->netmask);
123 netif_set_gw(pNetIF,(const IPAddr*)&pInfo->gw);
124
125 //Start DHCP client
126 dhcp_start(pNetIF);
127 }
128 }
129 else
130 {
131 if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF))
132 {
133 //Release DHCP lease
134 dhcp_release(pNetIF);
135
136 //Stop DHCP client
137 dhcp_stop(pNetIF);
138 }
139
140 netif_set_ipaddr(pNetIF,(const IPAddr*)&pInfo->ipaddr);
141 netif_set_netmask(pNetIF,(const IPAddr*)&pInfo->netmask);
142 netif_set_gw(pNetIF,(const IPAddr*)&pInfo->gw);
143 }
144#else
145 netif_set_ipaddr(pNetIF,(const IPAddr*)&pInfo->ipaddr);
146 netif_set_netmask(pNetIF,(const IPAddr*)&pInfo->netmask);
147 netif_set_gw(pNetIF,(const IPAddr*)&pInfo->gw);
148#endif
149
150 return 1;
151}
152
153static void InitDone(void* pvArg)
154{
155 dbgprintf("InitDone: TCPIP initialized\n");
156 sys_sem_signal((sys_sem_t*)pvArg);
157}
158
159#if NOSYS
160static void TimerThread(void* pvArg)
161{
162 while (1)
163 {
164 //TCP timer.
165 tcp_tmr();
166
167 //ARP timer.
168 iTimerARP+=TCP_TMR_INTERVAL;
169 if (iTimerARP>=ARP_TMR_INTERVAL)
170 {
171 iTimerARP-=ARP_TMR_INTERVAL;
172 etharp_tmr();
173 }
174
175#if defined(PS2IP_DHCP)
176
177 //DHCP timer.
178
179 iTimerDHCP+=TCP_TMR_INTERVAL;
180 if ((iTimerDHCP-TCP_TMR_INTERVAL)/DHCP_FINE_TIMER_MSECS!=iTimerDHCP/DHCP_FINE_TIMER_MSECS)
181 {
182 dhcp_fine_tmr();
183 }
184
185 if (iTimerDHCP>=DHCP_COARSE_TIMER_SECS*1000)
186 {
187 iTimerDHCP-=DHCP_COARSE_TIMER_SECS*1000;
188 dhcp_coarse_tmr();
189 }
190#endif
191
192 DelayThread(TCP_TMR_INTERVAL*250);
193 }
194}
195
196static inline void InitTimer(void)
197{
198 iop_thread_t Thread={TH_C, (u32)"PS2IP-timer", TimerThread, 0x300, 0x16};
199 int iTimerThreadID=CreateThread(&Thread);
200
201 if (iTimerThreadID<0)
202 {
203 printf("InitTimer: Fatal error - Failed to create tcpip timer-thread!\n");
204 }
205
206 //Start timer-thread
207 StartThread(iTimerThreadID, NULL);
208}
209#endif
210
211err_t
212ps2ip_input(PBuf* pInput,NetIF* pNetIF)
213{
214 err_t result;
215
216 if((result = pNetIF->input(pInput, pNetIF)) != ERR_OK)
217 pbuf_free(pInput);
218
219 return result;
220}
221
222int _exit(int argc, char *argv[])
223{
224 (void)argc;
225 (void)argv;
226
227 return MODULE_NO_RESIDENT_END; // return "not resident"!
228}
229
230static struct netif NIF;
231
232static void LinkStateUp(void){
233 tcpip_callback((void*)&netif_set_link_up, &NIF);
234}
235
236static void LinkStateDown(void){
237 tcpip_callback((void*)&netif_set_link_down, &NIF);
238}
239
240static void *AllocRxPacket(unsigned int size, void **payload)
241{
242 struct pbuf* pbuf;
243
244 if((pbuf = pbuf_alloc(PBUF_RAW, size, PBUF_POOL)) != NULL)
245 {
246 *payload = pbuf->payload;
247 }
248
249 return pbuf;
250}
251
252static void FreeRxPacket(void *packet)
253{
254 pbuf_free(packet);
255}
256
257static void EnQRxPacket(void *packet)
258{
259 ps2ip_input(packet, &NIF);
260}
261
262static int NextTxPacket(void **payload)
263{
264 int len;
265
266 if(TxTail != NULL)
267 {
268 *payload = TxTail->payload;
269 len = TxTail->len;
270 } else
271 len = 0;
272
273 return len;
274}
275
276static void DeQTxPacket(void)
277{
278 struct pbuf *toFree;
279 int OldState;
280
281 toFree = NULL;
282
283 CpuSuspendIntr(&OldState);
284 if(TxTail != NULL)
285 {
286 toFree = TxTail;
287
288 if(TxTail == TxHead) {
289 //Last in queue.
290 TxTail = NULL;
291 TxHead = NULL;
292 } else {
293 TxTail = TxTail->next;
294 }
295 }
296 CpuResumeIntr(OldState);
297
298 if(toFree != NULL)
299 {
300 toFree->next = NULL;
301 pbuf_free(toFree);
302 }
303}
304
305static void EnQTxPacket(struct pbuf *tx)
306{
307 int OldState;
308
309 CpuSuspendIntr(&OldState);
310
311 if(TxHead != NULL)
312 TxHead->next = tx;
313
314 TxHead = tx;
315 tx->next = NULL;
316
317 if(TxTail == NULL) //Queue empty
318 TxTail = TxHead;
319
320 CpuResumeIntr(OldState);
321}
322
323static err_t
324SMapLowLevelOutput(struct netif *pNetIF, struct pbuf* pOutput)
325{
326 err_t result;
327
328 (void)pNetIF;
329
330 result = ERR_OK;
331 if(pOutput->tot_len > pOutput->len)
332 {
333 struct pbuf* pbuf;
334
335 pbuf_ref(pOutput); //Increment reference count because LWIP must free the PBUF, not the driver!
336 if((pbuf = pbuf_coalesce(pOutput, PBUF_RAW)) != pOutput)
337 { //No need to increase reference count because pbuf_coalesce() does it.
338 EnQTxPacket(pbuf);
339 NetManNetIFXmit();
340 } else
341 result = ERR_MEM;
342 } else {
343 pbuf_ref(pOutput); //This will be freed later.
344 EnQTxPacket(pOutput);
345 NetManNetIFXmit();
346 }
347
348 return result;
349}
350
351//SMapOutput():
352
353//This function is called by the TCP/IP stack when an IP packet should be sent. It'll be invoked in the context of the
354//tcpip-thread, hence no synchronization is required.
355// For LWIP versions before v1.3.0.
356#ifdef PRE_LWIP_130_COMPAT
357static err_t
358SMapOutput(struct netif *pNetIF, struct pbuf *pOutput, IPAddr* pIPAddr)
359{
360 struct pbuf *pBuf=etharp_output(pNetIF,pIPAddr,pOutput);
361
362 return pBuf!=NULL ? SMapLowLevelOutput(pNetIF, pBuf):ERR_OK;
363}
364#endif
365
366//Should be called at the beginning of the program to set up the network interface.
367static err_t SMapIFInit(struct netif* pNetIF)
368{
369 TxHead = NULL;
370 TxTail = NULL;
371
372 pNetIF->name[0]='s';
373 pNetIF->name[1]='m';
374#ifdef PRE_LWIP_130_COMPAT
375 pNetIF->output=&SMapOutput; // For LWIP versions before v1.3.0.
376#else
377 pNetIF->output=&etharp_output; // For LWIP 1.3.0 and later.
378#endif
379 pNetIF->linkoutput=&SMapLowLevelOutput;
381#ifdef PRE_LWIP_130_COMPAT
382 pNetIF->flags|=(NETIF_FLAG_LINK_UP|NETIF_FLAG_BROADCAST); // For LWIP versions before v1.3.0.
383#else
384 pNetIF->flags|=(NETIF_FLAG_ETHARP|NETIF_FLAG_BROADCAST); // For LWIP v1.3.0 and later.
385#endif
386 pNetIF->mtu=1500;
387
388 //Get MAC address.
389 NetManIoctl(NETMAN_NETIF_IOCTL_ETH_GET_MAC, NULL, 0, pNetIF->hwaddr, sizeof(pNetIF->hwaddr));
390// DEBUG_PRINTF("MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",pNetIF->hwaddr[0],pNetIF->hwaddr[1],pNetIF->hwaddr[2],
391// pNetIF->hwaddr[3],pNetIF->hwaddr[4],pNetIF->hwaddr[5]);
392
393 return ERR_OK;
394}
395
396static inline int InitializeLWIP(void){
397 sys_sem_t Sema;
398 int result;
399
400 dbgprintf("PS2IP: Module Loaded.\n");
401
402 if ((result = RegisterLibraryEntries(&_exp_ps2ip))!=0)
403 {
404 printf("PS2IP: RegisterLibraryEntries returned: %d\n", result);
405 } else {
406 sys_sem_new(&Sema, 0);
407 dbgprintf("PS2IP: Calling tcpip_init\n");
408 tcpip_init(InitDone,&Sema);
409
410 sys_arch_sem_wait(&Sema, 0);
411 sys_sem_free(&Sema);
412
413 dbgprintf("PS2IP: tcpip_init called\n");
414#if NOSYS
415 InitTimer();
416#endif
417
418 dbgprintf("PS2IP: System Initialised\n");
419
420 result = 0;
421 }
422
423 return result;
424}
425
426static inline int InitLWIPStack(IPAddr *IP, IPAddr *NM, IPAddr *GW){
427 int result;
428 static struct NetManNetProtStack stack={
429 &LinkStateUp,
430 &LinkStateDown,
431 &AllocRxPacket,
432 &FreeRxPacket,
433 &EnQRxPacket,
434 &NextTxPacket,
435 &DeQTxPacket,
436 NULL,
437 NULL
438 };
439
440 if((result = InitializeLWIP()) != 0)
441 return result;
442
443 netif_add(&NIF, IP, NM, GW, NULL, &SMapIFInit, tcpip_input);
444 netif_set_default(&NIF);
445
446 NetManRegisterNetworkStack(&stack);
447 netif_set_up(&NIF);
448
449 return 0;
450}
451
452int _start(int argc, char *argv[]){
453 IPAddr IP, NM, GW;
454
455 //Parse IP address arguments.
456 if(argc>=4)
457 {
458 dbgprintf("SMAP: %s %s %s\n", argv[1],argv[2],argv[3]);
459 IP.addr=inet_addr(argv[1]);
460 NM.addr=inet_addr(argv[2]);
461 GW.addr=inet_addr(argv[3]);
462 }
463 else
464 {
465 //Set some defaults.
466 IP4_ADDR(&IP,192,168,0,80);
467 IP4_ADDR(&NM,255,255,255,0);
468 IP4_ADDR(&GW,192,168,0,1);
469 }
470
471 return InitLWIPStack(&IP, &NM, &GW)==0?MODULE_RESIDENT_END:MODULE_NO_RESIDENT_END;
472}
struct netif * netif_find(const char *name)
static err_t SMapIFInit(struct netif *pNetIF)
Definition ps2ip.c:272
#define NETIF_FLAG_LINK_UP
Definition tcpip.h:1095
#define NETIF_FLAG_ETHARP
Definition tcpip.h:1099
#define NETIF_FLAG_BROADCAST
Definition tcpip.h:1089
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
#define tcpip_callback(f, ctx)
Definition ps2ip.h:70
@ NETMAN_NETIF_IOCTL_ETH_GET_MAC
Definition netman.h:78
char name[2]
Definition tcpip.h:1315
u8 hwaddr_len
Definition tcpip.h:1309
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition tcpip.h:290
struct pbuf * next
Definition tcpip.h:202
void * payload
Definition tcpip.h:205
netif_output_fn output
Definition tcpip.h:1258
netif_input_fn input
Definition tcpip.h:1252
ip_addr_t ip_addr
Definition tcpip.h:1239
@ PBUF_POOL
Definition tcpip.h:195
#define NETIF_MAX_HWADDR_LEN
Definition tcpip.h:1071
u16 tot_len
Definition tcpip.h:214
u8 hwaddr[NETIF_MAX_HWADDR_LEN]
Definition tcpip.h:1311
u8 flags
Definition tcpip.h:1313
netif_linkoutput_fn linkoutput
Definition tcpip.h:1263
u16 len
Definition tcpip.h:217
@ PBUF_RAW
Definition tcpip.h:166
u16 mtu
Definition tcpip.h:1307
Definition tcpip.h:200