<dsbomb> hmm, there's no authentication .. this app could be sploited by people drivi...
[svpe-wii.git] / tcploader / wii / main.c
blob9235a029b91e60deba656d87a8d52879856a8a91
1 /*-------------------------------------------------------------
3 tcploader -- a very small tcp elf loader for the wii
5 Copyright (C) 2008 Sven Peter
7 This software is provided 'as-is', without any express or implied
8 warranty. In no event will the authors be held liable for any
9 damages arising from the use of this software.
11 Permission is granted to anyone to use this software for any
12 purpose, including commercial applications, and to alter it and
13 redistribute it freely, subject to the following restrictions:
15 1.The origin of this software must not be misrepresented; you
16 must not claim that you wrote the original software. If you use
17 this software in a product, an acknowledgment in the product
18 documentation would be appreciated but is not required.
20 2.Altered source versions must be plainly marked as such, and
21 must not be misrepresented as being the original software.
23 3.This notice may not be removed or altered from any source
24 distribution.
26 -------------------------------------------------------------*/
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ogcsys.h>
32 #include <gccore.h>
33 #include <ogc/ipc.h>
34 #include <network.h>
36 #define READ_SIZE (1 << 10)
38 #include "asm.h"
39 #include "processor.h"
40 #include "elf.h"
41 #include "dol.h"
44 static void *xfb = NULL;
45 static GXRModeObj *rmode = NULL;
47 u8 *data = (u8 *)0x92000000;
49 static inline void wait_for(u32 btn)
51 while(1)
53 PAD_ScanPads();
54 if(PAD_ButtonsHeld(0) & btn)
55 break;
56 VIDEO_WaitVSync();
61 extern s32 __STM_Init();
62 extern void __exception_closeall();
63 extern s32 __IOS_ShutdownSubsystems();
65 /* code to establish a socket; originally from bzs@bu-cs.bu.edu
68 int establish(unsigned short portnum) {
69 int s;
70 struct sockaddr_in sa;
72 memset(&sa, 0, sizeof(struct sockaddr_in)); /* clear our address */
73 sa.sin_family= AF_INET; /* this is our host address */
74 sa.sin_port= htons(portnum); /* this is our port number */
75 sa.sin_addr.s_addr = net_gethostip();
76 sa.sin_len = 8;
77 if ((s= net_socket(AF_INET, SOCK_STREAM, 0)) < 0) /* create socket */
78 return(-1);
79 if (net_bind(s,(struct sockaddr *)&sa,8) < 0) {
80 net_close(s);
81 return(-1); /* bind address to socket */
83 net_listen(s, 3); /* max # of queued connects */
84 return(s);
87 // wait for a connection to occur on a socket created with establish()
89 int get_connection(int s, struct sockaddr_in *sa)
91 int t; /* socket of connection */
92 // struct sockaddr_in sa;
93 sa->sin_len = 8;
94 sa->sin_family = AF_INET;
95 u32 buflen = 8;
96 t = net_accept(s,(struct sockaddr *)sa, &buflen);
97 printf("Incoming connection from %d.%d.%d.%d\n",
98 (sa->sin_addr.s_addr >> 24) & 0xFF,
99 (sa->sin_addr.s_addr >> 16) & 0xFF,
100 (sa->sin_addr.s_addr >> 8) & 0xFF,
101 (sa->sin_addr.s_addr) & 0xFF);
103 return t;
106 int read_data(int s, /* connected socket */
107 char *buf, /* pointer to the buffer */
108 int n /* number of characters (bytes) we want */
110 { int bcount; /* counts bytes read */
111 int br; /* bytes read this pass */
113 bcount= 0;
114 br= 0;
115 while (bcount < n) { /* loop until full buffer */
116 if ((br= net_read(s,buf,n-bcount)) > 0) {
117 bcount += br; /* increment byte counter */
118 buf += br; /* move buffer ptr for next read */
120 else if (br < 0) /* signal an error to the caller */
121 return br;
123 // debug_printf("read_data(%d, %p, %d): \n", s, buf, n);
124 // printf("read_data(%d, %p, %d): %d\n", s, buf, n, bcount);
125 return bcount;
128 int write_data(int s, char *buf, int n)
130 int bcount;
131 int br;
132 bcount = 0;
133 br = 0;
134 while(bcount < n) {
135 if ((br = net_write(s,buf,n-bcount)) > 0) {
136 bcount += br;
137 buf += br;
139 else if (br < 0)
140 return br;
142 // debug_printf("write_data(%d, %p, %d): \n", s, buf, n);
143 // hexdump(buf, bcount);
144 return (bcount);
147 int main(int argc, char **argv)
149 unsigned long level;
150 u32 res, offset, read, size, ip, client;
151 u8 *oct = (u8 *)&ip;
152 u8 *bfr[READ_SIZE];
153 struct sockaddr_in addr;
154 void (*ep)();
156 VIDEO_Init();
157 PAD_Init();
159 switch(VIDEO_GetCurrentTvMode())
161 case VI_PAL:
162 rmode = &TVPal528IntDf;
163 break;
164 case VI_MPAL:
165 rmode = &TVMpal480IntDf;
166 default:
167 case VI_NTSC:
168 rmode = &TVNtsc480IntDf;
169 break;
172 xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
173 console_init(xfb, 20, 20, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
175 VIDEO_Configure(rmode);
176 VIDEO_SetBlack(FALSE);
177 VIDEO_SetNextFramebuffer(xfb);
178 VIDEO_Flush();
179 VIDEO_WaitVSync();
180 if(rmode->viTVMode & VI_NON_INTERLACE)
181 VIDEO_WaitVSync();
183 __STM_Init();
185 printf("\n\nTCP ELF Loader\n");
186 printf("(c) 2008 Sven Peter\n");
187 printf("Based on bushing's title_listener.c and his networking code.\n");
188 printf("(c) 2008 bushing\n\n");
190 redo:
191 printf("Press A to continue.\n");
192 wait_for(PAD_BUTTON_A);
194 printf("net_init(), please wait...\n");
195 net_init();
198 printf("Opening socket on port 8080\n");
199 s32 listen = establish(8080);
201 if(listen < 0)
203 printf("establish() returned < 0.\n");
204 goto redo;
207 ip = net_gethostip();
208 printf("fd = %d\n", listen);
209 printf("You Wii's ip address is %d.%d.%d.%d\n", oct[0], oct[1], oct[2], oct[3]);
210 printf("Waiting for connection\n");
212 while(1)
214 client = get_connection(listen, &addr);
216 if(client > 0)
218 printf("client connected..\n");
219 printf("Please check the IP address and press A to continue\n");
220 wait_for(PAD_BUTTON_A);
222 if(((addr.sin_addr.s_addr >> 24) & 0xFF) != 192 || ((addr.sin_addr.s_addr >> 16) & 0xFF) != 168)
224 printf("WARNING: the client is not connecting from your local network.\n");
225 printf("Please check if you really want to run a file from this IP as it\n");
226 printf("may be something that bricks your wii from someone you don't even know!!\n");
227 printf("Press Z if you really want to continue!\n");
228 wait_for(PAD_TRIGGER_Z);
231 if(read_data(client, (char *)&size, 4) < 0)
233 printf("read_data() error while reading filesize\n");
234 net_close(client);
235 net_close(listen);
236 goto redo;
239 printf("size: %d\n", size);
240 printf("reading data, please wait...\n");
242 offset = 0;
243 while(offset < size && (read = read_data(client, (char *)bfr, (size - offset) > READ_SIZE ? READ_SIZE : (size - offset))) > 0)
245 memcpy(data + offset, bfr, READ_SIZE);
246 offset += read;
248 net_close(client);
249 net_close(listen);
251 res = valid_elf_image(data);
252 if(res != 1)
254 printf("Invalid ELF image.\n");
255 printf("assuming DOL image. your wii will crash if this is just some random file...\n");
256 ep = (void(*)())load_dol_image(data, 1);
258 else
260 printf("Loading ELF image...\n");
261 ep = (void(*)())load_elf_image(data);
263 printf("entry point: 0x%08X\n", (unsigned int)ep);
264 printf("shutting down...\n");
265 __IOS_ShutdownSubsystems();
266 _CPU_ISR_Disable(level);
267 __exception_closeall();
268 printf("jumping to entry point now...\n\n\n\n");
269 ep();
270 _CPU_ISR_Restore(level);
271 printf("this should not happen :/\n\n");
272 goto redo;
276 // never reached but fixes a gcc warning
277 return 0;