2 #include <oskitdebug.h>
5 #include <sys/socket.h>
6 #include <sys/kernel.h>
7 #include <sys/filedesc.h>
12 #include <sys/protosw.h>
13 #include <sys/socket.h>
14 #include <sys/socketvar.h>
18 #define snprintf _snprintf
21 struct linker_set domain_set
;
23 OSKITTCP_EVENT_HANDLERS OtcpEvent
= { 0 };
25 //OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
26 OSK_UINT OskitDebugTraceLevel
= 0;
31 unsigned volatile ipending
;
32 struct timeval boottime
;
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 );
40 void fbsd_free( void *data
, ... ) {
41 if( !OtcpEvent
.TCPFree
) panic("no free");
42 OtcpEvent
.TCPFree( OtcpEvent
.ClientData
, data
, "*", 0 );
46 OS_DbgPrint(OSK_MID_TRACE
,("Init Called\n"));
47 OS_DbgPrint(OSK_MID_TRACE
,("MB Init\n"));
49 OS_DbgPrint(OSK_MID_TRACE
,("Rawip Init\n"));
52 OS_DbgPrint(OSK_MID_TRACE
,("Route Init\n"));
54 OS_DbgPrint(OSK_MID_TRACE
,("Init fake freebsd scheduling\n"));
56 OS_DbgPrint(OSK_MID_TRACE
,("Init clock\n"));
58 OS_DbgPrint(OSK_MID_TRACE
,("Init TCP\n"));
60 OS_DbgPrint(OSK_MID_TRACE
,("Init routing\n"));
62 OS_DbgPrint(OSK_MID_TRACE
,("Init Finished\n"));
66 void DeinitOskitTCP() {
69 void TimerOskitTCP() {
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
));
81 void OskitDumpBuffer( OSK_PCHAR Data
, OSK_UINT Len
)
85 static const char* hex
= "0123456789abcdef";
87 for ( i
= 0; i
< Len
; i
++ )
90 int align3
= (align
<<1) + align
;
91 unsigned char c
= Data
[i
];
94 if ( i
) DbgPrint( line
);
95 snprintf ( line
, sizeof(line
)-1, "%08x: \n", &Data
[i
] );
96 line
[sizeof(line
)-1] = '\0';
99 line
[10+align3
] = hex
[(c
>>4)&0xf];
100 line
[11+align3
] = hex
[c
&0xf];
109 /* From uipc_syscalls.c */
111 int OskitTCPSocket( void *context
,
118 int error
= socreate(domain
, &so
, type
, proto
);
120 so
->so_connection
= context
;
121 so
->so_state
= SS_NBIO
;
123 so
->so_q
= so
->so_q0
= NULL
;
131 int OskitTCPRecv( void *connection
,
136 char *output_ptr
= Data
;
137 struct uio uio
= { 0 };
138 struct iovec iov
= { 0 };
145 printf("so->so_state %x\n", ((struct socket
*)connection
)->so_state
);
147 if( Flags
& OSK_MSG_OOB
) tcp_flags
|= MSG_OOB
;
148 if( Flags
& OSK_MSG_DONTWAIT
) tcp_flags
|= MSG_DONTWAIT
;
149 if( Flags
& OSK_MSG_PEEK
) tcp_flags
|= MSG_PEEK
;
153 uio
.uio_rw
= UIO_READ
;
158 OS_DbgPrint(OSK_MID_TRACE
,("Reading %d bytes from TCP:\n", Len
));
160 error
= soreceive( connection
, NULL
, &uio
, NULL
, NULL
/* SCM_RIGHTS */,
164 *OutLen
= Len
- uio
.uio_resid
;
171 getsockaddr(namp
, uaddr
, len
)
172 /* [<][>][^][v][top][bottom][index][help] */
173 struct sockaddr
**namp
;
180 if (len
> SOCK_MAXADDRLEN
)
182 MALLOC(sa
, struct sockaddr
*, len
, M_SONAME
, M_WAITOK
);
183 error
= copyin(uaddr
, sa
, len
);
192 int OskitTCPBind( void *socket
, void *connection
,
193 void *nam
, OSK_UINT namelen
) {
195 struct socket
*so
= socket
;
196 struct mbuf sabuf
= { 0 };
197 struct sockaddr addr
;
199 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
202 addr
= *((struct sockaddr
*)nam
);
204 sabuf
.m_data
= (void *)&addr
;
205 sabuf
.m_len
= sizeof(addr
);
207 addr
.sa_family
= addr
.sa_len
;
208 addr
.sa_len
= sizeof(struct sockaddr
);
210 error
= sobind(so
, &sabuf
);
212 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
216 int OskitTCPConnect( void *socket
, void *connection
,
217 void *nam
, OSK_UINT namelen
) {
218 struct socket
*so
= socket
;
219 struct connect_args _uap
= {
222 int error
= EFAULT
, s
;
223 struct mbuf sabuf
= { 0 };
224 struct sockaddr addr
;
226 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
228 so
->so_connection
= connection
;
230 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
235 OS_DbgPrint(OSK_MIN_TRACE
,("Nam: %x\n", nam
));
237 addr
= *((struct sockaddr
*)nam
);
239 sabuf
.m_data
= (void *)&addr
;
240 sabuf
.m_len
= sizeof(addr
);
242 addr
.sa_family
= addr
.sa_len
;
243 addr
.sa_len
= sizeof(struct sockaddr
);
245 error
= soconnect(so
, &sabuf
);
250 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
256 so
->so_state
&= ~SS_ISCONNECTING
;
258 if (error
== ERESTART
)
262 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
266 int OskitTCPShutdown( void *socket
, int disconn_type
) {
267 struct socket
*so
= socket
;
268 return soshutdown( socket
, disconn_type
);
271 int OskitTCPClose( void *socket
) {
272 struct socket
*so
= socket
;
273 so
->so_connection
= 0;
278 int OskitTCPSend( void *socket
, OSK_PCHAR Data
, OSK_UINT Len
,
279 OSK_UINT
*OutLen
, OSK_UINT flags
) {
280 struct mbuf
* m
= m_devget( Data
, Len
, 0, NULL
, NULL
);
284 error
= sosend( socket
, NULL
, NULL
, m
, NULL
, 0 );
289 int OskitTCPAccept( void *socket
,
293 OSK_UINT
*OutAddrLen
,
294 OSK_UINT FinishAccepting
) {
295 struct socket
*head
= (void *)socket
;
296 struct sockaddr
*name
= (struct sockaddr
*)AddrOut
;
297 struct socket
**newso
= (struct socket
**)new_socket
;
298 struct socket
*so
= socket
;
299 struct sockaddr_in sa
;
302 int namelen
= 0, error
= 0, s
;
304 OS_DbgPrint(OSK_MID_TRACE
,("OSKITTCP: Doing accept (Finish %d)\n",
307 *OutAddrLen
= AddrLen
;
310 /* that's a copyin actually */
311 namelen
= *OutAddrLen
;
316 if ((head
->so_options
& SO_ACCEPTCONN
) == 0) {
318 OS_DbgPrint(OSK_MID_TRACE
,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
319 head
->so_options
, SO_ACCEPTCONN
));
325 OS_DbgPrint(OSK_MID_TRACE
,("head->so_q = %x, head->so_state = %x\n",
326 head
->so_q
, head
->so_state
));
328 if ((head
->so_state
& SS_NBIO
) && head
->so_q
== NULL
) {
334 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
335 while (head
->so_q
== NULL
&& head
->so_error
== 0) {
336 if (head
->so_state
& SS_CANTRCVMORE
) {
337 head
->so_error
= ECONNABORTED
;
340 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
341 error
= tsleep((caddr_t
)&head
->so_timeo
, PSOCK
| PCATCH
,
347 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
349 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
352 if (head
->so_error
) {
353 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
354 error
= head
->so_error
;
359 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
363 * At this point we know that there is at least one connection
364 * ready to be accepted. Remove it from the queue.
368 inp
= so
? (struct inpcb
*)so
->so_pcb
: NULL
;
370 ((struct sockaddr_in
*)AddrOut
)->sin_addr
.s_addr
=
371 inp
->inp_faddr
.s_addr
;
372 ((struct sockaddr_in
*)AddrOut
)->sin_port
= inp
->inp_fport
;
375 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
376 if( FinishAccepting
) {
377 head
->so_q
= so
->so_q
;
382 /*so->so_state &= ~SS_COMP;*/
384 mnam
.m_data
= (char *)&sa
;
385 mnam
.m_len
= sizeof(sa
);
387 (void) soaccept(so
, &mnam
);
389 so
->so_state
= SS_NBIO
| SS_ISCONNECTED
;
390 so
->so_q
= so
->so_q0
= NULL
;
394 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
396 /* check sa_len before it is destroyed */
397 memcpy( AddrOut
, &sa
, AddrLen
< sizeof(sa
) ? AddrLen
: sizeof(sa
) );
398 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
399 *OutAddrLen
= namelen
; /* copyout actually */
401 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
405 OS_DbgPrint(OSK_MID_TRACE
,("OSKITTCP: Returning %d\n", error
));
411 * We have a packet. While we store the fields we want in host byte order
412 * outside the original packet, the bsd stack modifies them in place.
415 void OskitTCPReceiveDatagram( OSK_PCHAR Data
, OSK_UINT Len
,
416 OSK_UINT IpHeaderLen
) {
417 struct mbuf
*Ip
= m_devget( Data
, Len
, 0, NULL
, NULL
);
420 if( !Ip
) return; /* drop the segment */
422 //memcpy( Ip->m_data, Data, Len );
423 Ip
->m_pkthdr
.len
= IpHeaderLen
;
425 /* Do the transformations on the header that tcp_input expects */
426 iph
= mtod(Ip
, struct ip
*);
428 iph
->ip_len
-= sizeof(struct ip
);
430 OS_DbgPrint(OSK_MAX_TRACE
,
431 ("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len
,
434 tcp_input(Ip
, IpHeaderLen
);
436 /* The buffer Ip is freed by tcp_input */
439 int OskitTCPListen( void *socket
, int backlog
) {
442 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
443 error
= solisten( socket
, backlog
);
444 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
449 void OskitTCPSetAddress( void *socket
,
450 OSK_UINT LocalAddress
,
452 OSK_UINT RemoteAddress
,
453 OSK_UI16 RemotePort
) {
454 struct socket
*so
= socket
;
455 struct inpcb
*inp
= (struct inpcb
*)so
->so_pcb
;
456 inp
->inp_laddr
.s_addr
= LocalAddress
;
457 inp
->inp_lport
= LocalPort
;
458 inp
->inp_faddr
.s_addr
= RemoteAddress
;
459 inp
->inp_fport
= RemotePort
;
462 void OskitTCPGetAddress( void *socket
,
463 OSK_UINT
*LocalAddress
,
465 OSK_UINT
*RemoteAddress
,
466 OSK_UI16
*RemotePort
) {
467 struct socket
*so
= socket
;
468 struct inpcb
*inp
= so
? (struct inpcb
*)so
->so_pcb
: NULL
;
470 *LocalAddress
= inp
->inp_laddr
.s_addr
;
471 *LocalPort
= inp
->inp_lport
;
472 *RemoteAddress
= inp
->inp_faddr
.s_addr
;
473 *RemotePort
= inp
->inp_fport
;
477 struct ifaddr
*ifa_iffind(struct sockaddr
*addr
, int type
)
479 if( OtcpEvent
.FindInterface
)
480 return OtcpEvent
.FindInterface( OtcpEvent
.ClientData
,
488 void oskittcp_die( const char *file
, int line
) {
489 DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file
, line
);
493 /* Stuff supporting the BSD network-interface interface */
494 struct ifaddr
**ifnet_addrs
;
507 panic("if_attach\n");
517 * Handle interface watchdog timer routines. Called
518 * from softclock, we decrement timers (if set) and
519 * call the appropriate interface routine on expiration.
526 register struct ifnet
*ifp
;
529 for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
) {
530 if (ifp
->if_timer
== 0 || --ifp
->if_timer
)
532 if (ifp
->if_watchdog
)
533 (*ifp
->if_watchdog
)(ifp
->if_unit
);
536 timeout(if_slowtimo
, (void *)0, hz
/ IFNET_SLOWHZ
);
541 * Locate an interface based on a complete address.
545 struct ifaddr
*ifa_ifwithaddr(addr
)
546 struct sockaddr
*addr
;
548 struct ifaddr
*ifaddr
= ifa_ifwithnet( addr
);
549 struct sockaddr_in
*addr_in
;
550 struct sockaddr_in
*faddr_in
;
553 OS_DbgPrint(OSK_MID_TRACE
,("No ifaddr\n"));
556 OS_DbgPrint(OSK_MID_TRACE
,("ifaddr @ %x\n", ifaddr
));
559 addr_in
= (struct sockaddr_in
*)addr
;
560 faddr_in
= (struct sockaddr_in
*)ifaddr
->ifa_addr
;
562 if( faddr_in
->sin_addr
.s_addr
== addr_in
->sin_addr
.s_addr
)
569 * Locate the point to point interface with a given destination address.
573 ifa_ifwithdstaddr(addr
)
574 register struct sockaddr
*addr
;
576 OS_DbgPrint(OSK_MID_TRACE
,("Called\n"));
577 return ifa_iffind(addr
, IFF_POINTOPOINT
);
581 * Find an interface on a specific network. If many, choice
582 * is most specific found.
584 struct ifaddr
*ifa_ifwithnet(addr
)
585 struct sockaddr
*addr
;
587 struct sockaddr_in
*sin
;
588 struct ifaddr
*ifaddr
= ifa_iffind(addr
, IFF_UNICAST
);
592 sin
= (struct sockaddr_in
*)&ifaddr
->ifa_addr
;
594 OS_DbgPrint(OSK_MID_TRACE
,("ifaddr->addr = %x\n",
595 sin
->sin_addr
.s_addr
));