2 #include <oskitdebug.h>
3 #include <net/raw_cb.h>
7 #include <sys/socket.h>
8 #include <sys/kernel.h>
9 #include <sys/filedesc.h>
11 #include <sys/fcntl.h>
14 #include <sys/protosw.h>
15 #include <sys/socket.h>
16 #include <sys/socketvar.h>
19 struct linker_set domain_set
;
21 OSKITTCP_EVENT_HANDLERS OtcpEvent
= { 0 };
23 //OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
24 OSK_UINT OskitDebugTraceLevel
= 0;
31 unsigned volatile ipending
;
32 struct timeval boottime
;
35 int _snprintf(char * buf
, size_t cnt
, const char *fmt
, ...);
37 void *fbsd_malloc( unsigned int bytes
, char *file
, unsigned line
, ... ) {
38 if( !OtcpEvent
.TCPMalloc
) panic("no malloc");
39 return OtcpEvent
.TCPMalloc
40 ( OtcpEvent
.ClientData
, (OSK_UINT
)bytes
, (OSK_PCHAR
)file
, line
);
43 void fbsd_free( void *data
, char *file
, unsigned line
, ... ) {
44 if( !OtcpEvent
.TCPFree
) panic("no free");
45 OtcpEvent
.TCPFree( OtcpEvent
.ClientData
, data
, (OSK_PCHAR
)file
, line
);
49 OS_DbgPrint(OSK_MID_TRACE
,("Init Called\n"));
50 KeInitializeSpinLock(&OSKLock
);
51 OS_DbgPrint(OSK_MID_TRACE
,("MB Init\n"));
53 OS_DbgPrint(OSK_MID_TRACE
,("Rawip Init\n"));
56 OS_DbgPrint(OSK_MID_TRACE
,("Route Init\n"));
58 OS_DbgPrint(OSK_MID_TRACE
,("Init clock\n"));
60 OS_DbgPrint(OSK_MID_TRACE
,("Init TCP\n"));
62 OS_DbgPrint(OSK_MID_TRACE
,("Init routing\n"));
64 OS_DbgPrint(OSK_MID_TRACE
,("Init Finished\n"));
68 void DeinitOskitTCP() {
71 void TimerOskitTCP( int FastTimer
, int SlowTimer
) {
74 /* This function is a special case in which we cannot use OSKLock/OSKUnlock
75 * because we don't enter with the connection lock held */
77 OSKLockAndRaise(&OldIrql
);
84 OSKUnlockAndLower(OldIrql
);
87 void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers
) {
88 memcpy( &OtcpEvent
, EventHandlers
, sizeof(OtcpEvent
) );
91 void OskitDumpBuffer( OSK_PCHAR Data
, OSK_UINT Len
)
95 static const char* hex
= "0123456789abcdef";
97 for ( i
= 0; i
< Len
; i
++ )
100 int align3
= (align
<<1) + align
;
101 unsigned char c
= Data
[i
];
104 if ( i
) DbgPrint( line
);
105 _snprintf ( line
, sizeof(line
)-1, "%08x: \n", &Data
[i
] );
106 line
[sizeof(line
)-1] = '\0';
109 line
[10+align3
] = hex
[(c
>>4)&0xf];
110 line
[11+align3
] = hex
[c
&0xf];
119 /* From uipc_syscalls.c */
121 int OskitTCPSocket( void *context
,
130 int error
= socreate(domain
, &so
, type
, proto
);
132 so
->so_connection
= context
;
133 so
->so_state
|= SS_NBIO
;
141 int OskitTCPRecv( void *connection
,
146 struct uio uio
= { 0 };
147 struct iovec iov
= { 0 };
151 OS_DbgPrint(OSK_MID_TRACE
,
152 ("so->so_state %x\n", ((struct socket
*)connection
)->so_state
));
154 if( Flags
& OSK_MSG_OOB
) tcp_flags
|= MSG_OOB
;
155 if( Flags
& OSK_MSG_DONTWAIT
) tcp_flags
|= MSG_DONTWAIT
;
156 if( Flags
& OSK_MSG_PEEK
) tcp_flags
|= MSG_PEEK
;
159 iov
.iov_base
= (char *)Data
;
164 uio
.uio_segflg
= UIO_SYSSPACE
;
165 uio
.uio_rw
= UIO_READ
;
166 uio
.uio_procp
= NULL
;
168 OS_DbgPrint(OSK_MID_TRACE
,("Reading %d bytes from TCP:\n", Len
));
171 error
= soreceive( connection
, NULL
, &uio
, NULL
, NULL
/* SCM_RIGHTS */,
175 *OutLen
= Len
- uio
.uio_resid
;
180 int OskitTCPBind( void *socket
,
181 void *nam
, OSK_UINT namelen
) {
183 struct socket
*so
= socket
;
185 struct sockaddr addr
;
187 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
190 return OSK_ESHUTDOWN
;
193 addr
= *((struct sockaddr
*)nam
);
195 RtlZeroMemory(&sabuf
, sizeof(sabuf
));
196 sabuf
.m_data
= (void *)&addr
;
197 sabuf
.m_len
= sizeof(addr
);
199 addr
.sa_family
= addr
.sa_len
;
200 addr
.sa_len
= sizeof(struct sockaddr
);
203 error
= sobind(so
, &sabuf
);
206 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
210 int OskitTCPConnect( void *socket
, void *nam
, OSK_UINT namelen
) {
211 struct socket
*so
= socket
;
214 struct sockaddr addr
;
216 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
219 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
224 OS_DbgPrint(OSK_MIN_TRACE
,("Nam: %x\n", nam
));
226 addr
= *((struct sockaddr
*)nam
);
228 RtlZeroMemory(&sabuf
, sizeof(sabuf
));
229 sabuf
.m_data
= (void *)&addr
;
230 sabuf
.m_len
= sizeof(addr
);
232 addr
.sa_family
= addr
.sa_len
;
233 addr
.sa_len
= sizeof(struct sockaddr
);
235 error
= soconnect(so
, &sabuf
);
237 if (error
== EINPROGRESS
)
242 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
248 so
->so_state
&= ~SS_ISCONNECTING
;
250 if (error
== ERESTART
)
255 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
259 int OskitTCPDisconnect(void *socket
)
264 return OSK_ESHUTDOWN
;
267 error
= sodisconnect(socket
);
273 int OskitTCPShutdown( void *socket
, int disconn_type
) {
277 return OSK_ESHUTDOWN
;
280 error
= soshutdown( socket
, disconn_type
);
286 int OskitTCPClose( void *socket
) {
290 return OSK_ESHUTDOWN
;
293 error
= soclose( socket
);
299 int OskitTCPSend( void *socket
, OSK_PCHAR Data
, OSK_UINT Len
,
300 OSK_UINT
*OutLen
, OSK_UINT flags
) {
306 return OSK_ESHUTDOWN
;
309 iov
.iov_base
= (char *)Data
;
314 uio
.uio_segflg
= UIO_SYSSPACE
;
315 uio
.uio_rw
= UIO_WRITE
;
316 uio
.uio_procp
= NULL
;
319 error
= sosend( socket
, NULL
, &uio
, NULL
, NULL
, 0 );
322 *OutLen
= Len
- uio
.uio_resid
;
327 int OskitTCPAccept( void *socket
,
332 OSK_UINT
*OutAddrLen
,
333 OSK_UINT FinishAccepting
) {
334 struct socket
*head
= (void *)socket
;
335 struct sockaddr
*name
= (struct sockaddr
*)AddrOut
;
336 struct socket
**newso
= (struct socket
**)new_socket
;
337 struct socket
*so
= socket
;
338 struct sockaddr_in sa
;
341 int namelen
= 0, error
= 0, s
;
344 return OSK_ESHUTDOWN
;
346 if (!new_socket
|| !AddrOut
)
349 OS_DbgPrint(OSK_MID_TRACE
,("OSKITTCP: Doing accept (Finish %d)\n",
352 *OutAddrLen
= AddrLen
;
355 /* that's a copyin actually */
356 namelen
= *OutAddrLen
;
363 if ((head
->so_options
& SO_ACCEPTCONN
) == 0) {
364 OS_DbgPrint(OSK_MID_TRACE
,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
365 head
->so_options
, SO_ACCEPTCONN
));
371 OS_DbgPrint(OSK_MID_TRACE
,("head->so_q = %x, head->so_state = %x\n",
372 head
->so_q
, head
->so_state
));
374 if ((head
->so_state
& SS_NBIO
) && head
->so_q
== NULL
) {
380 * At this point we know that there is at least one connection
381 * ready to be accepted. Remove it from the queue.
385 inp
= so
? (struct inpcb
*)so
->so_pcb
: NULL
;
387 ((struct sockaddr_in
*)AddrOut
)->sin_addr
.s_addr
=
388 inp
->inp_faddr
.s_addr
;
389 ((struct sockaddr_in
*)AddrOut
)->sin_port
= inp
->inp_fport
;
392 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
393 if( FinishAccepting
&& so
) {
394 head
->so_q
= so
->so_q
;
397 mnam
.m_data
= (char *)&sa
;
398 mnam
.m_len
= sizeof(sa
);
400 error
= soaccept(so
, &mnam
);
404 so
->so_state
|= SS_NBIO
| SS_ISCONNECTED
;
405 so
->so_q
= so
->so_q0
= NULL
;
408 so
->so_connection
= context
;
412 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
414 /* check sa_len before it is destroyed */
415 memcpy( AddrOut
, &sa
, AddrLen
< sizeof(sa
) ? AddrLen
: sizeof(sa
) );
416 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
417 *OutAddrLen
= namelen
; /* copyout actually */
419 OS_DbgPrint(OSK_MID_TRACE
,("error = %d\n", error
));
424 OS_DbgPrint(OSK_MID_TRACE
,("OSKITTCP: Returning %d\n", error
));
430 * We have a packet. While we store the fields we want in host byte order
431 * outside the original packet, the bsd stack modifies them in place.
434 void OskitTCPReceiveDatagram( OSK_PCHAR Data
, OSK_UINT Len
,
435 OSK_UINT IpHeaderLen
) {
440 /* This function is a special case in which we cannot use OSKLock/OSKUnlock
441 * because we don't enter with the connection lock held */
443 OSKLockAndRaise(&OldIrql
);
444 Ip
= m_devget( (char *)Data
, Len
, 0, NULL
, NULL
);
447 OSKUnlockAndLower(OldIrql
);
448 return; /* drop the segment */
451 //memcpy( Ip->m_data, Data, Len );
452 Ip
->m_pkthdr
.len
= IpHeaderLen
;
454 /* Do the transformations on the header that tcp_input expects */
455 iph
= mtod(Ip
, struct ip
*);
457 iph
->ip_len
-= sizeof(struct ip
);
459 OS_DbgPrint(OSK_MAX_TRACE
,
460 ("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len
,
463 tcp_input(Ip
, IpHeaderLen
);
464 OSKUnlockAndLower(OldIrql
);
466 /* The buffer Ip is freed by tcp_input */
469 int OskitTCPSetSockOpt(void *socket
,
479 return OSK_ESHUTDOWN
;
485 m
= m_get(M_WAIT
, MT_SOOPTS
);
494 memcpy(m
->m_data
, buffer
, size
);
496 /* m is freed by sosetopt */
497 error
= sosetopt(socket
, level
, optname
, m
);
503 int OskitTCPGetSockOpt(void *socket
,
509 int error
, oldsize
= *size
;
513 return OSK_ESHUTDOWN
;
516 error
= sogetopt(socket
, level
, optname
, &m
);
521 if (!buffer
|| oldsize
< m
->m_len
)
528 memcpy(buffer
, m
->m_data
, m
->m_len
);
537 int OskitTCPListen( void *socket
, int backlog
) {
541 return OSK_ESHUTDOWN
;
543 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
546 error
= solisten( socket
, backlog
);
549 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
554 int OskitTCPSetAddress( void *socket
,
555 OSK_UINT LocalAddress
,
557 OSK_UINT RemoteAddress
,
558 OSK_UI16 RemotePort
) {
559 struct socket
*so
= socket
;
563 return OSK_ESHUTDOWN
;
566 inp
= (struct inpcb
*)so
->so_pcb
;
567 inp
->inp_laddr
.s_addr
= LocalAddress
;
568 inp
->inp_lport
= LocalPort
;
569 inp
->inp_faddr
.s_addr
= RemoteAddress
;
570 inp
->inp_fport
= RemotePort
;
576 int OskitTCPGetAddress( void *socket
,
577 OSK_UINT
*LocalAddress
,
579 OSK_UINT
*RemoteAddress
,
580 OSK_UI16
*RemotePort
) {
581 struct socket
*so
= socket
;
585 return OSK_ESHUTDOWN
;
588 inp
= (struct inpcb
*)so
->so_pcb
;
589 *LocalAddress
= inp
->inp_laddr
.s_addr
;
590 *LocalPort
= inp
->inp_lport
;
591 *RemoteAddress
= inp
->inp_faddr
.s_addr
;
592 *RemotePort
= inp
->inp_fport
;
598 int OskitTCPGetSocketError(void *socket
) {
599 struct socket
*so
= socket
;
603 return OSK_ESHUTDOWN
;
606 error
= so
->so_error
;
612 struct ifaddr
*ifa_iffind(struct sockaddr
*addr
, int type
)
614 if( OtcpEvent
.FindInterface
)
615 return OtcpEvent
.FindInterface( OtcpEvent
.ClientData
,
623 void oskittcp_die( const char *file
, int line
) {
624 DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file
, line
);
628 /* Stuff supporting the BSD network-interface interface */
629 struct ifaddr
**ifnet_addrs
;
642 panic("if_attach\n");
652 * Handle interface watchdog timer routines. Called
653 * from softclock, we decrement timers (if set) and
654 * call the appropriate interface routine on expiration.
661 register struct ifnet
*ifp
;
664 for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
) {
665 if (ifp
->if_timer
== 0 || --ifp
->if_timer
)
667 if (ifp
->if_watchdog
)
668 (*ifp
->if_watchdog
)(ifp
->if_unit
);
671 timeout(if_slowtimo
, (void *)0, hz
/ IFNET_SLOWHZ
);
676 * Locate an interface based on a complete address.
680 struct ifaddr
*ifa_ifwithaddr(addr
)
681 struct sockaddr
*addr
;
683 struct ifaddr
*ifaddr
= ifa_ifwithnet( addr
);
684 struct sockaddr_in
*addr_in
;
685 struct sockaddr_in
*faddr_in
;
688 OS_DbgPrint(OSK_MID_TRACE
,("No ifaddr\n"));
691 OS_DbgPrint(OSK_MID_TRACE
,("ifaddr @ %x\n", ifaddr
));
694 addr_in
= (struct sockaddr_in
*)addr
;
695 faddr_in
= (struct sockaddr_in
*)ifaddr
->ifa_addr
;
697 if( faddr_in
->sin_addr
.s_addr
== addr_in
->sin_addr
.s_addr
)
704 * Locate the point to point interface with a given destination address.
708 ifa_ifwithdstaddr(addr
)
709 register struct sockaddr
*addr
;
711 OS_DbgPrint(OSK_MID_TRACE
,("Called\n"));
712 return ifa_iffind(addr
, IFF_POINTOPOINT
);
716 * Find an interface on a specific network. If many, choice
717 * is most specific found.
719 struct ifaddr
*ifa_ifwithnet(addr
)
720 struct sockaddr
*addr
;
722 struct sockaddr_in
*sin
;
723 struct ifaddr
*ifaddr
= ifa_iffind(addr
, IFF_UNICAST
);
727 sin
= (struct sockaddr_in
*)&ifaddr
->ifa_addr
;
729 OS_DbgPrint(OSK_MID_TRACE
,("ifaddr->addr = %x\n",
730 sin
->sin_addr
.s_addr
));