new version of OskitDumpBuffer() that shows ascii characters, too, for easier debugging
[reactos.git] / reactos / drivers / lib / oskittcp / oskittcp / interface.c
1 #include <stdio.h>
2 #include <oskittcp.h>
3 #include <oskitdebug.h>
4 #include <sys/param.h>
5 #include <sys/systm.h>
6 #include <sys/socket.h>
7 #include <sys/kernel.h>
8 #include <sys/filedesc.h>
9 #include <sys/proc.h>
10 #include <sys/fcntl.h>
11 #include <sys/file.h>
12 #include <sys/mbuf.h>
13 #include <sys/protosw.h>
14 #include <sys/socket.h>
15 #include <sys/socketvar.h>
16 #include <sys/uio.h>
17
18 #ifdef WIN32
19 #define snprintf _snprintf
20 #endif//WIN32
21
22 struct linker_set domain_set;
23
24 OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 };
25
26 OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
27
28 /* SPL */
29 unsigned cpl;
30 unsigned net_imask;
31 unsigned volatile ipending;
32 struct timeval boottime;
33
34 void *fbsd_malloc( unsigned int bytes, ... ) {
35 if( !OtcpEvent.TCPMalloc ) panic("no malloc");
36 return OtcpEvent.TCPMalloc
37 ( OtcpEvent.ClientData, (OSK_UINT)bytes, "*", 0 );
38 }
39
40 void fbsd_free( void *data, ... ) {
41 if( !OtcpEvent.TCPFree ) panic("no free");
42 OtcpEvent.TCPFree( OtcpEvent.ClientData, data, "*", 0 );
43 }
44
45 void InitOskitTCP() {
46 OS_DbgPrint(OSK_MID_TRACE,("Init Called\n"));
47 OS_DbgPrint(OSK_MID_TRACE,("MB Init\n"));
48 mbinit();
49 OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n"));
50 rip_init();
51 raw_init();
52 OS_DbgPrint(OSK_MID_TRACE,("Route Init\n"));
53 route_init();
54 OS_DbgPrint(OSK_MID_TRACE,("Init fake freebsd scheduling\n"));
55 init_freebsd_sched();
56 OS_DbgPrint(OSK_MID_TRACE,("Init clock\n"));
57 clock_init();
58 OS_DbgPrint(OSK_MID_TRACE,("Init TCP\n"));
59 tcp_init();
60 OS_DbgPrint(OSK_MID_TRACE,("Init routing\n"));
61 domaininit();
62 OS_DbgPrint(OSK_MID_TRACE,("Init Finished\n"));
63 tcp_iss = 1024;
64 }
65
66 void DeinitOskitTCP() {
67 }
68
69 void TimerOskitTCP() {
70 tcp_slowtimo();
71 tcp_fasttimo();
72 }
73
74 void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) {
75 memcpy( &OtcpEvent, EventHandlers, sizeof(OtcpEvent) );
76 if( OtcpEvent.PacketSend )
77 OS_DbgPrint(OSK_MID_TRACE,("SendPacket handler registered: %x\n",
78 OtcpEvent.PacketSend));
79 }
80
81 void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len )
82 {
83 unsigned int i;
84 char line[81];
85 static const char* hex = "0123456789abcdef";
86
87 for ( i = 0; i < Len; i++ )
88 {
89 int align = i & 0xf;
90 int align3 = (align<<1) + align;
91 unsigned char c = Data[i];
92 if ( !align )
93 {
94 if ( i ) DbgPrint( line );
95 snprintf ( line, sizeof(line)-1, "%08x: \n", Data );
96 line[sizeof(line)-1] = '\0';
97 }
98
99 line[10+align3] = hex[(c>>4)&0xf];
100 line[11+align3] = hex[c&0xf];
101 if ( !isprint(c) )
102 c = '.';
103 line[59+align] = c;
104 }
105 if ( Len & 0xf )
106 DbgPrint ( line );
107 }
108
109 /* From uipc_syscalls.c */
110
111 int OskitTCPSocket( void *context,
112 void **aso,
113 int domain,
114 int type,
115 int proto )
116 {
117 struct socket *so;
118 int error = socreate(domain, &so, type, proto);
119 if( !error ) {
120 so->so_connection = context;
121 so->so_state = SS_NBIO;
122 *aso = so;
123 }
124 return error;
125 }
126
127 int OskitTCPRecv( void *connection,
128 OSK_PCHAR Data,
129 OSK_UINT Len,
130 OSK_UINT *OutLen,
131 OSK_UINT Flags ) {
132 char *output_ptr = Data;
133 struct uio uio = { 0 };
134 struct iovec iov = { 0 };
135 int error = 0;
136 int tcp_flags = 0;
137 int tocopy = 0;
138
139 *OutLen = 0;
140
141 if( Flags & OSK_MSG_OOB ) tcp_flags |= MSG_OOB;
142 if( Flags & OSK_MSG_DONTWAIT ) tcp_flags |= MSG_DONTWAIT;
143 if( Flags & OSK_MSG_PEEK ) tcp_flags |= MSG_PEEK;
144
145 uio.uio_resid = Len;
146 uio.uio_iov = &iov;
147 uio.uio_rw = UIO_READ;
148 uio.uio_iovcnt = 1;
149 iov.iov_len = Len;
150 iov.iov_base = Data;
151
152 OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
153
154 error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */,
155 &tcp_flags );
156
157 if( error == 0 ) {
158 OS_DbgPrint(OSK_MID_TRACE,("Successful read from TCP:\n"));
159 *OutLen = Len - uio.uio_resid;
160 OskitDumpBuffer( Data, *OutLen );
161 }
162
163 return error;
164 }
165
166 static int
167 getsockaddr(namp, uaddr, len)
168 /* [<][>][^][v][top][bottom][index][help] */
169 struct sockaddr **namp;
170 caddr_t uaddr;
171 size_t len;
172 {
173 struct sockaddr *sa;
174 int error;
175
176 if (len > SOCK_MAXADDRLEN)
177 return ENAMETOOLONG;
178 MALLOC(sa, struct sockaddr *, len, M_SONAME, M_WAITOK);
179 error = copyin(uaddr, sa, len);
180 if (error) {
181 FREE(sa, M_SONAME);
182 } else {
183 *namp = sa;
184 }
185 return error;
186 }
187
188 int OskitTCPBind( void *socket, void *connection,
189 void *nam, OSK_UINT namelen ) {
190 int error = EFAULT;
191 struct socket *so = socket;
192 struct mbuf sabuf = { 0 };
193 struct sockaddr addr;
194
195 OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
196
197 if( nam )
198 addr = *((struct sockaddr *)nam);
199
200 sabuf.m_data = (void *)&addr;
201 sabuf.m_len = sizeof(addr);
202
203 addr.sa_family = addr.sa_len;
204 addr.sa_len = sizeof(struct sockaddr);
205
206 OskitDumpBuffer( (OSK_PCHAR)&addr, sizeof(addr) );
207
208 error = sobind(so, &sabuf);
209
210 OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
211 return (error);
212 }
213
214 int OskitTCPConnect( void *socket, void *connection,
215 void *nam, OSK_UINT namelen ) {
216 struct socket *so = socket;
217 struct connect_args _uap = {
218 0, nam, namelen
219 }, *uap = &_uap;
220 int error = EFAULT, s;
221 struct mbuf sabuf = { 0 };
222 struct sockaddr addr;
223
224 OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
225
226 so->so_connection = connection;
227
228 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
229 error = EALREADY;
230 goto done;
231 }
232
233 OS_DbgPrint(OSK_MIN_TRACE,("Nam: %x\n", nam));
234 if( nam )
235 addr = *((struct sockaddr *)nam);
236
237 sabuf.m_data = (void *)&addr;
238 sabuf.m_len = sizeof(addr);
239
240 addr.sa_family = addr.sa_len;
241 addr.sa_len = sizeof(struct sockaddr);
242
243 error = soconnect(so, &sabuf);
244
245 if (error)
246 goto bad;
247
248 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
249 error = EINPROGRESS;
250 goto done;
251 }
252
253 bad:
254 so->so_state &= ~SS_ISCONNECTING;
255
256 if (error == ERESTART)
257 error = EINTR;
258
259 done:
260 OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
261 return (error);
262 }
263
264 int OskitTCPClose( void *socket ) {
265 struct socket *so = socket;
266 so->so_connection = 0;
267 soclose( so );
268 return 0;
269 }
270
271 int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
272 OSK_UINT *OutLen, OSK_UINT flags ) {
273 struct mbuf* m = m_devget( Data, Len, 0, NULL, NULL );
274 int error = 0;
275 if ( !m )
276 return ENOBUFS;
277 OskitDumpBuffer( Data, Len );
278 error = sosend( socket, NULL, NULL, m, NULL, 0 );
279 *OutLen = Len;
280 return error;
281 }
282
283 int OskitTCPAccept( void *socket,
284 void *AddrOut,
285 OSK_UINT AddrLen,
286 OSK_UINT *OutAddrLen ) {
287 struct mbuf nam;
288 int error;
289
290 nam.m_data = AddrOut;
291 nam.m_len = AddrLen;
292
293 return soaccept( socket, &nam );
294 }
295
296 /* The story so far
297 *
298 * We have a packet. While we store the fields we want in host byte order
299 * outside the original packet, the bsd stack modifies them in place.
300 */
301
302 void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
303 OSK_UINT IpHeaderLen ) {
304 struct mbuf *Ip = m_devget( Data, Len, 0, NULL, NULL );
305 struct ip *iph;
306
307 if( !Ip ) return; /* drop the segment */
308
309 //memcpy( Ip->m_data, Data, Len );
310 Ip->m_pkthdr.len = IpHeaderLen;
311
312 /* Do the transformations on the header that tcp_input expects */
313 iph = mtod(Ip, struct ip *);
314 NTOHS(iph->ip_len);
315 iph->ip_len -= sizeof(struct ip);
316
317 OS_DbgPrint(OSK_MAX_TRACE,
318 ("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len,
319 IpHeaderLen));
320
321 OskitDumpBuffer( Data, Len );
322
323 tcp_input(Ip, IpHeaderLen);
324
325 /* The buffer Ip is freed by tcp_input */
326 }
327
328 int OskitTCPListen( void *socket, int backlog ) {
329 return solisten( socket, backlog );
330 }
331
332 void OskitTCPSetAddress( void *socket,
333 OSK_UINT LocalAddress,
334 OSK_UI16 LocalPort,
335 OSK_UINT RemoteAddress,
336 OSK_UI16 RemotePort ) {
337 struct socket *so = socket;
338 struct inpcb *inp = so->so_pcb;
339 inp->inp_laddr.s_addr = LocalAddress;
340 inp->inp_lport = LocalPort;
341 inp->inp_faddr.s_addr = RemoteAddress;
342 inp->inp_fport = RemotePort;
343 DbgPrint("OSKIT: SET ADDR %x:%x -> %x:%x\n",
344 LocalAddress, LocalPort,
345 RemoteAddress, RemotePort);
346 }
347
348 void OskitTCPGetAddress( void *socket,
349 OSK_UINT *LocalAddress,
350 OSK_UI16 *LocalPort,
351 OSK_UINT *RemoteAddress,
352 OSK_UI16 *RemotePort ) {
353 struct socket *so = socket;
354 struct inpcb *inp = so ? so->so_pcb : 0;
355 if( inp ) {
356 *LocalAddress = inp->inp_laddr.s_addr;
357 *LocalPort = inp->inp_lport;
358 *RemoteAddress = inp->inp_faddr.s_addr;
359 *RemotePort = inp->inp_fport;
360 DbgPrint("OSKIT: GET ADDR %x:%x -> %x:%x\n",
361 *LocalAddress, *LocalPort,
362 *RemoteAddress, *RemotePort);
363 }
364 }
365
366 struct ifaddr *ifa_iffind(struct sockaddr *addr, int type)
367 {
368 if( OtcpEvent.FindInterface )
369 return OtcpEvent.FindInterface( OtcpEvent.ClientData,
370 PF_INET,
371 type,
372 addr );
373 else
374 return NULL;
375 }
376
377 void oskittcp_die( const char *file, int line ) {
378 DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file, line);
379 *((int *)0) = 0;
380 }
381
382 /* Stuff supporting the BSD network-interface interface */
383 struct ifaddr **ifnet_addrs;
384 struct ifnet *ifnet;
385
386 void
387 ifinit()
388 {
389 }
390
391
392 void
393 if_attach(ifp)
394 struct ifnet *ifp;
395 {
396 panic("if_attach\n");
397 }
398
399 struct ifnet *
400 ifunit(char *name)
401 {
402 return 0;
403 }
404
405 /*
406 * Handle interface watchdog timer routines. Called
407 * from softclock, we decrement timers (if set) and
408 * call the appropriate interface routine on expiration.
409 */
410 void
411 if_slowtimo(arg)
412 void *arg;
413 {
414 #if 0
415 register struct ifnet *ifp;
416 int s = splimp();
417
418 for (ifp = ifnet; ifp; ifp = ifp->if_next) {
419 if (ifp->if_timer == 0 || --ifp->if_timer)
420 continue;
421 if (ifp->if_watchdog)
422 (*ifp->if_watchdog)(ifp->if_unit);
423 }
424 splx(s);
425 timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ);
426 #endif
427 }
428
429 /*
430 * Locate an interface based on a complete address.
431 */
432
433 /*ARGSUSED*/
434 struct ifaddr *ifa_ifwithaddr(addr)
435 struct sockaddr *addr;
436 {
437 struct ifaddr *ifaddr = ifa_ifwithnet( addr );
438 struct sockaddr_in *addr_in;
439 struct sockaddr_in *faddr_in;
440
441 if( !ifaddr ) {
442 OS_DbgPrint(OSK_MID_TRACE,("No ifaddr\n"));
443 return NULL;
444 } else {
445 OS_DbgPrint(OSK_MID_TRACE,("ifaddr @ %x\n", ifaddr));
446 }
447
448 addr_in = (struct sockaddr_in *)addr;
449 faddr_in = (struct sockaddr_in *)ifaddr->ifa_addr;
450
451 if( faddr_in->sin_addr.s_addr == addr_in->sin_addr.s_addr )
452 return ifaddr;
453 else
454 return NULL;
455 }
456
457 /*
458 * Locate the point to point interface with a given destination address.
459 */
460 /*ARGSUSED*/
461 struct ifaddr *
462 ifa_ifwithdstaddr(addr)
463 register struct sockaddr *addr;
464 {
465 OS_DbgPrint(OSK_MID_TRACE,("Called\n"));
466 return ifa_iffind(addr, IFF_POINTOPOINT);
467 }
468
469 /*
470 * Find an interface on a specific network. If many, choice
471 * is most specific found.
472 */
473 struct ifaddr *ifa_ifwithnet(addr)
474 struct sockaddr *addr;
475 {
476 struct sockaddr_in *sin;
477 struct ifaddr *ifaddr = ifa_iffind(addr, IFF_UNICAST);
478
479 if( ifaddr )
480 {
481 sin = (struct sockaddr *)&ifaddr->ifa_addr;
482
483 OS_DbgPrint(OSK_MID_TRACE,("ifaddr->addr = %x\n",
484 sin->sin_addr.s_addr));
485 }
486
487 return ifaddr;
488 }
489