3 #include <oskitdebug.h>
6 #include <sys/socket.h>
7 #include <sys/kernel.h>
8 #include <sys/filedesc.h>
10 #include <sys/fcntl.h>
13 #include <sys/protosw.h>
14 #include <sys/socket.h>
15 #include <sys/socketvar.h>
19 #define snprintf _snprintf
22 struct linker_set domain_set
;
24 OSKITTCP_EVENT_HANDLERS OtcpEvent
= { 0 };
26 OSK_UINT OskitDebugTraceLevel
= OSK_DEBUG_ULTRA
;
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
;
127 int OskitTCPRecv( void *connection
,
132 char *output_ptr
= Data
;
133 struct uio uio
= { 0 };
134 struct iovec iov
= { 0 };
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
;
147 uio
.uio_rw
= UIO_READ
;
152 OS_DbgPrint(OSK_MID_TRACE
,("Reading %d bytes from TCP:\n", Len
));
154 error
= soreceive( connection
, NULL
, &uio
, NULL
, NULL
/* SCM_RIGHTS */,
158 *OutLen
= Len
- uio
.uio_resid
;
165 getsockaddr(namp
, uaddr
, len
)
166 /* [<][>][^][v][top][bottom][index][help] */
167 struct sockaddr
**namp
;
174 if (len
> SOCK_MAXADDRLEN
)
176 MALLOC(sa
, struct sockaddr
*, len
, M_SONAME
, M_WAITOK
);
177 error
= copyin(uaddr
, sa
, len
);
186 int OskitTCPBind( void *socket
, void *connection
,
187 void *nam
, OSK_UINT namelen
) {
189 struct socket
*so
= socket
;
190 struct mbuf sabuf
= { 0 };
191 struct sockaddr addr
;
193 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
196 addr
= *((struct sockaddr
*)nam
);
198 sabuf
.m_data
= (void *)&addr
;
199 sabuf
.m_len
= sizeof(addr
);
201 addr
.sa_family
= addr
.sa_len
;
202 addr
.sa_len
= sizeof(struct sockaddr
);
204 error
= sobind(so
, &sabuf
);
206 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
210 int OskitTCPConnect( void *socket
, void *connection
,
211 void *nam
, OSK_UINT namelen
) {
212 struct socket
*so
= socket
;
213 struct connect_args _uap
= {
216 int error
= EFAULT
, s
;
217 struct mbuf sabuf
= { 0 };
218 struct sockaddr addr
;
220 OS_DbgPrint(OSK_MID_TRACE
,("Called, socket = %08x\n", socket
));
222 so
->so_connection
= connection
;
224 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
229 OS_DbgPrint(OSK_MIN_TRACE
,("Nam: %x\n", nam
));
231 addr
= *((struct sockaddr
*)nam
);
233 sabuf
.m_data
= (void *)&addr
;
234 sabuf
.m_len
= sizeof(addr
);
236 addr
.sa_family
= addr
.sa_len
;
237 addr
.sa_len
= sizeof(struct sockaddr
);
239 error
= soconnect(so
, &sabuf
);
244 if ((so
->so_state
& SS_NBIO
) && (so
->so_state
& SS_ISCONNECTING
)) {
250 so
->so_state
&= ~SS_ISCONNECTING
;
252 if (error
== ERESTART
)
256 OS_DbgPrint(OSK_MID_TRACE
,("Ending: %08x\n", error
));
260 int OskitTCPClose( void *socket
) {
261 struct socket
*so
= socket
;
262 so
->so_connection
= 0;
267 int OskitTCPSend( void *socket
, OSK_PCHAR Data
, OSK_UINT Len
,
268 OSK_UINT
*OutLen
, OSK_UINT flags
) {
269 struct mbuf
* m
= m_devget( Data
, Len
, 0, NULL
, NULL
);
273 error
= sosend( socket
, NULL
, NULL
, m
, NULL
, 0 );
278 int OskitTCPAccept( void *socket
,
281 OSK_UINT
*OutAddrLen
) {
285 nam
.m_data
= AddrOut
;
288 return soaccept( socket
, &nam
);
293 * We have a packet. While we store the fields we want in host byte order
294 * outside the original packet, the bsd stack modifies them in place.
297 void OskitTCPReceiveDatagram( OSK_PCHAR Data
, OSK_UINT Len
,
298 OSK_UINT IpHeaderLen
) {
299 struct mbuf
*Ip
= m_devget( Data
, Len
, 0, NULL
, NULL
);
302 if( !Ip
) return; /* drop the segment */
304 //memcpy( Ip->m_data, Data, Len );
305 Ip
->m_pkthdr
.len
= IpHeaderLen
;
307 /* Do the transformations on the header that tcp_input expects */
308 iph
= mtod(Ip
, struct ip
*);
310 iph
->ip_len
-= sizeof(struct ip
);
312 OS_DbgPrint(OSK_MAX_TRACE
,
313 ("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len
,
316 tcp_input(Ip
, IpHeaderLen
);
318 /* The buffer Ip is freed by tcp_input */
321 int OskitTCPListen( void *socket
, int backlog
) {
322 return solisten( socket
, backlog
);
325 void OskitTCPSetAddress( void *socket
,
326 OSK_UINT LocalAddress
,
328 OSK_UINT RemoteAddress
,
329 OSK_UI16 RemotePort
) {
330 struct socket
*so
= socket
;
331 struct inpcb
*inp
= so
->so_pcb
;
332 inp
->inp_laddr
.s_addr
= LocalAddress
;
333 inp
->inp_lport
= LocalPort
;
334 inp
->inp_faddr
.s_addr
= RemoteAddress
;
335 inp
->inp_fport
= RemotePort
;
336 DbgPrint("OSKIT: SET ADDR %x:%x -> %x:%x\n",
337 LocalAddress
, LocalPort
,
338 RemoteAddress
, RemotePort
);
341 void OskitTCPGetAddress( void *socket
,
342 OSK_UINT
*LocalAddress
,
344 OSK_UINT
*RemoteAddress
,
345 OSK_UI16
*RemotePort
) {
346 struct socket
*so
= socket
;
347 struct inpcb
*inp
= so
? so
->so_pcb
: 0;
349 *LocalAddress
= inp
->inp_laddr
.s_addr
;
350 *LocalPort
= inp
->inp_lport
;
351 *RemoteAddress
= inp
->inp_faddr
.s_addr
;
352 *RemotePort
= inp
->inp_fport
;
353 DbgPrint("OSKIT: GET ADDR %x:%x -> %x:%x\n",
354 *LocalAddress
, *LocalPort
,
355 *RemoteAddress
, *RemotePort
);
359 struct ifaddr
*ifa_iffind(struct sockaddr
*addr
, int type
)
361 if( OtcpEvent
.FindInterface
)
362 return OtcpEvent
.FindInterface( OtcpEvent
.ClientData
,
370 void oskittcp_die( const char *file
, int line
) {
371 DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file
, line
);
375 /* Stuff supporting the BSD network-interface interface */
376 struct ifaddr
**ifnet_addrs
;
389 panic("if_attach\n");
399 * Handle interface watchdog timer routines. Called
400 * from softclock, we decrement timers (if set) and
401 * call the appropriate interface routine on expiration.
408 register struct ifnet
*ifp
;
411 for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
) {
412 if (ifp
->if_timer
== 0 || --ifp
->if_timer
)
414 if (ifp
->if_watchdog
)
415 (*ifp
->if_watchdog
)(ifp
->if_unit
);
418 timeout(if_slowtimo
, (void *)0, hz
/ IFNET_SLOWHZ
);
423 * Locate an interface based on a complete address.
427 struct ifaddr
*ifa_ifwithaddr(addr
)
428 struct sockaddr
*addr
;
430 struct ifaddr
*ifaddr
= ifa_ifwithnet( addr
);
431 struct sockaddr_in
*addr_in
;
432 struct sockaddr_in
*faddr_in
;
435 OS_DbgPrint(OSK_MID_TRACE
,("No ifaddr\n"));
438 OS_DbgPrint(OSK_MID_TRACE
,("ifaddr @ %x\n", ifaddr
));
441 addr_in
= (struct sockaddr_in
*)addr
;
442 faddr_in
= (struct sockaddr_in
*)ifaddr
->ifa_addr
;
444 if( faddr_in
->sin_addr
.s_addr
== addr_in
->sin_addr
.s_addr
)
451 * Locate the point to point interface with a given destination address.
455 ifa_ifwithdstaddr(addr
)
456 register struct sockaddr
*addr
;
458 OS_DbgPrint(OSK_MID_TRACE
,("Called\n"));
459 return ifa_iffind(addr
, IFF_POINTOPOINT
);
463 * Find an interface on a specific network. If many, choice
464 * is most specific found.
466 struct ifaddr
*ifa_ifwithnet(addr
)
467 struct sockaddr
*addr
;
469 struct sockaddr_in
*sin
;
470 struct ifaddr
*ifaddr
= ifa_iffind(addr
, IFF_UNICAST
);
474 sin
= (struct sockaddr
*)&ifaddr
->ifa_addr
;
476 OS_DbgPrint(OSK_MID_TRACE
,("ifaddr->addr = %x\n",
477 sin
->sin_addr
.s_addr
));