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>
17 struct linker_set domain_set
;
19 OSKITTCP_EVENT_HANDLERS OtcpEvent
= { 0 };
21 OSK_UINT OskitDebugTraceLevel
= OSK_DEBUG_ULTRA
;
26 unsigned volatile ipending
;
27 struct timeval boottime
;
29 void *fbsd_malloc( unsigned int bytes
, const char *file
, int line
, ... ) {
30 if( !OtcpEvent
.TCPMalloc
) panic("no malloc");
31 return OtcpEvent
.TCPMalloc
32 ( OtcpEvent
.ClientData
,
33 (OSK_UINT
)bytes
, (OSK_PCHAR
)file
, (OSK_UINT
)line
);
36 void fbsd_free( void *data
, const char *file
, int line
, ... ) {
37 if( !OtcpEvent
.TCPFree
) panic("no free");
38 OtcpEvent
.TCPFree( OtcpEvent
.ClientData
,
39 data
, (OSK_PCHAR
)file
, (OSK_UINT
)line
);
43 OS_DbgPrint(OSK_MID_TRACE
,("Init Called\n"));
44 OS_DbgPrint(OSK_MID_TRACE
,("MB Init\n"));
46 OS_DbgPrint(OSK_MID_TRACE
,("Rawip Init\n"));
49 OS_DbgPrint(OSK_MID_TRACE
,("Route Init\n"));
51 OS_DbgPrint(OSK_MID_TRACE
,("Init fake freebsd scheduling\n"));
53 OS_DbgPrint(OSK_MID_TRACE
,("Init clock\n"));
55 OS_DbgPrint(OSK_MID_TRACE
,("Init TCP\n"));
57 OS_DbgPrint(OSK_MID_TRACE
,("Init routing\n"));
59 memset( &OtcpEvent
, 0, sizeof( OtcpEvent
) );
60 OS_DbgPrint(OSK_MID_TRACE
,("Init Finished\n"));
64 void DeinitOskitTCP() {
67 void TimerOskitTCP() {
72 void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers
) {
73 memcpy( &OtcpEvent
, EventHandlers
, sizeof(OtcpEvent
) );
74 if( OtcpEvent
.PacketSend
)
75 OS_DbgPrint(OSK_MID_TRACE
,("SendPacket handler registered: %x\n",
76 OtcpEvent
.PacketSend
));
79 void OskitDumpBuffer( OSK_PCHAR Data
, OSK_UINT Len
) {
82 for( i
= 0; i
< Len
; i
++ ) {
83 if( i
&& !(i
& 0xf) ) DbgPrint( "\n" );
84 if( !(i
& 0xf) ) DbgPrint( "%08x: ", (OSK_UINT
)(Data
+ i
) );
85 DbgPrint( " %02x", Data
[i
] );
90 /* From uipc_syscalls.c */
92 int OskitTCPSocket( void *context
,
99 int error
= socreate(domain
, &so
, type
, proto
);
101 so
->so_connection
= context
;
102 so
->so_state
= SS_NBIO
;
108 int OskitTCPRecv( void *connection
,
113 struct mbuf
*paddr
= 0;
115 struct uio uio
= { 0 };
119 if( Flags
& OSK_MSG_OOB
) tcp_flags
|= MSG_OOB
;
120 if( Flags
& OSK_MSG_DONTWAIT
) tcp_flags
|= MSG_DONTWAIT
;
121 if( Flags
& OSK_MSG_PEEK
) tcp_flags
|= MSG_PEEK
;
127 m
.m_flags
= M_PKTHDR
| M_EOR
;
131 OS_DbgPrint(OSK_MID_TRACE
,("Reading %d bytes from TCP:\n", Len
));
133 error
= soreceive( connection
, &paddr
, &uio
, &mp
, NULL
/* SCM_RIGHTS */,
137 OS_DbgPrint(OSK_MID_TRACE
,("Successful read from TCP:\n"));
138 OskitDumpBuffer( m
.m_data
, uio
.uio_resid
);
141 *OutLen
= uio
.uio_resid
;
146 getsockaddr(namp
, uaddr
, len
)
147 /* [<][>][^][v][top][bottom][index][help] */
148 struct sockaddr
**namp
;
155 if (len
> SOCK_MAXADDRLEN
)
157 MALLOC(sa
, struct sockaddr
*, len
, M_SONAME
, M_WAITOK
);
158 error
= copyin(uaddr
, sa
, len
);
167 int OskitTCPBind( void *socket
, void *connection
,
168 void *nam
, OSK_UINT namelen
) {
170 struct socket
*so
= socket
;
171 struct mbuf sabuf
= { 0 };
172 struct sockaddr addr
;
174 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
177 addr
= *((struct sockaddr
*)nam
);
179 sabuf
.m_data
= (void *)&addr
;
180 sabuf
.m_len
= sizeof(addr
);
182 addr
.sa_family
= addr
.sa_len
;
183 addr
.sa_len
= sizeof(struct sockaddr
);
185 OskitDumpBuffer( (OSK_PCHAR
)&addr
, sizeof(addr
) );
187 error
= sobind(so
, &sabuf
);
189 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
193 int OskitTCPConnect( void *socket
, void *connection
,
194 void *nam
, OSK_UINT namelen
) {
195 struct socket
*so
= socket
;
196 struct connect_args _uap
= {
199 int error
= EFAULT
, s
;
200 struct mbuf sabuf
= { 0 };
201 struct sockaddr addr
;
203 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
205 so
->so_connection
= connection
;
207 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
212 OS_DbgPrint(OSK_MIN_TRACE
,("Nam: %x\n", nam
));
214 addr
= *((struct sockaddr
*)nam
);
216 sabuf
.m_data
= (void *)&addr
;
217 sabuf
.m_len
= sizeof(addr
);
219 addr
.sa_family
= addr
.sa_len
;
220 addr
.sa_len
= sizeof(struct sockaddr
);
222 error
= soconnect(so
, &sabuf
);
227 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
233 so
->so_state
&= ~SS_ISCONNECTING
;
235 if (error
== ERESTART
)
239 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
243 int OskitTCPClose( void *socket
) {
244 struct socket
*so
= socket
;
245 so
->so_connection
= 0;
250 int OskitTCPSend( void *socket
, OSK_PCHAR Data
, OSK_UINT Len
,
251 OSK_UINT
*OutLen
, OSK_UINT flags
) {
253 /*struct uio uio = { 0 };*/
255 OskitDumpBuffer( Data
, Len
);
256 /*uio.uio_resid = Len;*/
260 error
= sosend( socket
, NULL
, NULL
/*&uio*/, (struct mbuf
*)&mb
, NULL
, 0 );
261 /*printf("uio.uio_resid = %d\n", uio.uio_resid);*/
262 *OutLen
= Len
/*uio.uio_resid*/;
266 int OskitTCPAccept( void *socket
,
269 OSK_UINT
*OutAddrLen
) {
273 nam
.m_data
= AddrOut
;
276 return soaccept( socket
, &nam
);
281 * We have a packet. While we store the fields we want in host byte order
282 * outside the original packet, the bsd stack modifies them in place.
285 void OskitTCPReceiveDatagram( OSK_PCHAR Data
, OSK_UINT Len
,
286 OSK_UINT IpHeaderLen
) {
287 struct mbuf
*Ip
= m_devget( Data
, Len
, 0, NULL
, NULL
);
290 if( !Ip
) return; /* drop the segment */
292 memcpy( Ip
->m_data
, Data
, Len
);
293 Ip
->m_pkthdr
.len
= IpHeaderLen
;
295 /* Do the transformations on the header that tcp_input expects */
296 iph
= mtod(Ip
, struct ip
*);
298 iph
->ip_len
-= sizeof(struct ip
);
300 OS_DbgPrint(OSK_MAX_TRACE
,
301 ("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len
,
304 OskitDumpBuffer( Data
, Len
);
306 tcp_input(Ip
, IpHeaderLen
);
308 /* The buffer Ip is freed by tcp_input */
311 int OskitTCPListen( void *socket
, int backlog
) {
312 return solisten( socket
, backlog
);
315 void OskitTCPSetAddress( void *socket
,
316 OSK_UINT LocalAddress
,
318 OSK_UINT RemoteAddress
,
319 OSK_UI16 RemotePort
) {
320 struct socket
*so
= socket
;
321 struct inpcb
*inp
= so
->so_pcb
;
322 inp
->inp_laddr
.s_addr
= LocalAddress
;
323 inp
->inp_lport
= LocalPort
;
324 inp
->inp_faddr
.s_addr
= RemoteAddress
;
325 inp
->inp_fport
= RemotePort
;
326 DbgPrint("OSKIT: SET ADDR %x:%x -> %x:%x\n",
327 LocalAddress
, LocalPort
,
328 RemoteAddress
, RemotePort
);
331 void OskitTCPGetAddress( void *socket
,
332 OSK_UINT
*LocalAddress
,
334 OSK_UINT
*RemoteAddress
,
335 OSK_UI16
*RemotePort
) {
336 struct socket
*so
= socket
;
337 struct inpcb
*inp
= so
? so
->so_pcb
: 0;
339 *LocalAddress
= inp
->inp_laddr
.s_addr
;
340 *LocalPort
= inp
->inp_lport
;
341 *RemoteAddress
= inp
->inp_faddr
.s_addr
;
342 *RemotePort
= inp
->inp_fport
;
343 DbgPrint("OSKIT: GET ADDR %x:%x -> %x:%x\n",
344 *LocalAddress
, *LocalPort
,
345 *RemoteAddress
, *RemotePort
);
349 struct ifaddr
*ifa_iffind(struct sockaddr
*addr
, int type
)
351 if( OtcpEvent
.FindInterface
)
352 return OtcpEvent
.FindInterface( OtcpEvent
.ClientData
,
360 void oskittcp_die( const char *file
, int line
) {
361 DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file
, line
);
365 /* Stuff supporting the BSD network-interface interface */
366 struct ifaddr
**ifnet_addrs
;
379 panic("if_attach\n");
389 * Handle interface watchdog timer routines. Called
390 * from softclock, we decrement timers (if set) and
391 * call the appropriate interface routine on expiration.
398 register struct ifnet
*ifp
;
401 for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
) {
402 if (ifp
->if_timer
== 0 || --ifp
->if_timer
)
404 if (ifp
->if_watchdog
)
405 (*ifp
->if_watchdog
)(ifp
->if_unit
);
408 timeout(if_slowtimo
, (void *)0, hz
/ IFNET_SLOWHZ
);
413 * Locate an interface based on a complete address.
417 struct ifaddr
*ifa_ifwithaddr(addr
)
418 struct sockaddr
*addr
;
420 struct ifaddr
*ifaddr
= ifa_ifwithnet( addr
);
421 struct sockaddr_in
*addr_in
;
422 struct sockaddr_in
*faddr_in
;
425 OS_DbgPrint(OSK_MID_TRACE
,("No ifaddr\n"));
428 OS_DbgPrint(OSK_MID_TRACE
,("ifaddr @ %x\n", ifaddr
));
431 addr_in
= (struct sockaddr_in
*)addr
;
432 faddr_in
= (struct sockaddr_in
*)ifaddr
->ifa_addr
;
434 if( faddr_in
->sin_addr
.s_addr
== addr_in
->sin_addr
.s_addr
)
441 * Locate the point to point interface with a given destination address.
445 ifa_ifwithdstaddr(addr
)
446 register struct sockaddr
*addr
;
448 OS_DbgPrint(OSK_MID_TRACE
,("Called\n"));
449 return ifa_iffind(addr
, IFF_POINTOPOINT
);
453 * Find an interface on a specific network. If many, choice
454 * is most specific found.
456 struct ifaddr
*ifa_ifwithnet(addr
)
457 struct sockaddr
*addr
;
459 struct sockaddr_in
*sin
;
460 struct ifaddr
*ifaddr
= ifa_iffind(addr
, IFF_UNICAST
);
462 sin
= (struct sockaddr
*)&ifaddr
->ifa_addr
;
464 OS_DbgPrint(OSK_MID_TRACE
,("ifaddr->addr = %x\n", sin
->sin_addr
.s_addr
));