diff --git a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/if.h b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/if.h index aca7de714cb..fcf6dad121f 100644 --- a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/if.h +++ b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/if.h @@ -167,6 +167,7 @@ struct ifnet { #define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0) #define IFF_UP 0x1 /* interface is up */ +#define IFF_UNICAST 0x1 /* for our interface to reactos */ #define IFF_BROADCAST 0x2 /* broadcast address valid */ #define IFF_DEBUG 0x4 /* turn on debugging */ #define IFF_LOOPBACK 0x8 /* is a loopback net */ @@ -236,13 +237,13 @@ struct ifnet { #define IFQ_MAXLEN 50 #define IFNET_SLOWHZ 1 /* granularity is 1 second */ -#ifndef __REACTOS__ /* * The ifaddr structure contains information about one address * of an interface. They are maintained by the different address families, * are allocated and attached when an address is set, and are linked * together so all addresses for an interface can be located. */ +#ifndef __REACTOS__ struct ifaddr { struct sockaddr *ifa_addr; /* address of interface */ struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ @@ -259,8 +260,8 @@ struct ifaddr { struct rtentry *ifa_rt; /* XXXX for ROUTETOIF ????? */ #endif }; -#define IFA_ROUTE RTF_UP /* route installed */ #endif +#define IFA_ROUTE RTF_UP /* route installed */ /* * Message format for use in obtaining information about interfaces @@ -374,10 +375,10 @@ int ifioctl __P((struct socket *, int, caddr_t, struct proc *)); int ifpromisc __P((struct ifnet *, int)); struct ifnet *ifunit __P((char *)); -int ifa_ifwithaddr __P((struct sockaddr *, struct ifaddr *)); +struct ifaddr *ifa_ifwithaddr __P((struct sockaddr *)); struct ifaddr *ifa_ifwithaf __P((int)); -struct ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *, struct ifaddr *)); -int ifa_ifwithnet __P((struct sockaddr *, struct ifaddr *)); +struct ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *)); +struct ifaddr *ifa_ifwithnet __P((struct sockaddr *)); struct ifaddr *ifa_ifwithroute __P((int, struct sockaddr *, struct sockaddr *)); struct ifaddr *ifaof_ifpforaddr __P((struct sockaddr *, struct ifnet *)); diff --git a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/route.h b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/route.h index ef78cbb9392..3173211303f 100644 --- a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/route.h +++ b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/route.h @@ -36,8 +36,6 @@ #ifndef _NET_ROUTE_H_ #define _NET_ROUTE_H_ -#include - /* * Kernel resident routing tables. * @@ -51,10 +49,28 @@ * in their control blocks, e.g. inpcb. */ struct route { - struct rtentry ro_rt; + struct rtentry *ro_rt; struct sockaddr ro_dst; }; +/* + * These numbers are used by reliable protocols for determining + * retransmission behavior and are included in the routing structure. + */ +struct rt_metrics { + u_long rmx_locks; /* Kernel must leave these values alone */ + u_long rmx_mtu; /* MTU for this path */ + u_long rmx_hopcount; /* max hops expected */ + u_long rmx_expire; /* lifetime for route, e.g. redirect */ + u_long rmx_recvpipe; /* inbound delay-bandwith product */ + u_long rmx_sendpipe; /* outbound delay-bandwith product */ + u_long rmx_ssthresh; /* outbound gateway buffer limit */ + u_long rmx_rtt; /* estimated round trip time */ + u_long rmx_rttvar; /* estimated rtt variance */ + u_long rmx_pksent; /* packets sent using this route */ + u_long rmx_filler[4]; /* will be used for T/TCP later */ +}; + /* * rmx_rtt and rmx_rttvar are stored as microseconds; * RTTTOPRHZ(rtt) converts to a value suitable for use @@ -79,15 +95,32 @@ struct mbuf; #ifndef RNF_NORMAL #include #endif +struct rtentry { + struct radix_node rt_nodes[2]; /* tree glue, and other values */ +#define rt_key(r) ((struct sockaddr *)((r)->rt_nodes->rn_key)) +#define rt_mask(r) ((struct sockaddr *)((r)->rt_nodes->rn_mask)) + struct sockaddr *rt_gateway; /* value */ + short rt_filler; /* was short flags field */ + short rt_refcnt; /* # held references */ + u_long rt_flags; /* up/down?, host/net */ + struct ifnet *rt_ifp; /* the answer: interface to use */ + struct ifaddr *rt_ifa; /* the answer: interface to use */ + struct sockaddr *rt_genmask; /* for generation of cloned routes */ + caddr_t rt_llinfo; /* pointer to link level info cache */ + struct rt_metrics rt_rmx; /* metrics used by rx'ing protocols */ + struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */ + int (*rt_output) __P((struct rtentry *, struct mbuf *, + struct sockaddr *, int)); + /* output routine for this (rt,if) */ + struct rtentry *rt_parent; /* cloning parent of this route */ + void *rt_filler2; /* more filler */ +}; -#include - -#ifndef __REACTOS__ /* * Following structure necessary for 4.3 compatibility; * We should eventually move it to a compat file. */ -struct rtentry { +struct ortentry { u_long rt_hash; /* to speed lookups */ struct sockaddr rt_dst; /* key */ struct sockaddr rt_gateway; /* value */ @@ -96,7 +129,6 @@ struct rtentry { u_long rt_use; /* raw # packets forwarded */ struct ifnet *rt_ifp; /* the answer: interface to use */ }; -#endif #define rt_use rt_rmx.rmx_pksent @@ -215,15 +247,11 @@ struct route_cb { }; #ifdef KERNEL -#ifndef __REACTOS__ #define RTFREE(rt) \ if ((rt)->rt_refcnt <= 1) \ rtfree(rt); \ else \ (rt)->rt_refcnt--; -#else -#define RTFREE(rt) rtfree(rt) -#endif struct route_cb route_cb; struct rtstat rtstat; diff --git a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/in_pcb.h b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/in_pcb.h index 0a8b58d182e..2b8cba76e41 100644 --- a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/in_pcb.h +++ b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/in_pcb.h @@ -89,7 +89,7 @@ void in_pcbdetach __P((struct inpcb *)); void in_pcbdisconnect __P((struct inpcb *)); void in_pcbinshash __P((struct inpcb *)); int in_pcbladdr __P((struct inpcb *, struct mbuf *, - struct sockaddr_in *)); /* XXX Reactos * <- ** */ + struct sockaddr_in **)); struct inpcb * in_pcblookup __P((struct inpcbhead *, struct in_addr, u_int, struct in_addr, u_int, int)); @@ -97,7 +97,8 @@ struct inpcb * in_pcblookuphash __P((struct inpcbinfo *, struct in_addr, u_int, struct in_addr, u_int)); void in_pcbnotify __P((struct inpcbhead *, struct sockaddr *, - u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int)));void in_pcbrehash __P((struct inpcb *)); + u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int))); +void in_pcbrehash __P((struct inpcb *)); void in_rtchange __P((struct inpcb *, int)); void in_setpeeraddr __P((struct inpcb *, struct mbuf *)); void in_setsockaddr __P((struct inpcb *, struct mbuf *)); diff --git a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/ip_var.h b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/ip_var.h index 351ebf146e9..9aa1e4c69e8 100644 --- a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/ip_var.h +++ b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/ip_var.h @@ -176,8 +176,8 @@ extern int (*ip_mforward) __P((struct ip *, struct ifnet *, struct mbuf *, struct ip_moptions *)); int ip_next_mtu __P((int, int)); int ip_optcopy __P((struct ip *, struct ip *)); -int ip_output __P((struct socket *so, struct mbuf *, - struct mbuf *, struct route *, int, struct ip_moptions *)); +int ip_output __P((struct mbuf *, struct mbuf *, struct route *, int, + struct ip_moptions *)); int ip_pcbopts __P((struct mbuf **, struct mbuf *)); struct ip * ip_reass __P((struct ipasfrag *, struct ipq *)); diff --git a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/mbuf.h b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/mbuf.h index 50138e22dca..aa0400233f4 100644 --- a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/mbuf.h +++ b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/mbuf.h @@ -57,6 +57,13 @@ #include #endif +#ifndef OSKIT +#ifdef __REACTOS__ +/* #define OSKIT */ +#define LOCAL_OSKIT_DEFINED +#endif +#endif + /* * Mbufs are of a single size, MSIZE (machine/machparam.h), which * includes overhead. An mbuf may add a single "mbuf cluster" of size @@ -79,7 +86,11 @@ * cltom(x) - convert cluster # to ptr to beginning of cluster */ #define mtod(m,t) ((t)((m)->m_data)) +#ifndef __REACTOS__ +#define dtom(x) ((struct mbuf *)((int)(x) & ~(MSIZE-1))) +#else #define dtom(x) ((struct mbuf *)((int)(x) - sizeof(struct m_hdr))) +#endif #ifndef OSKIT #define mtocl(x) (((u_int)(x) - (u_int)mbutl) >> MCLSHIFT) #define cltom(x) ((caddr_t)((u_int)mbutl + ((u_int)(x) << MCLSHIFT))) @@ -139,7 +150,7 @@ struct mbuf { #define m_dat M_dat.M_databuf /* mbuf flags */ -#ifdef OSKIT +#if defined(OSKIT) && !defined(__REACTOS__) #include /* * A small step for mankind, but a huge leap for BSD: @@ -203,6 +214,7 @@ struct mbuf { */ #define MGET(m, how, type) { \ MALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \ + OS_DbgPrint(OSK_MID_TRACE,("(MGET) got mbuf @ %x\n", m)); \ if (m) { \ (m)->m_type = (type); \ MBUFLOCK(mbstat.m_mtypes[type]++;) \ @@ -216,6 +228,7 @@ struct mbuf { #define MGETHDR(m, how, type) { \ MALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \ + OS_DbgPrint(OSK_MID_TRACE,("(MGETHDR) got mbuf @ %x\n", m)); \ if (m) { \ (m)->m_type = (type); \ MBUFLOCK(mbstat.m_mtypes[type]++;) \ @@ -223,14 +236,14 @@ struct mbuf { (m)->m_nextpkt = (struct mbuf *)NULL; \ (m)->m_data = (m)->m_pktdat; \ (m)->m_flags = M_PKTHDR; \ - } else { \ + } else \ (m) = m_retryhdr((how), (type)); \ - } \ } -#if defined(OSKIT) || defined(__REACTOS__) +#ifdef OSKIT #define MGET_DONT_RECURSE(m, how, type) { \ MALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \ + OS_DbgPrint(OSK_MID_TRACE,("(MGET_DONT_RECURSE) got mbuf @ %x\n", m)); \ if (m) { \ (m)->m_type = (type); \ MBUFLOCK(mbstat.m_mtypes[type]++;) \ @@ -244,6 +257,7 @@ struct mbuf { #define MGETHDR_DONT_RECURSE(m, how, type) { \ MALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \ + OS_DbgPrint(OSK_MID_TRACE,("(MGETHDR_DONT_RECURSE) got mbuf @ %x\n", m)); \ if (m) { \ (m)->m_type = (type); \ MBUFLOCK(mbstat.m_mtypes[type]++;) \ @@ -276,6 +290,7 @@ union mcluster { #define MCLALLOC(p, how) \ MBUFLOCK( \ + OS_DbgPrint(OSK_MID_TRACE,("(MCLALLOC)\n")); \ if (mclfree == 0) \ (void)m_clalloc(1, (how)); \ (p) = (caddr_t)mclfree; \ @@ -288,6 +303,7 @@ union mcluster { #define MCLGET(m, how) \ { MCLALLOC((m)->m_ext.ext_buf, (how)); \ + OS_DbgPrint(OSK_MID_TRACE,("(MCLGET) m = %x\n", m)); \ if ((m)->m_ext.ext_buf != NULL) { \ (m)->m_data = (m)->m_ext.ext_buf; \ (m)->m_flags |= M_EXT; \ @@ -297,6 +313,7 @@ union mcluster { #define MCLFREE(p) \ MBUFLOCK ( \ + OS_DbgPrint(OSK_MID_TRACE,("(MCLFREE)\n")); \ if (--mclrefcnt[mtocl(p)] == 0) { \ ((union mcluster *)(p))->mcl_next = mclfree; \ mclfree = (union mcluster *)(p); \ @@ -306,6 +323,7 @@ union mcluster { #else #define MCLGET(m, how) \ { (m)->m_ext.ext_bufio = oskit_bufio_create(MCLBYTES); \ + OS_DbgPrint(OSK_MID_TRACE,("(!OSKIT MCLGET)\n")); \ oskit_bufio_map((m)->m_ext.ext_bufio, \ (void **)&((m)->m_ext.ext_buf), 0, MCLBYTES); \ if ((m)->m_ext.ext_buf != NULL) { \ @@ -339,6 +357,7 @@ union mcluster { #ifdef OSKIT #define MFREE(m, nn) \ { MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--;) \ + OS_DbgPrint(OSK_MID_TRACE,("(OSKIT MFREE) m = %x\n", m)); \ if ((m)->m_flags & M_EXT) { \ oskit_bufio_release((m)->m_ext.ext_bufio); \ } \ @@ -348,10 +367,11 @@ union mcluster { #else /* !OSKIT */ #define MFREE(m, nn) \ { MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--;) \ + OS_DbgPrint(OSK_MID_TRACE,("(!OSKIT MFREE) m = %x\n", m)); \ if ((m)->m_flags & M_EXT) { \ MCLFREE((m)->m_ext.ext_buf); \ } \ - /* (nn) = (m)->m_next; */ \ + (nn) = (m)->m_next; \ FREE((m), mbtypes[(m)->m_type]); \ } #endif /* OSKIT */ @@ -362,6 +382,7 @@ union mcluster { * from must have M_PKTHDR set, and to must be empty. */ #define M_COPY_PKTHDR(to, from) { \ + OS_DbgPrint(OSK_MID_TRACE,("(M_COPY_PKTHDR) to %x from %x\n", to, from)); \ (to)->m_pkthdr = (from)->m_pkthdr; \ (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \ (to)->m_data = (to)->m_pktdat; \ @@ -372,13 +393,19 @@ union mcluster { * an object of the specified size at the end of the mbuf, longword aligned. */ #define M_ALIGN(m, len) \ - { (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); } + { \ + OS_DbgPrint(OSK_MID_TRACE,("(M_ALIGN) %d @ %x\n", m, len)); \ + (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); \ + } /* * As above, for mbufs allocated with m_gethdr/MGETHDR * or initialized by M_COPY_PKTHDR. */ #define MH_ALIGN(m, len) \ - { (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); } + { \ + OS_DbgPrint(OSK_MID_TRACE,("(MH_ALIGN) %d @ %x\n", m, len)); \ + (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); \ + } /* * Compute the amount of space available @@ -402,6 +429,7 @@ union mcluster { * after the end of data in an mbuf. */ #define M_TRAILINGSPACE(m) \ + OS_DbgPrint(OSK_MID_TRACE,("(M_TRAILINGSPACE) %x\n", m)); \ ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \ ((m)->m_data + (m)->m_len) : \ &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len)) @@ -413,6 +441,7 @@ union mcluster { * is freed and m is set to NULL. */ #define M_PREPEND(m, plen, how) { \ + OS_DbgPrint(OSK_MID_TRACE,("(M_PREPEND) %d on %x\n", plen, m)); \ if (M_LEADINGSPACE(m) >= (plen)) { \ (m)->m_data -= (plen); \ (m)->m_len += (plen); \ @@ -424,6 +453,7 @@ union mcluster { /* change mbuf to new type */ #define MCHTYPE(m, t) { \ + OS_DbgPrint(OSK_MID_TRACE,("(MCHTYPE) %x %x\n", m, t)); \ MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;) \ (m)->m_type = t;\ } @@ -509,4 +539,9 @@ int mbtypes[] = { /* XXX */ #endif #endif +#ifdef LOCAL_OSKIT_DEFINED +#undef LOCAL_OSKIT_DEFINED +#undef OSKIT +#endif + #endif /* !_SYS_MBUF_H_ */ diff --git a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/proc.h b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/proc.h index 03b31b94012..413569a0810 100644 --- a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/proc.h +++ b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/proc.h @@ -320,7 +320,7 @@ void cpu_switch __P((struct proc *)); void sleep __P((void *chan, int pri)); int tsleep __P((void *chan, int pri, char *wmesg, int timo)); void unsleep __P((struct proc *)); -void wakeup __P((struct socket *so, struct selinfo *si, void *chan)); +void wakeup __P((struct socket *so, void *chan)); __dead void cpu_exit __P((struct proc *)) __dead2; __dead void exit1 __P((struct proc *, int)) __dead2; diff --git a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/select.h b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/select.h index bbb19ffd9a7..18d3fc6b663 100644 --- a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/select.h +++ b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/select.h @@ -57,7 +57,7 @@ struct selinfo { struct proc; void selrecord __P((struct proc *selector, struct selinfo *)); -void selwakeup __P((struct selinfo *)); +void selwakeup __P((struct socket *so, struct selinfo *)); #endif #endif /* !_SYS_SELECT_H_ */ diff --git a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/socketvar.h b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/socketvar.h index 2c90e24d085..5afe34897af 100644 --- a/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/socketvar.h +++ b/reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/socketvar.h @@ -52,6 +52,7 @@ struct socket { short so_linger; /* time to linger while closing */ short so_state; /* internal state flags SS_*, below */ caddr_t so_pcb; /* protocol control block */ + void *so_connection; /* connection (outside context) */ struct protosw *so_proto; /* protocol handle */ /* * Variables for connection queueing. @@ -100,10 +101,6 @@ struct socket { caddr_t so_tpcb; /* Wisc. protocol control block XXX */ void (*so_upcall) __P((struct socket *so, caddr_t arg, int waitf)); caddr_t so_upcallarg; /* Arg for above */ - -#ifdef __REACTOS__ - void *so_connection; /* The connection object used by our parent */ -#endif }; /* @@ -185,7 +182,7 @@ struct socket { (sb)->sb_flags &= ~SB_LOCK; \ if ((sb)->sb_flags & SB_WANT) { \ (sb)->sb_flags &= ~SB_WANT; \ - wakeup(so, &(sb)->sb_sel, (caddr_t)&(sb)->sb_flags); \ + wakeup(so, (caddr_t)&(sb)->sb_flags); \ } \ } @@ -195,7 +192,6 @@ struct socket { } #define sowwakeup(so) sowakeup((so), &(so)->so_snd) -#define socwakeup(so) sowakeup((so), &(so)->so_snd) #ifdef KERNEL extern u_long sb_max; @@ -224,7 +220,7 @@ void sowakeup __P((struct socket *, struct sockbuf *)); void socantrcvmore __P((struct socket *)); void socantsendmore __P((struct socket *)); void sbrelease __P((struct sockbuf *)); -void sbappend __P((struct socket *, struct sockbuf *, struct mbuf *)); +void sbappend __P((struct sockbuf *, struct mbuf *)); void sbappendrecord __P((struct sockbuf *, struct mbuf *)); int sbappendcontrol __P((struct sockbuf *, struct mbuf *, struct mbuf *)); int sbappendaddr __P((struct sockbuf *, struct sockaddr *, struct mbuf *, struct mbuf *)); diff --git a/reactos/drivers/lib/oskittcp/include/oskittcp.h b/reactos/drivers/lib/oskittcp/include/oskittcp.h index 3d07a09cc23..133ca4342ce 100644 --- a/reactos/drivers/lib/oskittcp/include/oskittcp.h +++ b/reactos/drivers/lib/oskittcp/include/oskittcp.h @@ -58,15 +58,20 @@ typedef int (*OSKITTCP_SOCKET_STATE) typedef int (*OSKITTCP_SEND_PACKET) ( void *ClientData, - void *WhichSocket, - void *WhichConnection, OSK_PCHAR Data, OSK_UINT Len ); +typedef struct ifaddr *(*OSKITTCP_FIND_INTERFACE) + ( void *ClientData, + OSK_UINT AddrType, + OSK_UINT FindType, + struct sockaddr *ReqAddr ); + typedef struct _OSKITTCP_EVENT_HANDLERS { void *ClientData; OSKITTCP_SOCKET_STATE SocketState; OSKITTCP_SEND_PACKET PacketSend; + OSKITTCP_FIND_INTERFACE FindInterface; } OSKITTCP_EVENT_HANDLERS, *POSKITTCP_EVENT_HANDLERS; extern OSKITTCP_EVENT_HANDLERS OtcpEvent; @@ -74,6 +79,7 @@ extern OSKITTCP_EVENT_HANDLERS OtcpEvent; extern void InitOskitTCP(); extern void DeinitOskitTCP(); extern void TimerOskitTCP(); +extern void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len ); extern int OskitTCPSocket( void *Connection, void **ConnectionContext, int Af, int Type, int Proto ); extern void RegisterOskitTCPEventHandlers @@ -91,6 +97,28 @@ extern int OskitTCPSend( void *socket, OSK_UINT Len, OSK_UINT *OutLen, OSK_UINT Flags ); + +extern int OskitTCPConnect( void *socket, void *connection, + void *nam, OSK_UINT namelen ); +extern int OskitTCPClose( void *socket ); + +extern int OskitTCPBind( void *socket, void *connection, + void *nam, OSK_UINT namelen ); + +extern int OskitTCPListen( void *socket, int backlog ); + +extern int OskitTCPRecv( void *connection, + OSK_PCHAR Data, + OSK_UINT Len, + OSK_UINT *OutLen, + OSK_UINT Flags ); + +void OskitTCPGetAddress( void *socket, + OSK_UINT *LocalAddress, + OSK_UI16 *LocalPort, + OSK_UINT *RemoteAddress, + OSK_UI16 *RemotePort ); + #undef errno #define malloc(x,...) fbsd_malloc(x,__FILE__,__LINE__) diff --git a/reactos/drivers/lib/oskittcp/include/oskittypes.h b/reactos/drivers/lib/oskittcp/include/oskittypes.h index 1040980e2db..9fad9f9c173 100644 --- a/reactos/drivers/lib/oskittcp/include/oskittypes.h +++ b/reactos/drivers/lib/oskittcp/include/oskittypes.h @@ -18,7 +18,7 @@ typedef char * osk_caddr_t; * are allocated and attached when an address is set, and are linked * together so all addresses for an interface can be located. */ -struct ifaddr { +typedef struct ifaddr { struct sockaddr *ifa_addr; /* address of interface */ struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ @@ -27,34 +27,9 @@ struct ifaddr { short ifa_refcnt; /* extra to malloc for link info */ int ifa_metric; /* cost of going out this interface */ u_short ifa_mtu; /* MTU */ -}; +} OSK_IFADDR, *POSK_IFADDR; + #define IFA_ROUTE RTF_UP /* route installed */ #define OSK_IFQ_MAXLEN 50 -/* - * These numbers are used by reliable protocols for determining - * retransmission behavior and are included in the routing structure. - */ -struct rt_metrics { - u_long rmx_locks; /* Kernel must leave these values alone */ - u_long rmx_mtu; /* MTU for this path */ - u_long rmx_hopcount; /* max hops expected */ - u_long rmx_expire; /* lifetime for route, e.g. redirect */ - u_long rmx_recvpipe; /* inbound delay-bandwith product */ - u_long rmx_sendpipe; /* outbound delay-bandwith product */ - u_long rmx_ssthresh; /* outbound gateway buffer limit */ - u_long rmx_rtt; /* estimated round trip time */ - u_long rmx_rttvar; /* estimated rtt variance */ - u_long rmx_pksent; /* packets sent using this route */ - u_long rmx_filler[4]; /* will be used for T/TCP later */ -}; - -struct rtentry { - struct sockaddr *rt_gateway; /* value */ - u_long rt_flags; /* up/down?, host/net */ - struct ifaddr rt_ifa; /* the answer: interface to use */ - struct rt_metrics rt_rmx; /* metrics used by rx'ing protocols */ - u_long rt_mtu; /* Path MTU */ -}; - #endif/*OSKITTYPES_H*/ diff --git a/reactos/drivers/lib/oskittcp/makefile b/reactos/drivers/lib/oskittcp/makefile index 3178bbff539..4c3fca71499 100644 --- a/reactos/drivers/lib/oskittcp/makefile +++ b/reactos/drivers/lib/oskittcp/makefile @@ -1,6 +1,6 @@ -# $Id: makefile,v 1.2 2004/07/18 22:03:48 arty Exp $ +# $Id: makefile,v 1.3 2004/08/19 21:38:53 arty Exp $ PATH_TO_TOP = ../../.. @@ -45,6 +45,10 @@ REACTOS_OBJECTS = \ oskittcp/param.o \ oskittcp/radix.o \ oskittcp/random.o \ + oskittcp/raw_cb.o \ + oskittcp/raw_ip.o \ + oskittcp/raw_usrreq.o \ + oskittcp/route.o \ oskittcp/rtsock.o \ oskittcp/scanc.o \ oskittcp/sleep.o \ diff --git a/reactos/drivers/lib/oskittcp/notes.txt b/reactos/drivers/lib/oskittcp/notes.txt new file mode 100644 index 00000000000..d5f2921e933 --- /dev/null +++ b/reactos/drivers/lib/oskittcp/notes.txt @@ -0,0 +1,6 @@ +The story so far: + +tcp_input is called from OskitTCPReceiveDatagram ... I'm not so sure that +this part is correct. I believe that at least the ACK number calculation +is correct as is. + diff --git a/reactos/drivers/lib/oskittcp/oskittcp/in_cksum.c b/reactos/drivers/lib/oskittcp/oskittcp/in_cksum.c index 4175f8cb087..de93c1e5ef5 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/in_cksum.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/in_cksum.c @@ -67,6 +67,9 @@ in_cksum(m, len) } l_util; for (;m && len; m = m->m_next) { + OS_DbgPrint(OSK_MID_TRACE,("Processing m %x (%d)\n", m, len)); + OskitDumpBuffer( m->m_data, m->m_len ); + if (m->m_len == 0) continue; w = mtod(m, u_short *); @@ -136,8 +139,9 @@ in_cksum(m, len) } else if (mlen == -1) s_util.c[0] = *(char *)w; } - if (len) - printf("cksum: out of data\n"); + if (len) { + panic("cksum: out of data: need %d bytes\n", len); + } if (mlen == -1) { /* The last mbuf has odd # of bytes. Follow the standard (the odd byte may be shifted left by 8 bits diff --git a/reactos/drivers/lib/oskittcp/oskittcp/in_pcb.c b/reactos/drivers/lib/oskittcp/oskittcp/in_pcb.c index f050eb655d4..4307890be8e 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/in_pcb.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/in_pcb.c @@ -90,12 +90,21 @@ in_pcbbind(inp, nam) unsigned short *lastport = &inp->inp_pcbinfo->lastport; struct sockaddr_in *sin; struct proc *p = curproc; /* XXX */ - struct ifaddr ifa; u_short lport = 0; int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); int error; - if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) + OS_DbgPrint(OSK_MID_TRACE,("Called\n")); + + OskitDumpBuffer( nam->m_data, nam->m_len ); + +#ifndef __REACTOS__ + if (in_ifaddr == 0) { + OS_DbgPrint(OSK_MID_TRACE,("Leaving EADDRNOTAVAIL\n")); + return (EADDRNOTAVAIL); + } +#endif + if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) return (EINVAL); if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 && ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 || @@ -103,15 +112,19 @@ in_pcbbind(inp, nam) wild = INPLOOKUP_WILDCARD; if (nam) { sin = mtod(nam, struct sockaddr_in *); - if (nam->m_len != sizeof (*sin)) - return (EINVAL); + if (nam->m_len != sizeof (*sin)) { + OS_DbgPrint(OSK_MID_TRACE,("Leaving EINVAL\n")); + return (EINVAL); + } #ifdef notdef /* * We should check the family, but old programs * incorrectly fail to initialize it. */ - if (sin->sin_family != AF_INET) - return (EAFNOSUPPORT); + if (sin->sin_family != AF_INET) { + OS_DbgPrint(OSK_MID_TRACE,("Leaving EAFNOSUPPORT\n")); + return (EAFNOSUPPORT); + } #endif lport = sin->sin_port; if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { @@ -126,34 +139,51 @@ in_pcbbind(inp, nam) reuseport = SO_REUSEADDR|SO_REUSEPORT; } else if (sin->sin_addr.s_addr != INADDR_ANY) { sin->sin_port = 0; /* yech... */ - if (ifa_ifwithaddr((struct sockaddr *)sin, &ifa) != 0) - return (EADDRNOTAVAIL); + OS_DbgPrint(OSK_MID_TRACE,("Calling ifwithaddr\n")); + if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) { + OS_DbgPrint(OSK_MID_TRACE, + ("Leaving EADDRNOTAVAIL\n")); + return (EADDRNOTAVAIL); + } + OS_DbgPrint(OSK_MID_TRACE,("Yep, we have that addr\n")); } if (lport) { struct inpcb *t; /* GROSS */ if (ntohs(lport) < IPPORT_RESERVED && - (error = suser(p->p_ucred, &p->p_acflag))) - return (EACCES); + (error = suser(p->p_ucred, &p->p_acflag))) { + OS_DbgPrint(OSK_MID_TRACE, + ("Leaving EACCESS\n")); + return (EACCES); + } t = in_pcblookup(head, zeroin_addr, 0, sin->sin_addr, lport, wild); if (t && (reuseport & t->inp_socket->so_options) == 0) - return (EADDRINUSE); + { + OS_DbgPrint(OSK_MID_TRACE, + ("Leaving EADDRINUSE\n")); + return (EADDRINUSE); + } } inp->inp_laddr = sin->sin_addr; } if (lport == 0) do { - ++*lastport; - if (*lastport < IPPORT_RESERVED || - *lastport > IPPORT_USERRESERVED) - *lastport = IPPORT_RESERVED; - lport = htons(*lastport); + ++*lastport; + OS_DbgPrint(OSK_MID_TRACE,("Finding port %d\n", + *lastport)); + if (*lastport < IPPORT_RESERVED || + *lastport > IPPORT_USERRESERVED) + *lastport = IPPORT_RESERVED; + lport = htons(*lastport); } while (in_pcblookup(head, - zeroin_addr, 0, inp->inp_laddr, lport, wild)); + zeroin_addr, 0, inp->inp_laddr, + lport, wild)); inp->inp_lport = lport; in_pcbrehash(inp); + + OS_DbgPrint(OSK_MID_TRACE,("Returning success\n")); return (0); } @@ -173,49 +203,118 @@ int in_pcbladdr(inp, nam, plocal_sin) register struct inpcb *inp; struct mbuf *nam; - struct sockaddr_in *plocal_sin; + struct sockaddr_in **plocal_sin; { - struct ifaddr ifa; + struct in_ifaddr *ia; struct sockaddr_in *ifaddr = 0; register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); + OS_DbgPrint(OSK_MID_TRACE,("Called\n")); + if (nam->m_len != sizeof (*sin)) return (EINVAL); - if (sin->sin_family != AF_INET) { - OS_DbgPrint(OSK_MID_TRACE,("EAFNOSUPPORT: %d\n", sin->sin_family)); + if (sin->sin_family != AF_INET) return (EAFNOSUPPORT); - } if (sin->sin_port == 0) return (EADDRNOTAVAIL); - if (inp->inp_laddr.s_addr == INADDR_ANY) { - register struct route *ro; - /* - * If route is known or can be allocated now, - * our src addr is taken from the i/f, else punt. - */ - ro = &inp->inp_route; - if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0) { - /* No route yet, so try to acquire one */ - ro->ro_dst.sa_family = AF_INET; - /* ro->ro_dst.sa_len = sizeof(struct sockaddr_in); */ - ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = - sin->sin_addr; - if( ifa_ifwithnet( sin, &ifa ) == 0 ) { - inp->inp_laddr = - ((struct sockaddr_in *)&ifa.ifa_addr)->sin_addr; - OS_DbgPrint(OSK_MID_TRACE, - ("Assigning local address: %x\n", - inp->inp_laddr.s_addr)); - } - } + if (in_ifaddr) { + /* + * If the destination address is INADDR_ANY, + * use the primary local address. + * If the supplied address is INADDR_BROADCAST, + * and the primary interface supports broadcast, + * choose the broadcast address for that interface. + */ +#define satosin(sa) ((struct sockaddr_in *)(sa)) +#define sintosa(sin) ((struct sockaddr *)(sin)) +#define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) + if (sin->sin_addr.s_addr == INADDR_ANY) + sin->sin_addr = IA_SIN(in_ifaddr)->sin_addr; +#ifndef __REACTOS__ + else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST && + (in_ifaddr->ia_ifp->if_flags & IFF_BROADCAST)) + sin->sin_addr = satosin(&in_ifaddr->ia_broadaddr)->sin_addr; +#endif } - /* + if (inp->inp_laddr.s_addr == INADDR_ANY) { + register struct route *ro; + + ia = (struct in_ifaddr *)0; + /* + * If route is known or can be allocated now, + * our src addr is taken from the i/f, else punt. + */ + ro = &inp->inp_route; + if (ro->ro_rt && + (satosin(&ro->ro_dst)->sin_addr.s_addr != + sin->sin_addr.s_addr || + inp->inp_socket->so_options & SO_DONTROUTE)) { + RTFREE(ro->ro_rt); + ro->ro_rt = (struct rtentry *)0; + } + if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ + (ro->ro_rt == (struct rtentry *)0 || + ro->ro_rt->rt_ifp == (struct ifnet *)0)) { + /* No route yet, so try to acquire one */ + ro->ro_dst.sa_family = AF_INET; + ro->ro_dst.sa_len = sizeof(struct sockaddr_in); + ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = + sin->sin_addr; + rtalloc(ro); + } + /* + * If we found a route, use the address + * corresponding to the outgoing interface + * unless it is the loopback (in case a route + * to our address on another net goes to loopback). + */ + if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) + ia = ifatoia(ro->ro_rt->rt_ifa); + if (ia == 0) { + u_short fport = sin->sin_port; + + sin->sin_port = 0; + ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); + + if (ia == 0) + ia = ifatoia(ifa_ifwithnet(sintosa(sin))); + sin->sin_port = fport; + if (ia == 0) + ia = in_ifaddr; + if (ia == 0) + return (EADDRNOTAVAIL); + } + /* + * If the destination address is multicast and an outgoing + * interface has been set as a multicast option, use the + * address of that interface as our source address. + */ +#ifndef __REACTOS__ + if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && + inp->inp_moptions != NULL) { + struct ip_moptions *imo; + struct ifnet *ifp; + + imo = inp->inp_moptions; + if (imo->imo_multicast_ifp != NULL) { + ifp = imo->imo_multicast_ifp; + for (ia = in_ifaddr; ia; ia = ia->ia_next) + if (ia->ia_ifp == ifp) + break; + if (ia == 0) + return (EADDRNOTAVAIL); + } + } +#endif + /* * Don't do pcblookup call here; return interface in plocal_sin * and exit to caller, that will do the lookup. */ - plocal_sin->sin_family = AF_INET; - plocal_sin->sin_addr = ((struct sockaddr_in *)&ifa.ifa_addr)->sin_addr; - plocal_sin->sin_port = sin->sin_port; + *plocal_sin = ia->ia_ifa.ifa_addr; + OS_DbgPrint(OSK_MID_TRACE,("plocal sin %x\n", + (*plocal_sin)->sin_addr.s_addr)); + + } return(0); } @@ -231,7 +330,7 @@ in_pcbconnect(inp, nam) register struct inpcb *inp; struct mbuf *nam; { - struct sockaddr_in ifaddr; + struct sockaddr_in *ifaddr; register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); int error; @@ -242,14 +341,13 @@ in_pcbconnect(inp, nam) return(error); if (in_pcblookuphash(inp->inp_pcbinfo, sin->sin_addr, sin->sin_port, - inp->inp_laddr.s_addr ? inp->inp_laddr : - ifaddr.sin_addr, + inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, inp->inp_lport) != NULL) return (EADDRINUSE); if (inp->inp_laddr.s_addr == INADDR_ANY) { if (inp->inp_lport == 0) (void)in_pcbbind(inp, (struct mbuf *)0); - inp->inp_laddr = ifaddr.sin_addr; + inp->inp_laddr = ifaddr->sin_addr; } inp->inp_faddr = sin->sin_addr; inp->inp_fport = sin->sin_port; @@ -280,6 +378,8 @@ in_pcbdetach(inp) sofree(so); if (inp->inp_options) (void)m_free(inp->inp_options); + if (inp->inp_route.ro_rt) + rtfree(inp->inp_route.ro_rt); ip_freemoptions(inp->inp_moptions); s = splnet(); LIST_REMOVE(inp, inp_hash); @@ -299,7 +399,7 @@ in_setsockaddr(inp, nam) sin = mtod(nam, struct sockaddr_in *); bzero((caddr_t)sin, sizeof (*sin)); sin->sin_family = AF_INET; - /* sin->sin_len = sizeof(*sin); */ + sin->sin_len = sizeof(*sin); sin->sin_port = inp->inp_lport; sin->sin_addr = inp->inp_laddr; } @@ -315,7 +415,7 @@ in_setpeeraddr(inp, nam) sin = mtod(nam, struct sockaddr_in *); bzero((caddr_t)sin, sizeof (*sin)); sin->sin_family = AF_INET; - /* sin->sin_len = sizeof(*sin); */ + sin->sin_len = sizeof(*sin); sin->sin_port = inp->inp_fport; sin->sin_addr = inp->inp_faddr; } @@ -384,6 +484,40 @@ in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify) splx(s); } +/* + * Check for alternatives when higher level complains + * about service problems. For now, invalidate cached + * routing information. If the route was created dynamically + * (by a redirect), time to try a default gateway again. + */ +void +in_losing(inp) + struct inpcb *inp; +{ + register struct rtentry *rt; + struct rt_addrinfo info; + + if ((rt = inp->inp_route.ro_rt)) { + inp->inp_route.ro_rt = 0; + bzero((caddr_t)&info, sizeof(info)); + info.rti_info[RTAX_DST] = + (struct sockaddr *)&inp->inp_route.ro_dst; + info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; + info.rti_info[RTAX_NETMASK] = rt_mask(rt); + rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); + if (rt->rt_flags & RTF_DYNAMIC) + (void) rtrequest(RTM_DELETE, rt_key(rt), + rt->rt_gateway, rt_mask(rt), rt->rt_flags, + (struct rtentry **)0); + else + /* + * A new route can be allocated + * the next time output is attempted. + */ + rtfree(rt); + } +} + /* * After a routing change, flush old routing * and allocate a (hopefully) better one. @@ -393,6 +527,14 @@ in_rtchange(inp, errno) register struct inpcb *inp; int errno; { + if (inp->inp_route.ro_rt) { + rtfree(inp->inp_route.ro_rt); + inp->inp_route.ro_rt = 0; + /* + * A new route can be allocated the next time + * output is attempted. + */ + } } struct inpcb * @@ -517,5 +659,3 @@ in_pcbrehash(inp) LIST_INSERT_HEAD(head, inp, inp_hash); splx(s); } - -void in_losing(struct inpcb *inp) { } diff --git a/reactos/drivers/lib/oskittcp/oskittcp/interface.c b/reactos/drivers/lib/oskittcp/oskittcp/interface.c index f37494d9faf..a6f51c9e2a7 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/interface.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/interface.c @@ -1,4 +1,3 @@ - #include #include #include @@ -28,8 +27,26 @@ unsigned net_imask; unsigned volatile ipending; struct timeval boottime; +void *fbsd_malloc( unsigned int bytes, const char *file, int line, ... ) { + void *v = ExAllocatePool( NonPagedPool, bytes ); + if( v ) TrackWithTag( 'fbsd', v, file, line ); + return v; +} + +void fbsd_free( void *data, const char *file, int line, ... ) { + UntrackFL( file, line, data ); + ExFreePool( data ); +} + void InitOskitTCP() { OS_DbgPrint(OSK_MID_TRACE,("Init Called\n")); + OS_DbgPrint(OSK_MID_TRACE,("MB Init\n")); + mbinit(); + OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n")); + rip_init(); + raw_init(); + OS_DbgPrint(OSK_MID_TRACE,("Route Init\n")); + route_init(); OS_DbgPrint(OSK_MID_TRACE,("Init fake freebsd scheduling\n")); init_freebsd_sched(); OS_DbgPrint(OSK_MID_TRACE,("Init clock\n")); @@ -48,6 +65,7 @@ void DeinitOskitTCP() { void TimerOskitTCP() { tcp_slowtimo(); + tcp_fasttimo(); } void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) { @@ -145,8 +163,34 @@ size_t len; return error; } -NTSTATUS OskitTCPConnect( PVOID socket, PVOID connection, - PVOID nam, OSK_UINT namelen ) { +int OskitTCPBind( PVOID socket, PVOID connection, + PVOID nam, OSK_UINT namelen ) { + int error = EFAULT; + struct socket *so = socket; + struct mbuf sabuf = { 0 }; + struct sockaddr addr; + + OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket)); + + if( nam ) + addr = *((struct sockaddr *)nam); + + sabuf.m_data = (void *)&addr; + sabuf.m_len = sizeof(addr); + + addr.sa_family = addr.sa_len; + addr.sa_len = sizeof(struct sockaddr); + + OskitDumpBuffer( (PCHAR)&addr, sizeof(addr) ); + + error = sobind(so, &sabuf); + + OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); + return (error); +} + +int OskitTCPConnect( PVOID socket, PVOID connection, + PVOID nam, OSK_UINT namelen ) { struct socket *so = socket; struct connect_args _uap = { 0, nam, namelen @@ -195,10 +239,11 @@ done: return (error); } -DWORD OskitTCPClose( void *socket ) { +int OskitTCPClose( void *socket ) { struct socket *so = socket; so->so_connection = 0; soclose( so ); + return 0; } int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, @@ -216,10 +261,10 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, return error; } -void *OskitTCPAccept( void *socket, - void *AddrOut, - OSK_UINT AddrLen, - OSK_UINT *OutAddrLen ) { +int OskitTCPAccept( void *socket, + void *AddrOut, + OSK_UINT AddrLen, + OSK_UINT *OutAddrLen ) { struct mbuf nam; int error; @@ -229,26 +274,39 @@ void *OskitTCPAccept( void *socket, return soaccept( socket, &nam ); } +/* The story so far + * + * We have a packet. While we store the fields we want in host byte order + * outside the original packet, the bsd stack modifies them in place. + */ + void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, OSK_UINT IpHeaderLen ) { - struct mbuf *Ip = m_get(M_DONTWAIT, MT_DATA); - char *NewData = malloc( Len ); + struct mbuf *Ip = m_devget( Data, Len, 0, NULL, NULL ); + struct ip *iph; + + if( !Ip ) return; /* drop the segment */ - OS_DbgPrint(OSK_MAX_TRACE, ("OskitTCPReceiveDatagram: %d Bytes\n", Len)); + memcpy( Ip->m_data, Data, Len ); + Ip->m_pkthdr.len = IpHeaderLen; + + /* Do the transformations on the header that tcp_input expects */ + iph = mtod(Ip, struct ip *); + NTOHS(iph->ip_len); + iph->ip_len -= sizeof(struct ip); + + OS_DbgPrint(OSK_MAX_TRACE, + ("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len, + IpHeaderLen)); OskitDumpBuffer( Data, Len ); - memset( Ip, 0, sizeof( *Ip ) ); - Ip->m_len = Len; - Ip->m_data = NewData; - memcpy( Ip->m_data, Data, Len ); - tcp_input(Ip, IpHeaderLen); /* The buffer Ip is freed by tcp_input */ } -void OskitTCPListen( void *socket, int backlog ) { +int OskitTCPListen( void *socket, int backlog ) { return solisten( socket, backlog ); } @@ -269,10 +327,10 @@ void OskitTCPSetAddress( void *socket, } void OskitTCPGetAddress( void *socket, - PULONG LocalAddress, - PUSHORT LocalPort, - PULONG RemoteAddress, - PUSHORT RemotePort ) { + OSK_UINT *LocalAddress, + OSK_UI16 *LocalPort, + OSK_UINT *RemoteAddress, + OSK_UI16 *RemotePort ) { struct socket *so = socket; struct inpcb *inp = so ? so->so_pcb : 0; if( inp ) { @@ -286,8 +344,123 @@ void OskitTCPGetAddress( void *socket, } } +struct ifaddr *ifa_iffind(struct sockaddr *addr, int type) +{ + if( OtcpEvent.FindInterface ) + return OtcpEvent.FindInterface( OtcpEvent.ClientData, + PF_INET, + type, + addr ); + else + return NULL; +} + void oskittcp_die( const char *file, int line ) { DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file, line); KeBugCheck(0); } +/* Stuff supporting the BSD network-interface interface */ +struct ifaddr **ifnet_addrs; +struct ifnet *ifnet; + +void +ifinit() +{ +} + + +void +if_attach(ifp) + struct ifnet *ifp; +{ + panic("if_attach\n"); +} + +struct ifnet * +ifunit(char *name) +{ + return 0; +} + +/* + * Handle interface watchdog timer routines. Called + * from softclock, we decrement timers (if set) and + * call the appropriate interface routine on expiration. + */ +void +if_slowtimo(arg) + void *arg; +{ +#if 0 + register struct ifnet *ifp; + int s = splimp(); + + for (ifp = ifnet; ifp; ifp = ifp->if_next) { + if (ifp->if_timer == 0 || --ifp->if_timer) + continue; + if (ifp->if_watchdog) + (*ifp->if_watchdog)(ifp->if_unit); + } + splx(s); + timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); +#endif +} + +/* + * Locate an interface based on a complete address. + */ + +/*ARGSUSED*/ +struct ifaddr *ifa_ifwithaddr(addr) + struct sockaddr *addr; +{ + struct ifaddr *ifaddr = ifa_ifwithnet( addr ); + struct sockaddr_in *addr_in; + struct sockaddr_in *faddr_in; + + if( !ifaddr ) { + OS_DbgPrint(OSK_MID_TRACE,("No ifaddr\n")); + return NULL; + } else { + OS_DbgPrint(OSK_MID_TRACE,("ifaddr @ %x\n", ifaddr)); + } + + addr_in = (struct sockaddr_in *)addr; + faddr_in = (struct sockaddr_in *)ifaddr->ifa_addr; + + if( faddr_in->sin_addr.s_addr == addr_in->sin_addr.s_addr ) + return ifaddr; + else + return NULL; +} + +/* + * Locate the point to point interface with a given destination address. + */ +/*ARGSUSED*/ +struct ifaddr * +ifa_ifwithdstaddr(addr) + register struct sockaddr *addr; +{ + OS_DbgPrint(OSK_MID_TRACE,("Called\n")); + return ifa_iffind(addr, IFF_POINTOPOINT); +} + +/* + * Find an interface on a specific network. If many, choice + * is most specific found. + */ +struct ifaddr *ifa_ifwithnet(addr) + struct sockaddr *addr; +{ + struct sockaddr_in *sin; + struct ifaddr *ifaddr = ifa_iffind(addr, IFF_UNICAST); + + sin = (struct sockaddr *)&ifaddr->ifa_addr; + + OS_DbgPrint(OSK_MID_TRACE,("ifaddr->addr = %x\n", sin->sin_addr.s_addr)); + + return ifaddr; +} + diff --git a/reactos/drivers/lib/oskittcp/oskittcp/ip_output.c b/reactos/drivers/lib/oskittcp/oskittcp/ip_output.c index 7e53ee3b594..587d305ba47 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/ip_output.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/ip_output.c @@ -62,21 +62,9 @@ u_short ip_id; -/* - * Discard the IP multicast options. - */ -void -ip_freemoptions(imo) - register struct ip_moptions *imo; -{ - register int i; - - if (imo != NULL) { - for (i = 0; i < imo->imo_num_memberships; ++i) - in_delmulti(imo->imo_membership[i]); - free(imo, M_IPMOPTS); - } -} +static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *)); +static void ip_mloopback + __P((struct ifnet *, struct mbuf *, struct sockaddr_in *)); /* * IP output. The packet in mbuf chain m contains a skeletal IP @@ -85,56 +73,525 @@ ip_freemoptions(imo) * The mbuf opt, if present, will not be freed. */ int -ip_output(so, m0, opt, ro, flags, imo) - struct socket *so; - struct mbuf *m0; - struct mbuf *opt; - struct route *ro; - int flags; - struct ip_moptions *imo; +ip_output(m0, opt, ro, flags, imo) + struct mbuf *m0; + struct mbuf *opt; + struct route *ro; + int flags; + struct ip_moptions *imo; { - register struct mbuf *m = m0; - int error = ENETDOWN; - /* - * It might seem obvious at first glance that one could easily - * make a one-behind cache out of this by simply making `iproute' - * static and eliminating the bzero() below. However, this turns - * out not to work, for two reasons: - * - * 1) This routine needs to be reentrant. It can be called - * recursively from encapsulating network interfaces, and it - * is always called recursively from ip_mforward(). - * - * 2) You turn out not to gain much. There is already a one- - * behind cache implemented for the specific case of forwarding, - * and sends on a connected socket will use a route associated - * with the PCB. The only cases left are sends on unconnected - * and raw sockets, and if these cases are really significant, - * something is seriously wrong. - */ - ipstat.ips_localout++; + register struct ip *ip, *mhip; + register struct ifnet *ifp; + register struct mbuf *m = m0; + register int hlen = sizeof (struct ip); + int len, off, error = 0; + /* + * It might seem obvious at first glance that one could easily + * make a one-behind cache out of this by simply making `iproute' + * static and eliminating the bzero() below. However, this turns + * out not to work, for two reasons: + * + * 1) This routine needs to be reentrant. It can be called + * recursively from encapsulating network interfaces, and it + * is always called recursively from ip_mforward(). + * + * 2) You turn out not to gain much. There is already a one- + * behind cache implemented for the specific case of forwarding, + * and sends on a connected socket will use a route associated + * with the PCB. The only cases left are sends on unconnected + * and raw sockets, and if these cases are really significant, + * something is seriously wrong. + */ + struct route iproute; + struct sockaddr_in *dst; + struct in_ifaddr *ia; - /* - * If this is the case, we probably don't want to allocate - * a protocol-cloned route since we didn't get one from the - * ULP. This lets TCP do its thing, while not burdening - * forwarding or ICMP with the overhead of cloning a route. - * Of course, we still want to do any cloning requested by - * the link layer, as this is probably required in all cases - * for correct operation (as it is for ARP). - */ - - if( OtcpEvent.PacketSend ) { - error = OtcpEvent.PacketSend - ( OtcpEvent.ClientData, - so, - so ? so->so_connection : 0, - m->m_data + IPHDR_SIZE, m->m_len - IPHDR_SIZE ); +#ifdef DIAGNOSTIC + if ((m->m_flags & M_PKTHDR) == 0) + panic("ip_output no HDR"); +#endif + if (opt) { + m = ip_insertoptions(m, opt, &len); + hlen = len; + } + ip = mtod(m, struct ip *); + /* + * Fill in IP header. + */ + if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) { + ip->ip_v = IPVERSION; + ip->ip_off &= IP_DF; + ip->ip_id = htons(ip_id++); + ip->ip_hl = hlen >> 2; + ipstat.ips_localout++; + } else { + hlen = ip->ip_hl << 2; + } + /* + * Route packet. + */ + if (ro == 0) { + ro = &iproute; + bzero((caddr_t)ro, sizeof (*ro)); + } + dst = (struct sockaddr_in *)&ro->ro_dst; + /* + * If there is a cached route, + * check that it is to the same destination + * and is still up. If not, free it and try again. + */ + if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || + dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { + RTFREE(ro->ro_rt); + ro->ro_rt = (struct rtentry *)0; + } + if (ro->ro_rt == 0) { + dst->sin_family = AF_INET; + dst->sin_len = sizeof(*dst); + dst->sin_addr = ip->ip_dst; + } + /* + * If routing to interface only, + * short circuit routing lookup. + */ +#define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) +#define sintosa(sin) ((struct sockaddr *)(sin)) + if (flags & IP_ROUTETOIF) { + if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 && + (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) { + ipstat.ips_noroute++; + error = ENETUNREACH; + goto bad; + } +#ifndef __REACTOS__ + ifp = ia->ia_ifp; +#endif + ip->ip_ttl = 1; + } else { + /* + * If this is the case, we probably don't want to allocate + * a protocol-cloned route since we didn't get one from the + * ULP. This lets TCP do its thing, while not burdening + * forwarding or ICMP with the overhead of cloning a route. + * Of course, we still want to do any cloning requested by + * the link layer, as this is probably required in all cases + * for correct operation (as it is for ARP). + */ +#ifndef __REACTOS__ + if (ro->ro_rt == 0) + rtalloc_ign(ro, RTF_PRCLONING); + if (ro->ro_rt == 0) { + ipstat.ips_noroute++; + OS_DbgPrint(OSK_MID_TRACE,("EHOSTUNREACH\n")); + error = EHOSTUNREACH; + goto bad; + } + ia = ifatoia(ro->ro_rt->rt_ifa); + ifp = ro->ro_rt->rt_ifp; + ro->ro_rt->rt_use++; + if (ro->ro_rt->rt_flags & RTF_GATEWAY) + dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; +#endif + } +#ifndef __REACTOS__ + if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { + struct in_multi *inm; + + m->m_flags |= M_MCAST; + /* + * IP destination address is multicast. Make sure "dst" + * still points to the address in "ro". (It may have been + * changed to point to a gateway address, above.) + */ + dst = (struct sockaddr_in *)&ro->ro_dst; + /* + * See if the caller provided any multicast options + */ + if (imo != NULL) { + ip->ip_ttl = imo->imo_multicast_ttl; + if (imo->imo_multicast_ifp != NULL) + ifp = imo->imo_multicast_ifp; + if (imo->imo_multicast_vif != -1) + ip->ip_src.s_addr = + ip_mcast_src(imo->imo_multicast_vif); + } else + ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL; + /* + * Confirm that the outgoing interface supports multicast. + */ + if ((imo == NULL) || (imo->imo_multicast_vif == -1)) { + if ((ifp->if_flags & IFF_MULTICAST) == 0) { + ipstat.ips_noroute++; + error = ENETUNREACH; + goto bad; + } + } + /* + * If source address not specified yet, use address + * of outgoing interface. + */ + if (ip->ip_src.s_addr == INADDR_ANY) { + register struct in_ifaddr *ia; + + panic("We don't handle this yet\n"); + for (ia = in_ifaddr; ia; ia = ia->ia_next) + if (ia->ia_ifp == ifp) { + ip->ip_src = IA_SIN(ia)->sin_addr; + break; + } + } + + IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm); + if (inm != NULL && + (imo == NULL || imo->imo_multicast_loop)) { + /* + * If we belong to the destination multicast group + * on the outgoing interface, and the caller did not + * forbid loopback, loop back a copy. + */ + ip_mloopback(ifp, m, dst); + } + else { + /* + * If we are acting as a multicast router, perform + * multicast forwarding as if the packet had just + * arrived on the interface to which we are about + * to send. The multicast forwarding function + * recursively calls this function, using the + * IP_FORWARDING flag to prevent infinite recursion. + * + * Multicasts that are looped back by ip_mloopback(), + * above, will be forwarded by the ip_input() routine, + * if necessary. + */ + if (ip_mrouter && (flags & IP_FORWARDING) == 0) { + /* + * Check if rsvp daemon is running. If not, don't + * set ip_moptions. This ensures that the packet + * is multicast and not just sent down one link + * as prescribed by rsvpd. + */ + if (!rsvp_on) + imo = NULL; + if (ip_mforward(ip, ifp, m, imo) != 0) { + m_freem(m); + goto done; + } + } + } + + /* + * Multicasts with a time-to-live of zero may be looped- + * back, above, but must not be transmitted on a network. + * Also, multicasts addressed to the loopback interface + * are not sent -- the above call to ip_mloopback() will + * loop back a copy if this host actually belongs to the + * destination group on the loopback interface. + */ + if (ip->ip_ttl == 0 || ifp->if_flags & IFF_LOOPBACK) { + m_freem(m); + goto done; + } + + goto sendit; + } +#endif + +#ifndef notdef + /* + * If source address not specified yet, use address + * of outgoing interface. + */ + if (ip->ip_src.s_addr == INADDR_ANY) + ip->ip_src = IA_SIN(ia)->sin_addr; +#endif +#ifndef __REACTOS__ + /* + * Verify that we have any chance at all of being able to queue + * the packet or packet fragments + */ + if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >= + ifp->if_snd.ifq_maxlen) { + error = ENOBUFS; + goto bad; + } + + /* + * Look for broadcast address and + * and verify user is allowed to send + * such a packet. + */ + if (in_broadcast(dst->sin_addr, ifp)) { + if ((ifp->if_flags & IFF_BROADCAST) == 0) { + error = EADDRNOTAVAIL; + goto bad; + } + if ((flags & IP_ALLOWBROADCAST) == 0) { + error = EACCES; + goto bad; + } + /* don't allow broadcast messages to be fragmented */ + if ((u_short)ip->ip_len > ifp->if_mtu) { + error = EMSGSIZE; + goto bad; + } + m->m_flags |= M_BCAST; + } else + m->m_flags &= ~M_BCAST; +#endif + +sendit: +#ifndef __REACTOS__ + /* + * Check with the firewall... + */ + if (!(*ip_fw_chk_ptr)(m,ip,ifp,1)) { + error = EACCES; + goto done; + } +#endif + + /* + * If small enough for interface, can just send directly. + */ + if ((u_short)ip->ip_len <= 1400 /* XXX Get MTU from Interface */) { + ip->ip_len = htons((u_short)ip->ip_len); + ip->ip_off = htons((u_short)ip->ip_off); + ip->ip_sum = 0; + ip->ip_sum = in_cksum(m, hlen); +#ifdef __REACTOS__ + if( OtcpEvent.PacketSend ) { + OS_DbgPrint(OSK_MID_TRACE,("Mark\n")); + error = OtcpEvent.PacketSend( OtcpEvent.ClientData, + m->m_data, m->m_len ); + goto done; + } +#else + error = (*ifp->if_output)(ifp, m, + (struct sockaddr *)dst, ro->ro_rt); +#endif + } + /* + * Too large for interface; fragment if possible. + * Must be able to put at least 8 bytes per fragment. + */ + if (ip->ip_off & IP_DF) { + error = EMSGSIZE; +#if 1 + /* + * This case can happen if the user changed the MTU + * of an interface after enabling IP on it. Because + * most netifs don't keep track of routes pointing to + * them, there is no way for one to update all its + * routes when the MTU is changed. + */ + if ((ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST)) + && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU) + && (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) { + ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu; + } +#endif + ipstat.ips_cantfrag++; + goto bad; + } +#ifndef __REACTOS__ + len = (ifp->if_mtu - hlen) &~ 7; + if (len < 8) { + error = EMSGSIZE; + goto bad; + } +#else + OS_DbgPrint(OSK_MID_TRACE,("Using default mtu of 1500\n")); + len = (1500 - hlen) & ~7; +#endif + + { + int mhlen, firstlen = len; + struct mbuf **mnext = &m->m_nextpkt; + + /* + * Loop through length of segment after first fragment, + * make new header and copy data of each part and link onto chain. + */ + m0 = m; + mhlen = sizeof (struct ip); + for (off = hlen + len; off < (u_short)ip->ip_len; off += len) { + OS_DbgPrint(OSK_MID_TRACE,("off = %d, len = %d\n", off, len)); + MGETHDR(m, M_DONTWAIT, MT_HEADER); + if (m == 0) { + error = ENOBUFS; + ipstat.ips_odropped++; + goto sendorfree; + } + m->m_data += max_linkhdr; + mhip = mtod(m, struct ip *); + *mhip = *ip; + if (hlen > sizeof (struct ip)) { + mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); + mhip->ip_hl = mhlen >> 2; + } + m->m_len = mhlen; + mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); + if (ip->ip_off & IP_MF) + mhip->ip_off |= IP_MF; + if (off + len >= (u_short)ip->ip_len) + len = (u_short)ip->ip_len - off; + else + mhip->ip_off |= IP_MF; + mhip->ip_len = htons((u_short)(len + mhlen)); + m->m_next = m_copy(m0, off, len); + if (m->m_next == 0) { + (void) m_free(m); + error = ENOBUFS; /* ??? */ + ipstat.ips_odropped++; + goto sendorfree; + } + m->m_pkthdr.len = mhlen + len; + m->m_pkthdr.rcvif = (struct ifnet *)0; + mhip->ip_off = htons((u_short)mhip->ip_off); + mhip->ip_sum = 0; + mhip->ip_sum = in_cksum(m, mhlen); + *mnext = m; + mnext = &m->m_nextpkt; + ipstat.ips_ofragments++; + } + /* + * Update first fragment by trimming what's been copied out + * and updating header, then send each fragment (in order). + */ + m = m0; + OS_DbgPrint(OSK_MID_TRACE,("hlen %d firstlen %d ip->ip_len %x\n", + hlen, firstlen, ip->ip_len)); + OS_DbgPrint(OSK_MID_TRACE,("hlen + firstlen - ip->ip_len %d\n", + hlen + firstlen - (u_short)ip->ip_len)); + m_adj(m, hlen + firstlen - (u_short)ip->ip_len); + m->m_pkthdr.len = hlen + firstlen; + ip->ip_len = htons((u_short)(m->m_pkthdr.len)); + ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); + ip->ip_sum = 0; + ip->ip_sum = in_cksum(m, hlen - sizeof( struct ip ) ); + + OS_DbgPrint(OSK_MID_TRACE,("ip->ip_len = %x\n", ip->ip_len)); + +sendorfree: + for (m = m0; m; m = m0) { + m0 = m->m_nextpkt; + m->m_nextpkt = 0; +#ifndef __REACTOS__ + if (error == 0) + error = (*ifp->if_output)(ifp, m, + (struct sockaddr *)dst, ro->ro_rt); + else + m_freem(m); +#else + if( error == 0 && OtcpEvent.PacketSend ) { + OS_DbgPrint(OSK_MID_TRACE,("Mark\n")); + error = OtcpEvent.PacketSend( OtcpEvent.ClientData, + m->m_data, m->m_len ); + } + + OS_DbgPrint(OSK_MID_TRACE,("Error from upper layer: %d\n", error)); +#endif + } + + if (error == 0) + ipstat.ips_fragmented++; } +done: + if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt) + RTFREE(ro->ro_rt); - OS_DbgPrint(OSK_MID_TRACE,("Error from upper layer: %d\n", error)); + return (error); +bad: + m_freem(m0); + goto done; +} - return (error); +/* + * Insert IP options into preformed packet. + * Adjust IP destination as required for IP source routing, + * as indicated by a non-zero in_addr at the start of the options. + * + * XXX This routine assumes that the packet has no options in place. + */ +static struct mbuf * +ip_insertoptions(m, opt, phlen) + register struct mbuf *m; + struct mbuf *opt; + int *phlen; +{ + register struct ipoption *p = mtod(opt, struct ipoption *); + struct mbuf *n; + register struct ip *ip = mtod(m, struct ip *); + unsigned optlen; + + optlen = opt->m_len - sizeof(p->ipopt_dst); + if (optlen + (u_short)ip->ip_len > IP_MAXPACKET) + return (m); /* XXX should fail */ + if (p->ipopt_dst.s_addr) + ip->ip_dst = p->ipopt_dst; + if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) { + MGETHDR(n, M_DONTWAIT, MT_HEADER); + if (n == 0) + return (m); + n->m_pkthdr.len = m->m_pkthdr.len + optlen; + m->m_len -= sizeof(struct ip); + m->m_data += sizeof(struct ip); + n->m_next = m; + m = n; + m->m_len = optlen + sizeof(struct ip); + m->m_data += max_linkhdr; + (void)memcpy(mtod(m, void *), ip, sizeof(struct ip)); + } else { + m->m_data -= optlen; + m->m_len += optlen; + m->m_pkthdr.len += optlen; + ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip)); + } + ip = mtod(m, struct ip *); + (void)memcpy(ip + 1, p->ipopt_list, (unsigned)optlen); + *phlen = sizeof(struct ip) + optlen; + ip->ip_hl = *phlen >> 2; + ip->ip_len += optlen; + return (m); +} + +/* + * Copy options from ip to jp, + * omitting those not copied during fragmentation. + */ +int +ip_optcopy(ip, jp) + struct ip *ip, *jp; +{ + register u_char *cp, *dp; + int opt, optlen, cnt; + + cp = (u_char *)(ip + 1); + dp = (u_char *)(jp + 1); + cnt = (ip->ip_hl << 2) - sizeof (struct ip); + for (; cnt > 0; cnt -= optlen, cp += optlen) { + opt = cp[0]; + if (opt == IPOPT_EOL) + break; + if (opt == IPOPT_NOP) { + /* Preserve for IP mcast tunnel's LSRR alignment. */ + *dp++ = IPOPT_NOP; + optlen = 1; + continue; + } else + optlen = cp[IPOPT_OLEN]; + /* bogus lengths should have been caught by ip_dooptions */ + if (optlen > cnt) + optlen = cnt; + if (IPOPT_COPIED(opt)) { + (void)memcpy(dp, cp, (unsigned)optlen); + dp += optlen; + } + } + for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++) + *dp++ = IPOPT_EOL; + return (optlen); } /* @@ -160,6 +617,14 @@ ip_ctloutput(op, so, level, optname, mp) case PRCO_SETOPT: switch (optname) { + case IP_OPTIONS: +#ifdef notyet + case IP_RETOPTS: + return (ip_pcbopts(optname, &inp->inp_options, m)); +#else + return (ip_pcbopts(&inp->inp_options, m)); +#endif + case IP_TOS: case IP_TTL: case IP_RECVOPTS: @@ -199,6 +664,16 @@ ip_ctloutput(op, so, level, optname, mp) } break; #undef OPTSET + + case IP_MULTICAST_IF: + case IP_MULTICAST_VIF: + case IP_MULTICAST_TTL: + case IP_MULTICAST_LOOP: + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + error = ip_setmoptions(optname, &inp->inp_moptions, m); + break; + default: error = ENOPROTOOPT; break; @@ -254,6 +729,15 @@ ip_ctloutput(op, so, level, optname, mp) *mtod(m, int *) = optval; break; + case IP_MULTICAST_IF: + case IP_MULTICAST_VIF: + case IP_MULTICAST_TTL: + case IP_MULTICAST_LOOP: + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + error = ip_getmoptions(optname, inp->inp_moptions, mp); + break; + default: error = ENOPROTOOPT; break; @@ -262,3 +746,491 @@ ip_ctloutput(op, so, level, optname, mp) } return (error); } + +/* + * Set up IP options in pcb for insertion in output packets. + * Store in mbuf with pointer in pcbopt, adding pseudo-option + * with destination address if source routed. + */ +int +#ifdef notyet +ip_pcbopts(optname, pcbopt, m) + int optname; +#else +ip_pcbopts(pcbopt, m) +#endif + struct mbuf **pcbopt; + register struct mbuf *m; +{ + register cnt, optlen; + register u_char *cp; + u_char opt; + + /* turn off any old options */ + if (*pcbopt) + (void)m_free(*pcbopt); + *pcbopt = 0; + if (m == (struct mbuf *)0 || m->m_len == 0) { + /* + * Only turning off any previous options. + */ + if (m) + (void)m_free(m); + return (0); + } + +#ifndef vax + if (m->m_len % sizeof(long)) + goto bad; +#endif + /* + * IP first-hop destination address will be stored before + * actual options; move other options back + * and clear it when none present. + */ + if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN]) + goto bad; + cnt = m->m_len; + m->m_len += sizeof(struct in_addr); + cp = mtod(m, u_char *) + sizeof(struct in_addr); + ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt); + bzero(mtod(m, caddr_t), sizeof(struct in_addr)); + + for (; cnt > 0; cnt -= optlen, cp += optlen) { + opt = cp[IPOPT_OPTVAL]; + if (opt == IPOPT_EOL) + break; + if (opt == IPOPT_NOP) + optlen = 1; + else { + optlen = cp[IPOPT_OLEN]; + if (optlen <= IPOPT_OLEN || optlen > cnt) + goto bad; + } + switch (opt) { + + default: + break; + + case IPOPT_LSRR: + case IPOPT_SSRR: + /* + * user process specifies route as: + * ->A->B->C->D + * D must be our final destination (but we can't + * check that since we may not have connected yet). + * A is first hop destination, which doesn't appear in + * actual IP option, but is stored before the options. + */ + if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr)) + goto bad; + m->m_len -= sizeof(struct in_addr); + cnt -= sizeof(struct in_addr); + optlen -= sizeof(struct in_addr); + cp[IPOPT_OLEN] = optlen; + /* + * Move first hop before start of options. + */ + bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t), + sizeof(struct in_addr)); + /* + * Then copy rest of options back + * to close up the deleted entry. + */ + ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] + + sizeof(struct in_addr)), + (caddr_t)&cp[IPOPT_OFFSET+1], + (unsigned)cnt + sizeof(struct in_addr)); + break; + } + } + if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr)) + goto bad; + *pcbopt = m; + return (0); + +bad: + (void)m_free(m); + return (EINVAL); +} + +/* + * Set the IP multicast options in response to user setsockopt(). + */ +int +ip_setmoptions(optname, imop, m) + int optname; + struct ip_moptions **imop; + struct mbuf *m; +{ + register int error = 0; + u_char loop; + register int i; + struct in_addr addr; + register struct ip_mreq *mreq; + register struct ifnet *ifp; + register struct ip_moptions *imo = *imop; + struct route ro; + register struct sockaddr_in *dst; + int s; + + if (imo == NULL) { + /* + * No multicast option buffer attached to the pcb; + * allocate one and initialize to default values. + */ + imo = (struct ip_moptions*)malloc(sizeof(*imo), M_IPMOPTS, + M_WAITOK); + + if (imo == NULL) + return (ENOBUFS); + *imop = imo; + imo->imo_multicast_ifp = NULL; + imo->imo_multicast_vif = -1; + imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL; + imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP; + imo->imo_num_memberships = 0; + } + + switch (optname) { +#ifndef __REACTOS__ + /* store an index number for the vif you wanna use in the send */ + case IP_MULTICAST_VIF: + if (!legal_vif_num) { + error = EOPNOTSUPP; + break; + } + if (m == NULL || m->m_len != sizeof(int)) { + error = EINVAL; + break; + } + i = *(mtod(m, int *)); + if (!legal_vif_num(i) && (i != -1)) { + error = EINVAL; + break; + } + imo->imo_multicast_vif = i; + break; + + case IP_MULTICAST_IF: + /* + * Select the interface for outgoing multicast packets. + */ + if (m == NULL || m->m_len != sizeof(struct in_addr)) { + error = EINVAL; + break; + } + addr = *(mtod(m, struct in_addr *)); + /* + * INADDR_ANY is used to remove a previous selection. + * When no interface is selected, a default one is + * chosen every time a multicast packet is sent. + */ + if (addr.s_addr == INADDR_ANY) { + imo->imo_multicast_ifp = NULL; + break; + } + /* + * The selected interface is identified by its local + * IP address. Find the interface and confirm that + * it supports multicasting. + */ + s = splimp(); + INADDR_TO_IFP(addr, ifp); + if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { + error = EADDRNOTAVAIL; + break; + } + imo->imo_multicast_ifp = ifp; + splx(s); + break; + + case IP_MULTICAST_TTL: + /* + * Set the IP time-to-live for outgoing multicast packets. + */ + if (m == NULL || m->m_len != 1) { + error = EINVAL; + break; + } + imo->imo_multicast_ttl = *(mtod(m, u_char *)); + break; + + case IP_MULTICAST_LOOP: + /* + * Set the loopback flag for outgoing multicast packets. + * Must be zero or one. + */ + if (m == NULL || m->m_len != 1 || + (loop = *(mtod(m, u_char *))) > 1) { + error = EINVAL; + break; + } + imo->imo_multicast_loop = loop; + break; + + case IP_ADD_MEMBERSHIP: + /* + * Add a multicast group membership. + * Group must be a valid IP multicast address. + */ + if (m == NULL || m->m_len != sizeof(struct ip_mreq)) { + error = EINVAL; + break; + } + mreq = mtod(m, struct ip_mreq *); + if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) { + error = EINVAL; + break; + } + s = splimp(); + /* + * If no interface address was provided, use the interface of + * the route to the given multicast address. + */ + if (mreq->imr_interface.s_addr == INADDR_ANY) { + bzero((caddr_t)&ro, sizeof(ro)); + dst = (struct sockaddr_in *)&ro.ro_dst; + dst->sin_len = sizeof(*dst); + dst->sin_family = AF_INET; + dst->sin_addr = mreq->imr_multiaddr; + rtalloc(&ro); + if (ro.ro_rt == NULL) { + error = EADDRNOTAVAIL; + splx(s); + break; + } + ifp = ro.ro_rt->rt_ifp; + rtfree(ro.ro_rt); + } + else { + INADDR_TO_IFP(mreq->imr_interface, ifp); + } + + /* + * See if we found an interface, and confirm that it + * supports multicast. + */ + if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { + error = EADDRNOTAVAIL; + splx(s); + break; + } + /* + * See if the membership already exists or if all the + * membership slots are full. + */ + for (i = 0; i < imo->imo_num_memberships; ++i) { + if (imo->imo_membership[i]->inm_ifp == ifp && + imo->imo_membership[i]->inm_addr.s_addr + == mreq->imr_multiaddr.s_addr) + break; + } + if (i < imo->imo_num_memberships) { + error = EADDRINUSE; + splx(s); + break; + } + if (i == IP_MAX_MEMBERSHIPS) { + error = ETOOMANYREFS; + splx(s); + break; + } + /* + * Everything looks good; add a new record to the multicast + * address list for the given interface. + */ + if ((imo->imo_membership[i] = + in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) { + error = ENOBUFS; + splx(s); + break; + } + ++imo->imo_num_memberships; + splx(s); + break; + + case IP_DROP_MEMBERSHIP: + /* + * Drop a multicast group membership. + * Group must be a valid IP multicast address. + */ + if (m == NULL || m->m_len != sizeof(struct ip_mreq)) { + error = EINVAL; + break; + } + mreq = mtod(m, struct ip_mreq *); + if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) { + error = EINVAL; + break; + } + + s = splimp(); + /* + * If an interface address was specified, get a pointer + * to its ifnet structure. + */ + if (mreq->imr_interface.s_addr == INADDR_ANY) + ifp = NULL; + else { + INADDR_TO_IFP(mreq->imr_interface, ifp); + if (ifp == NULL) { + error = EADDRNOTAVAIL; + splx(s); + break; + } + } + /* + * Find the membership in the membership array. + */ + for (i = 0; i < imo->imo_num_memberships; ++i) { + if ((ifp == NULL || + imo->imo_membership[i]->inm_ifp == ifp) && + imo->imo_membership[i]->inm_addr.s_addr == + mreq->imr_multiaddr.s_addr) + break; + } + if (i == imo->imo_num_memberships) { + error = EADDRNOTAVAIL; + splx(s); + break; + } + /* + * Give up the multicast address record to which the + * membership points. + */ + in_delmulti(imo->imo_membership[i]); + /* + * Remove the gap in the membership array. + */ + for (++i; i < imo->imo_num_memberships; ++i) + imo->imo_membership[i-1] = imo->imo_membership[i]; + --imo->imo_num_memberships; + splx(s); + break; +#endif + default: + error = EOPNOTSUPP; + break; + } + + /* + * If all options have default values, no need to keep the mbuf. + */ + if (imo->imo_multicast_ifp == NULL && + imo->imo_multicast_vif == -1 && + imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL && + imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP && + imo->imo_num_memberships == 0) { + free(*imop, M_IPMOPTS); + *imop = NULL; + } + + return (error); +} + +/* + * Return the IP multicast options in response to user getsockopt(). + */ +int +ip_getmoptions(optname, imo, mp) + int optname; + register struct ip_moptions *imo; + register struct mbuf **mp; +{ + u_char *ttl; + u_char *loop; + struct in_addr *addr; + struct in_ifaddr *ia; + + *mp = m_get(M_WAIT, MT_SOOPTS); + + switch (optname) { +#ifndef __REACTOS__ + case IP_MULTICAST_VIF: + if (imo != NULL) + *(mtod(*mp, int *)) = imo->imo_multicast_vif; + else + *(mtod(*mp, int *)) = -1; + (*mp)->m_len = sizeof(int); + return(0); + + case IP_MULTICAST_IF: + addr = mtod(*mp, struct in_addr *); + (*mp)->m_len = sizeof(struct in_addr); + if (imo == NULL || imo->imo_multicast_ifp == NULL) + addr->s_addr = INADDR_ANY; + else { + IFP_TO_IA(imo->imo_multicast_ifp, ia); + addr->s_addr = (ia == NULL) ? INADDR_ANY + : IA_SIN(ia)->sin_addr.s_addr; + } + return (0); + + case IP_MULTICAST_TTL: + ttl = mtod(*mp, u_char *); + (*mp)->m_len = 1; + *ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL + : imo->imo_multicast_ttl; + return (0); + + case IP_MULTICAST_LOOP: + loop = mtod(*mp, u_char *); + (*mp)->m_len = 1; + *loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP + : imo->imo_multicast_loop; + return (0); +#endif + default: + return (EOPNOTSUPP); + } +} + +/* + * Discard the IP multicast options. + */ +void +ip_freemoptions(imo) + register struct ip_moptions *imo; +{ + register int i; + + if (imo != NULL) { + for (i = 0; i < imo->imo_num_memberships; ++i) + in_delmulti(imo->imo_membership[i]); + free(imo, M_IPMOPTS); + } +} + +#ifndef __REACTOS__ +/* + * Routine called from ip_output() to loop back a copy of an IP multicast + * packet to the input queue of a specified interface. Note that this + * calls the output routine of the loopback "driver", but with an interface + * pointer that might NOT be a loopback interface -- evil, but easier than + * replicating that code here. + */ +static void +ip_mloopback(ifp, m, dst) + struct ifnet *ifp; + register struct mbuf *m; + register struct sockaddr_in *dst; +{ + register struct ip *ip; + struct mbuf *copym; + + copym = m_copy(m, 0, M_COPYALL); + if (copym != NULL) { + /* + * We don't bother to fragment if the IP length is greater + * than the interface's MTU. Can this possibly matter? + */ + ip = mtod(copym, struct ip *); + ip->ip_len = htons((u_short)ip->ip_len); + ip->ip_off = htons((u_short)ip->ip_off); + ip->ip_sum = 0; + ip->ip_sum = in_cksum(copym, ip->ip_hl << 2); + (void) looutput(ifp, copym, (struct sockaddr *)dst, NULL); + } +} +#endif diff --git a/reactos/drivers/lib/oskittcp/oskittcp/raw_cb.c b/reactos/drivers/lib/oskittcp/oskittcp/raw_cb.c new file mode 100644 index 00000000000..c0d39d84729 --- /dev/null +++ b/reactos/drivers/lib/oskittcp/oskittcp/raw_cb.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1980, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)raw_cb.c 8.1 (Berkeley) 6/10/93 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * Routines to manage the raw protocol control blocks. + * + * TODO: + * hash lookups by protocol family/protocol + address family + * take care of unique address problems per AF? + * redo address binding to allow wildcards + */ + +u_long raw_sendspace = RAWSNDQ; +u_long raw_recvspace = RAWRCVQ; + +/* + * Allocate a control block and a nominal amount + * of buffer space for the socket. + */ +int +raw_attach(so, proto) + register struct socket *so; + int proto; +{ + register struct rawcb *rp = sotorawcb(so); + int error; + + /* + * It is assumed that raw_attach is called + * after space has been allocated for the + * rawcb. + */ + if (rp == 0) + return (ENOBUFS); + error = soreserve(so, raw_sendspace, raw_recvspace); + if (error) + return (error); + rp->rcb_socket = so; + rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family; + rp->rcb_proto.sp_protocol = proto; + insque(rp, &rawcb); + return (0); +} + +/* + * Detach the raw connection block and discard + * socket resources. + */ +void +raw_detach(rp) + register struct rawcb *rp; +{ + struct socket *so = rp->rcb_socket; + + so->so_pcb = 0; + sofree(so); + remque(rp); +#ifdef notdef + if (rp->rcb_laddr) + m_freem(dtom(rp->rcb_laddr)); + rp->rcb_laddr = 0; +#endif + free((caddr_t)(rp), M_PCB); +} + +/* + * Disconnect and possibly release resources. + */ +void +raw_disconnect(rp) + struct rawcb *rp; +{ + +#ifdef notdef + if (rp->rcb_faddr) + m_freem(dtom(rp->rcb_faddr)); + rp->rcb_faddr = 0; +#endif + if (rp->rcb_socket->so_state & SS_NOFDREF) + raw_detach(rp); +} + +#ifdef notdef +int +raw_bind(so, nam) + register struct socket *so; + struct mbuf *nam; +{ + struct sockaddr *addr = mtod(nam, struct sockaddr *); + register struct rawcb *rp; + + if (ifnet == 0) + return (EADDRNOTAVAIL); + rp = sotorawcb(so); + nam = m_copym(nam, 0, M_COPYALL, M_WAITOK); + rp->rcb_laddr = mtod(nam, struct sockaddr *); + return (0); +} +#endif diff --git a/reactos/drivers/lib/oskittcp/oskittcp/raw_ip.c b/reactos/drivers/lib/oskittcp/oskittcp/raw_ip.c new file mode 100644 index 00000000000..9bb88d77683 --- /dev/null +++ b/reactos/drivers/lib/oskittcp/oskittcp/raw_ip.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 1982, 1986, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)raw_ip.c 8.7 (Berkeley) 5/15/95 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#ifndef __REACTOS__ +#include +#endif + +#include +#include + +static struct inpcbhead ripcb; +static struct inpcbinfo ripcbinfo; + +/* + * Nominal space allocated to a raw ip socket. + */ +#define RIPSNDQ 8192 +#define RIPRCVQ 8192 + +/* + * Raw interface to IP protocol. + */ + +/* + * Initialize raw connection block q. + */ +void +rip_init() +{ + LIST_INIT(&ripcb); + ripcbinfo.listhead = &ripcb; + /* + * XXX We don't use the hash list for raw IP, but it's easier + * to allocate a one entry hash list than it is to check all + * over the place for hashbase == NULL. + */ + ripcbinfo.hashbase = phashinit(1, M_PCB, &ripcbinfo.hashsize); +} + +static struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET }; +/* + * Setup generic address and protocol structures + * for raw_input routine, then pass them along with + * mbuf chain. + */ +void +rip_input(m) + struct mbuf *m; +{ + register struct ip *ip = mtod(m, struct ip *); + register struct inpcb *inp; + struct socket *last = 0; + + ripsrc.sin_addr = ip->ip_src; + OS_DbgPrint(OSK_MID_TRACE,("ripsrc: %x\n", ip->ip_src)); + for (inp = ripcb.lh_first; inp != NULL; inp = inp->inp_list.le_next) { + OS_DbgPrint(OSK_MID_TRACE,("Looking at %d %x -> %x\n", + inp->inp_ip.ip_p, + inp->inp_laddr.s_addr, + inp->inp_faddr.s_addr)); + if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p) + continue; + if (inp->inp_laddr.s_addr && + inp->inp_laddr.s_addr != ip->ip_dst.s_addr) + continue; + if (inp->inp_faddr.s_addr && + inp->inp_faddr.s_addr != ip->ip_src.s_addr) + continue; + if (last) { + struct mbuf *n = m_copy(m, 0, (int)M_COPYALL); + if (n) { + if (sbappendaddr(&last->so_rcv, + (struct sockaddr *)&ripsrc, n, + (struct mbuf *)0) == 0) + /* should notify about lost packet */ + m_freem(n); + else + sorwakeup(last); + } + } + last = inp->inp_socket; + } + if (last) { + if (sbappendaddr(&last->so_rcv, (struct sockaddr *)&ripsrc, + m, (struct mbuf *)0) == 0) + m_freem(m); + else + sorwakeup(last); + } else { + m_freem(m); + ipstat.ips_noproto++; + ipstat.ips_delivered--; + } +} + +/* + * Generate IP header and pass packet to ip_output. + * Tack on options user may have setup with control call. + */ +int +rip_output(m, so, dst) + register struct mbuf *m; + struct socket *so; + u_long dst; +{ + register struct ip *ip; + register struct inpcb *inp = sotoinpcb(so); + struct mbuf *opts; + int flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST; + + /* + * If the user handed us a complete IP packet, use it. + * Otherwise, allocate an mbuf for a header and fill it in. + */ + if ((inp->inp_flags & INP_HDRINCL) == 0) { + M_PREPEND(m, sizeof(struct ip), M_WAIT); + ip = mtod(m, struct ip *); + ip->ip_tos = 0; + ip->ip_off = 0; + ip->ip_p = inp->inp_ip.ip_p; + ip->ip_len = m->m_pkthdr.len; + ip->ip_src = inp->inp_laddr; + ip->ip_dst.s_addr = dst; + ip->ip_ttl = MAXTTL; + } else { + ip = mtod(m, struct ip *); + /* don't allow both user specified and setsockopt options, + and don't allow packet length sizes that will crash */ + if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) || + (ip->ip_len > m->m_pkthdr.len)) { + m_freem(m); + return EINVAL; + } + if (ip->ip_id == 0) + ip->ip_id = htons(ip_id++); + /* XXX prevent ip_output from overwriting header fields */ + flags |= IP_RAWOUTPUT; + ipstat.ips_rawout++; + } + return (ip_output(m, inp->inp_options, &inp->inp_route, flags, + inp->inp_moptions)); +} + +/* + * Raw IP socket option processing. + */ +int +rip_ctloutput(op, so, level, optname, m) + int op; + struct socket *so; + int level, optname; + struct mbuf **m; +{ + register int error = EINVAL; +#ifndef __REACTOS__ + register struct inpcb *inp = sotoinpcb(so); + + if (level != IPPROTO_IP) { + if (op == PRCO_SETOPT && *m) + (void)m_free(*m); + return (EINVAL); + } + + switch (optname) { + + case IP_HDRINCL: + error = 0; + if (op == PRCO_SETOPT) { + if (m == 0 || *m == 0 || (*m)->m_len < sizeof (int)) + error = EINVAL; + else if (*mtod(*m, int *)) + inp->inp_flags |= INP_HDRINCL; + else + inp->inp_flags &= ~INP_HDRINCL; + if (*m) + (void)m_free(*m); + } else { + *m = m_get(M_WAIT, MT_SOOPTS); + (*m)->m_len = sizeof (int); + *mtod(*m, int *) = inp->inp_flags & INP_HDRINCL; + } + return (error); + + case IP_FW_GET: + if (ip_fw_ctl_ptr==NULL || op == PRCO_SETOPT) { + if (*m) (void)m_free(*m); + return(EINVAL); + } + return (*ip_fw_ctl_ptr)(optname, m); + case IP_FW_ADD: + case IP_FW_DEL: + case IP_FW_FLUSH: + case IP_FW_ZERO: + if (ip_fw_ctl_ptr==NULL || op != PRCO_SETOPT) { + if (*m) (void)m_free(*m); + return(EINVAL); + } + + return (*ip_fw_ctl_ptr)(optname, m); + return(error); + + case IP_RSVP_ON: + return ip_rsvp_init(so); + break; + + case IP_RSVP_OFF: + return ip_rsvp_done(); + break; + + case IP_RSVP_VIF_ON: + return ip_rsvp_vif_init(so, *m); + + case IP_RSVP_VIF_OFF: + return ip_rsvp_vif_done(so, *m); + + case MRT_INIT: + case MRT_DONE: + case MRT_ADD_VIF: + case MRT_DEL_VIF: + case MRT_ADD_MFC: + case MRT_DEL_MFC: + case MRT_VERSION: + case MRT_ASSERT: + if (op == PRCO_SETOPT) { + error = ip_mrouter_set(optname, so, *m); + if (*m) + (void)m_free(*m); + } else if (op == PRCO_GETOPT) { + error = ip_mrouter_get(optname, so, m); + } else + error = EINVAL; + return (error); + } + return (ip_ctloutput(op, so, level, optname, m)); +#else + return error; +#endif +} + +static u_long rip_sendspace = RIPSNDQ; /* XXX sysctl ? */ +static u_long rip_recvspace = RIPRCVQ; /* XXX sysctl ? */ + +/*ARGSUSED*/ +int +rip_usrreq(so, req, m, nam, control) + register struct socket *so; + int req; + struct mbuf *m, *nam, *control; +{ + register int error = 0; + register struct inpcb *inp = sotoinpcb(so); + + if (req == PRU_CONTROL) + return (in_control(so, (u_long)m, (caddr_t)nam, + (struct ifnet *)control)); + + switch (req) { + + case PRU_ATTACH: + if (inp) + panic("rip_attach"); + if ((so->so_state & SS_PRIV) == 0) { + error = EACCES; + break; + } + if ((error = soreserve(so, rip_sendspace, rip_recvspace)) || + (error = in_pcballoc(so, &ripcbinfo))) + break; + inp = (struct inpcb *)so->so_pcb; + inp->inp_ip.ip_p = (int)nam; + break; + + case PRU_DISCONNECT: + if ((so->so_state & SS_ISCONNECTED) == 0) { + error = ENOTCONN; + break; + } + /* FALLTHROUGH */ + case PRU_ABORT: + soisdisconnected(so); + /* FALLTHROUGH */ + case PRU_DETACH: + if (inp == 0) + panic("rip_detach"); +#ifndef __REACTOS__ + if (so == ip_mrouter) + ip_mrouter_done(); + ip_rsvp_force_done(so); + if (so == ip_rsvpd) + ip_rsvp_done(); +#endif + in_pcbdetach(inp); + break; + + case PRU_BIND: + { + struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); + + if (nam->m_len != sizeof(*addr)) { + error = EINVAL; + break; + } + if ((ifnet == 0) || + ((addr->sin_family != AF_INET) && + (addr->sin_family != AF_IMPLINK)) || + (addr->sin_addr.s_addr && + ifa_ifwithaddr((struct sockaddr *)addr) == 0)) { + error = EADDRNOTAVAIL; + break; + } + inp->inp_laddr = addr->sin_addr; + break; + } + case PRU_CONNECT: + { + struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); + + if (nam->m_len != sizeof(*addr)) { + error = EINVAL; + break; + } + if (ifnet == 0) { + error = EADDRNOTAVAIL; + break; + } + if ((addr->sin_family != AF_INET) && + (addr->sin_family != AF_IMPLINK)) { + error = EAFNOSUPPORT; + break; + } + inp->inp_faddr = addr->sin_addr; + soisconnected(so); + break; + } + + case PRU_CONNECT2: + error = EOPNOTSUPP; + break; + + /* + * Mark the connection as being incapable of further input. + */ + case PRU_SHUTDOWN: + socantsendmore(so); + break; + + /* + * Ship a packet out. The appropriate raw output + * routine handles any massaging necessary. + */ + case PRU_SEND: + { + register u_long dst; + + if (so->so_state & SS_ISCONNECTED) { + if (nam) { + error = EISCONN; + break; + } + dst = inp->inp_faddr.s_addr; + } else { + if (nam == NULL) { + error = ENOTCONN; + break; + } + dst = mtod(nam, struct sockaddr_in *)->sin_addr.s_addr; + } + error = rip_output(m, so, dst); + m = NULL; + break; + } + + case PRU_SENSE: + /* + * stat: don't bother with a blocksize. + */ + return (0); + + /* + * Not supported. + */ + case PRU_RCVOOB: + case PRU_RCVD: + case PRU_LISTEN: + case PRU_ACCEPT: + case PRU_SENDOOB: + error = EOPNOTSUPP; + break; + + case PRU_SOCKADDR: + in_setsockaddr(inp, nam); + break; + + case PRU_PEERADDR: + in_setpeeraddr(inp, nam); + break; + + default: + panic("rip_usrreq"); + } + if (m != NULL) + m_freem(m); + return (error); +} diff --git a/reactos/drivers/lib/oskittcp/oskittcp/raw_usrreq.c b/reactos/drivers/lib/oskittcp/oskittcp/raw_usrreq.c new file mode 100644 index 00000000000..286bcced72d --- /dev/null +++ b/reactos/drivers/lib/oskittcp/oskittcp/raw_usrreq.c @@ -0,0 +1,314 @@ +/* + * Copyright (c) 1980, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * Initialize raw connection block q. + */ +void +raw_init() +{ + + rawcb.rcb_next = rawcb.rcb_prev = &rawcb; +} + + +/* + * Raw protocol input routine. Find the socket + * associated with the packet(s) and move them over. If + * nothing exists for this packet, drop it. + */ +/* + * Raw protocol interface. + */ +void +raw_input(m0, proto, src, dst) + struct mbuf *m0; + register struct sockproto *proto; + struct sockaddr *src, *dst; +{ + register struct rawcb *rp; + register struct mbuf *m = m0; + register int sockets = 0; + struct socket *last; + + last = 0; + for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) { + if (rp->rcb_proto.sp_family != proto->sp_family) + continue; + if (rp->rcb_proto.sp_protocol && + rp->rcb_proto.sp_protocol != proto->sp_protocol) + continue; + /* + * We assume the lower level routines have + * placed the address in a canonical format + * suitable for a structure comparison. + * + * Note that if the lengths are not the same + * the comparison will fail at the first byte. + */ +#define equal(a1, a2) \ + (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0) + if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst)) + continue; + if (rp->rcb_faddr && !equal(rp->rcb_faddr, src)) + continue; + if (last) { + struct mbuf *n; + n = m_copy(m, 0, (int)M_COPYALL); + if (n) { + if (sbappendaddr(&last->so_rcv, src, + n, (struct mbuf *)0) == 0) + /* should notify about lost packet */ + m_freem(n); + else { + sorwakeup(last); + sockets++; + } + } + } + last = rp->rcb_socket; + } + if (last) { + if (sbappendaddr(&last->so_rcv, src, + m, (struct mbuf *)0) == 0) + m_freem(m); + else { + sorwakeup(last); + sockets++; + } + } else + m_freem(m); +} + +/*ARGSUSED*/ +void +raw_ctlinput(cmd, arg) + int cmd; + struct sockaddr *arg; +{ + + if (cmd < 0 || cmd > PRC_NCMDS) + return; + /* INCOMPLETE */ +} + +/*ARGSUSED*/ +int +raw_usrreq(so, req, m, nam, control) + struct socket *so; + int req; + struct mbuf *m, *nam, *control; +{ + register struct rawcb *rp = sotorawcb(so); + register int error = 0; + int len; + + if (req == PRU_CONTROL) + return (EOPNOTSUPP); + if (control && control->m_len) { + error = EOPNOTSUPP; + goto release; + } + if (rp == 0) { + error = EINVAL; + goto release; + } + switch (req) { + + /* + * Allocate a raw control block and fill in the + * necessary info to allow packets to be routed to + * the appropriate raw interface routine. + */ + case PRU_ATTACH: + if ((so->so_state & SS_PRIV) == 0) { + error = EACCES; + break; + } + error = raw_attach(so, (int)nam); + break; + + /* + * Destroy state just before socket deallocation. + * Flush data or not depending on the options. + */ + case PRU_DETACH: + if (rp == 0) { + error = ENOTCONN; + break; + } + raw_detach(rp); + break; + + /* + * If a socket isn't bound to a single address, + * the raw input routine will hand it anything + * within that protocol family (assuming there's + * nothing else around it should go to). + */ + case PRU_CONNECT: + error = EINVAL; +#if 0 + if (rp->rcb_faddr) { + error = EISCONN; + break; + } + nam = m_copym(nam, 0, M_COPYALL, M_WAIT); + rp->rcb_faddr = mtod(nam, struct sockaddr *); + soisconnected(so); +#endif + break; + + case PRU_BIND: + error = EINVAL; +#if 0 + if (rp->rcb_laddr) { + error = EINVAL; /* XXX */ + break; + } + error = raw_bind(so, nam); +#endif + break; + + case PRU_CONNECT2: + error = EOPNOTSUPP; + goto release; + + case PRU_DISCONNECT: + if (rp->rcb_faddr == 0) { + error = ENOTCONN; + break; + } + raw_disconnect(rp); + soisdisconnected(so); + break; + + /* + * Mark the connection as being incapable of further input. + */ + case PRU_SHUTDOWN: + socantsendmore(so); + break; + + /* + * Ship a packet out. The appropriate raw output + * routine handles any massaging necessary. + */ + case PRU_SEND: + if (nam) { + if (rp->rcb_faddr) { + error = EISCONN; + break; + } + rp->rcb_faddr = mtod(nam, struct sockaddr *); + } else if (rp->rcb_faddr == 0) { + error = ENOTCONN; + break; + } + error = (*so->so_proto->pr_output)(m, so); + m = NULL; + if (nam) + rp->rcb_faddr = 0; + break; + + case PRU_ABORT: + raw_disconnect(rp); + sofree(so); + soisdisconnected(so); + break; + + case PRU_SENSE: + /* + * stat: don't bother with a blocksize. + */ + return (0); + + /* + * Not supported. + */ + case PRU_RCVOOB: + case PRU_RCVD: + return(EOPNOTSUPP); + + case PRU_LISTEN: + case PRU_ACCEPT: + case PRU_SENDOOB: + error = EOPNOTSUPP; + break; + + case PRU_SOCKADDR: + if (rp->rcb_laddr == 0) { + error = EINVAL; + break; + } + len = rp->rcb_laddr->sa_len; + bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len); + nam->m_len = len; + break; + + case PRU_PEERADDR: + if (rp->rcb_faddr == 0) { + error = ENOTCONN; + break; + } + len = rp->rcb_faddr->sa_len; + bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len); + nam->m_len = len; + break; + + default: + panic("raw_usrreq"); + } +release: + if (m != NULL) + m_freem(m); + return (error); +} diff --git a/reactos/drivers/lib/oskittcp/oskittcp/route.c b/reactos/drivers/lib/oskittcp/oskittcp/route.c index a7b2f1edfaa..b8649667c12 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/route.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/route.c @@ -50,14 +50,33 @@ #include #include +#ifndef __REACTOS__ #include +#endif +#include #define SA(p) ((struct sockaddr *)(p)) int rttrash; /* routes not in table but not freed */ struct sockaddr wildcard; /* zero valued cookie for wildcard searches */ -#define UNIMP panic("Unimplemented function") +void +rtable_init(table) + void **table; +{ + struct domain *dom; + for (dom = domains; dom; dom = dom->dom_next) + if (dom->dom_rtattach) + dom->dom_rtattach(&table[dom->dom_family], + dom->dom_rtoffset); +} + +void +route_init() +{ + rn_init(); /* initialize all zeroes, all ones, mask table */ + rtable_init((void **)rt_tables); +} /* * Packet routing routines. @@ -66,12 +85,9 @@ void rtalloc(ro) register struct route *ro; { -#if 0 if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP)) return; /* XXX */ ro->ro_rt = rtalloc1(&ro->ro_dst, 1, 0UL); -#endif - UNIMP; } void @@ -79,12 +95,9 @@ rtalloc_ign(ro, ignore) register struct route *ro; u_long ignore; { -#if 0 if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP)) return; /* XXX */ ro->ro_rt = rtalloc1(&ro->ro_dst, 1, ignore); -#endif - UNIMP; } struct rtentry * @@ -93,7 +106,6 @@ rtalloc1(dst, report, ignflags) int report; u_long ignflags; { -#if 0 register struct radix_node_head *rnh = rt_tables[dst->sa_family]; register struct rtentry *rt; register struct radix_node *rn; @@ -130,15 +142,12 @@ rtalloc1(dst, report, ignflags) } splx(s); return (newrt); -#endif - UNIMP; } void rtfree(rt) register struct rtentry *rt; { -#if 0 register struct radix_node_head *rnh = rt_tables[rt_key(rt)->sa_family]; register struct ifaddr *ifa; @@ -165,23 +174,18 @@ rtfree(rt) Free(rt_key(rt)); Free(rt); } -#endif - UNIMP; } void ifafree(ifa) register struct ifaddr *ifa; { -#if 0 if (ifa == NULL) panic("ifafree"); if (ifa->ifa_refcnt == 0) free(ifa, M_IFADDR); else ifa->ifa_refcnt--; -#endif - UNIMP; } /* @@ -199,7 +203,6 @@ rtredirect(dst, gateway, netmask, flags, src, rtp) int flags; struct rtentry **rtp; { -#if 0 register struct rtentry *rt; int error = 0; short *stat = 0; @@ -222,8 +225,10 @@ rtredirect(dst, gateway, netmask, flags, src, rtp) if (!(flags & RTF_DONE) && rt && (!equal(src, rt->rt_gateway) || rt->rt_ifa != ifa)) error = EINVAL; - else if (ifa_ifwithaddr(gateway)) - error = EHOSTUNREACH; + else if (ifa_ifwithaddr(gateway)) { + OS_DbgPrint(OSK_MID_TRACE,("EHOSTUNREACH\n")); + error = EHOSTUNREACH; + } if (error) goto done; /* @@ -260,8 +265,10 @@ rtredirect(dst, gateway, netmask, flags, src, rtp) stat = &rtstat.rts_newgateway; rt_setgate(rt, rt_key(rt), gateway); } - } else - error = EHOSTUNREACH; + } else { + OS_DbgPrint(OSK_MID_TRACE,("EHOSTUNREACH\n")); + error = EHOSTUNREACH; + } done: if (rt) { if (rtp && !error) @@ -280,8 +287,6 @@ out: info.rti_info[RTAX_NETMASK] = netmask; info.rti_info[RTAX_AUTHOR] = src; rt_missmsg(RTM_REDIRECT, &info, flags, error); -#endif - UNIMP; } /* @@ -293,15 +298,12 @@ rtioctl(req, data, p) caddr_t data; struct proc *p; { -#if 0 #ifdef INET /* Multicast goop, grrr... */ return mrt_ioctl(req, data, p); #else /* INET */ return ENXIO; #endif /* INET */ -#endif - UNIMP; } struct ifaddr * @@ -309,8 +311,12 @@ ifa_ifwithroute(flags, dst, gateway) int flags; struct sockaddr *dst, *gateway; { -#if 0 register struct ifaddr *ifa; + + OS_DbgPrint(OSK_MID_TRACE,("Called: flags %\n", flags)); + OskitDumpBuffer( dst, sizeof(*dst) ); + OskitDumpBuffer( gateway, sizeof(*gateway) ); + if ((flags & RTF_GATEWAY) == 0) { /* * If we are adding a route to an interface, @@ -343,15 +349,18 @@ ifa_ifwithroute(flags, dst, gateway) if ((ifa = rt->rt_ifa) == 0) return (0); } +#ifndef __REACTOS__ if (ifa->ifa_addr->sa_family != dst->sa_family) { struct ifaddr *oifa = ifa; ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); if (ifa == 0) ifa = oifa; } - return (ifa); #endif - UNIMP; + + OS_DbgPrint(OSK_MID_TRACE,("Leaving: %x\n")); + + return (ifa); } #define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) @@ -370,7 +379,6 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) struct sockaddr *dst, *gateway, *netmask; struct rtentry **ret_nrt; { -#if 0 int s = splnet(); int error = 0; register struct rtentry *rt; register struct radix_node *rn; @@ -385,6 +393,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) if (flags & RTF_HOST) netmask = 0; switch (req) { +#ifndef __REACTOS__ case RTM_DELETE: if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == 0) senderr(ESRCH); @@ -423,6 +432,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) rtfree(rt); } break; +#endif case RTM_RESOLVE: if (ret_nrt == 0 || (rt = *ret_nrt) == 0) @@ -436,12 +446,14 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) flags |= RTF_HOST; goto makeroute; +#ifndef __REACTOS__ case RTM_ADD: if ((flags & RTF_GATEWAY) && !gateway) panic("rtrequest: GATEWAY but no gateway"); if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0) senderr(ENETUNREACH); +#endif makeroute: R_Malloc(rt, struct rtentry *, sizeof(*rt)); @@ -465,7 +477,9 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) */ ifa->ifa_refcnt++; rt->rt_ifa = ifa; +#ifndef __REACTOS__ rt->rt_ifp = ifa->ifa_ifp; +#endif rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask, rnh, rt->rt_nodes); @@ -512,8 +526,10 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) (*ret_nrt)->rt_refcnt++; } } +#ifndef __REACTOS__ if (ifa->ifa_rtrequest) ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0)); +#endif /* * We repeat the same procedure from rt_setgate() here because * it doesn't fire when we call it there because the node @@ -536,8 +552,6 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) bad: splx(s); return (error); -#endif - UNIMP; } /* @@ -550,7 +564,6 @@ bad: static int rt_fixdelete(struct radix_node *rn, void *vp) { -#if 0 struct rtentry *rt = (struct rtentry *)rn; struct rtentry *rt0 = vp; @@ -560,8 +573,6 @@ rt_fixdelete(struct radix_node *rn, void *vp) rt->rt_flags, (struct rtentry **)0); } return 0; -#endif - UNIMP; } /* @@ -593,7 +604,6 @@ rt_fixchange(struct radix_node *rn, void *vp) u_char *xk1, *xm1, *xk2; int i, len; -#if 0 #ifdef DEBUG if (rtfcdebug) printf("rt_fixchange: rt %p, rt0 %p\n", rt, rt0); @@ -644,8 +654,6 @@ rt_fixchange(struct radix_node *rn, void *vp) #endif return rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt), rt->rt_flags, (struct rtentry **)0); -#endif - UNIMP; } int @@ -653,7 +661,6 @@ rt_setgate(rt0, dst, gate) struct rtentry *rt0; struct sockaddr *dst, *gate; { -#if 0 caddr_t new, old; int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len); register struct rtentry *rt = rt0; @@ -711,15 +718,12 @@ rt_setgate(rt0, dst, gate) } return 0; -#endif - UNIMP; } void rt_maskedcopy(src, dst, netmask) struct sockaddr *src, *dst, *netmask; { -#if 0 register u_char *cp1 = (u_char *)src; register u_char *cp2 = (u_char *)dst; register u_char *cp3 = (u_char *)netmask; @@ -734,8 +738,6 @@ rt_maskedcopy(src, dst, netmask) *cp2++ = *cp1++ & *cp3++; if (cp2 < cplim2) bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2)); -#endif - UNIMP; } /* @@ -747,13 +749,13 @@ rtinit(ifa, cmd, flags) register struct ifaddr *ifa; int cmd, flags; { -#if 0 + int error = EADDRNOTAVAIL; +#ifndef __REACTOS__ register struct rtentry *rt; register struct sockaddr *dst; register struct sockaddr *deldst; struct mbuf *m = 0; struct rtentry *nrt = 0; - int error; dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr; if (cmd == RTM_DELETE) { @@ -801,7 +803,6 @@ rtinit(ifa, cmd, flags) } rt_newaddrmsg(cmd, ifa, error, nrt); } - return (error); #endif - UNIMP; + return (error); } diff --git a/reactos/drivers/lib/oskittcp/oskittcp/rtsock.c b/reactos/drivers/lib/oskittcp/oskittcp/rtsock.c index 51cc2efe84a..17a25ff5fc5 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/rtsock.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/rtsock.c @@ -47,6 +47,478 @@ #include #include +#include + +struct sockaddr route_dst = { 2, PF_ROUTE, }; +struct sockaddr route_src = { 2, PF_ROUTE, }; +struct sockproto route_proto = { PF_ROUTE, }; + +struct walkarg { + int w_op, w_arg, w_given, w_needed, w_tmemsize; + caddr_t w_where, w_tmem; +}; + +static struct mbuf * + rt_msg1 __P((int, struct rt_addrinfo *)); +static int rt_msg2 __P((int, + struct rt_addrinfo *, caddr_t, struct walkarg *)); +static void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *)); + +/* Sleazy use of local variables throughout file, warning!!!! */ +#define dst info.rti_info[RTAX_DST] +#define gate info.rti_info[RTAX_GATEWAY] +#define netmask info.rti_info[RTAX_NETMASK] +#define genmask info.rti_info[RTAX_GENMASK] +#define ifpaddr info.rti_info[RTAX_IFP] +#define ifaaddr info.rti_info[RTAX_IFA] +#define brdaddr info.rti_info[RTAX_BRD] + +/*ARGSUSED*/ +int +route_usrreq(so, req, m, nam, control) + register struct socket *so; + int req; + struct mbuf *m, *nam, *control; +{ + register int error = 0; + register struct rawcb *rp = sotorawcb(so); + int s; + + if (req == PRU_ATTACH) { + MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK); + so->so_pcb = (caddr_t)rp; + if (so->so_pcb) + bzero(so->so_pcb, sizeof(*rp)); + + } + if (req == PRU_DETACH && rp) { + int af = rp->rcb_proto.sp_protocol; + if (af == AF_INET) + route_cb.ip_count--; + else if (af == AF_NS) + route_cb.ns_count--; + else if (af == AF_ISO) + route_cb.iso_count--; + route_cb.any_count--; + } + s = splnet(); + error = raw_usrreq(so, req, m, nam, control); + rp = sotorawcb(so); + if (req == PRU_ATTACH && rp) { + int af = rp->rcb_proto.sp_protocol; + if (error) { + free((caddr_t)rp, M_PCB); + splx(s); + return (error); + } + if (af == AF_INET) + route_cb.ip_count++; + else if (af == AF_NS) + route_cb.ns_count++; + else if (af == AF_ISO) + route_cb.iso_count++; + rp->rcb_faddr = &route_src; + route_cb.any_count++; + soisconnected(so); + so->so_options |= SO_USELOOPBACK; + } + splx(s); + return (error); +} + +/*ARGSUSED*/ +int +route_output(m, so) + register struct mbuf *m; + struct socket *so; +{ + register struct rt_msghdr *rtm = 0; + register struct rtentry *rt = 0; + struct rtentry *saved_nrt = 0; + struct radix_node_head *rnh; + struct rt_addrinfo info; + int len, error = 0; + struct ifnet *ifp = 0; + struct ifaddr *ifa = 0; + +#define senderr(e) { error = e; goto flush;} + if (m == 0 || ((m->m_len < sizeof(long)) && + (m = m_pullup(m, sizeof(long))) == 0)) + return (ENOBUFS); + if ((m->m_flags & M_PKTHDR) == 0) + panic("route_output"); + len = m->m_pkthdr.len; + if (len < sizeof(*rtm) || + len != mtod(m, struct rt_msghdr *)->rtm_msglen) { + dst = 0; + senderr(EINVAL); + } + R_Malloc(rtm, struct rt_msghdr *, len); + if (rtm == 0) { + dst = 0; + senderr(ENOBUFS); + } + m_copydata(m, 0, len, (caddr_t)rtm); + if (rtm->rtm_version != RTM_VERSION) { + dst = 0; + senderr(EPROTONOSUPPORT); + } + rtm->rtm_pid = curproc->p_pid; + info.rti_addrs = rtm->rtm_addrs; + rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info); + if (dst == 0) + senderr(EINVAL); + if (genmask) { + struct radix_node *t; + t = rn_addmask((caddr_t)genmask, 0, 1); + if (t && Bcmp(genmask, t->rn_key, *(u_char *)genmask) == 0) + genmask = (struct sockaddr *)(t->rn_key); + else + senderr(ENOBUFS); + } + switch (rtm->rtm_type) { + + case RTM_ADD: + if (gate == 0) + senderr(EINVAL); + error = rtrequest(RTM_ADD, dst, gate, netmask, + rtm->rtm_flags, &saved_nrt); + if (error == 0 && saved_nrt) { + rt_setmetrics(rtm->rtm_inits, + &rtm->rtm_rmx, &saved_nrt->rt_rmx); + saved_nrt->rt_refcnt--; + saved_nrt->rt_genmask = genmask; + } + break; + + case RTM_DELETE: + error = rtrequest(RTM_DELETE, dst, gate, netmask, + rtm->rtm_flags, &saved_nrt); + if (error == 0) { + if ((rt = saved_nrt)) + rt->rt_refcnt++; + goto report; + } + break; + + case RTM_GET: + case RTM_CHANGE: + case RTM_LOCK: + if ((rnh = rt_tables[dst->sa_family]) == 0) { + senderr(EAFNOSUPPORT); + } else if (rt = (struct rtentry *) + rnh->rnh_lookup(dst, netmask, rnh)) + rt->rt_refcnt++; + else + senderr(ESRCH); + switch(rtm->rtm_type) { + + case RTM_GET: + report: + dst = rt_key(rt); + gate = rt->rt_gateway; + netmask = rt_mask(rt); + genmask = rt->rt_genmask; + if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { + ifp = rt->rt_ifp; + if (ifp) { + ifpaddr = ifp->if_addrlist->ifa_addr; + ifaaddr = rt->rt_ifa->ifa_addr; + rtm->rtm_index = ifp->if_index; + } else { + ifpaddr = 0; + ifaaddr = 0; + } + } + len = rt_msg2(rtm->rtm_type, &info, (caddr_t)0, + (struct walkarg *)0); + if (len > rtm->rtm_msglen) { + struct rt_msghdr *new_rtm; + R_Malloc(new_rtm, struct rt_msghdr *, len); + if (new_rtm == 0) + senderr(ENOBUFS); + Bcopy(rtm, new_rtm, rtm->rtm_msglen); + Free(rtm); rtm = new_rtm; + } + (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, + (struct walkarg *)0); + rtm->rtm_flags = rt->rt_flags; + rtm->rtm_rmx = rt->rt_rmx; + rtm->rtm_addrs = info.rti_addrs; + break; + + case RTM_CHANGE: + if (gate && rt_setgate(rt, rt_key(rt), gate)) + senderr(EDQUOT); + + /* + * If they tried to change things but didn't specify + * the required gateway, then just use the old one. + * This can happen if the user tries to change the + * flags on the default route without changing the + * default gateway. Changing flags still doesn't work. + */ + if ((rt->rt_flags & RTF_GATEWAY) && !gate) + gate = rt->rt_gateway; + +#ifndef __REACTOS__ + /* new gateway could require new ifaddr, ifp; + flags may also be different; ifp may be specified + by ll sockaddr when protocol address is ambiguous */ + if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr)) && + (ifp = ifa->ifa_ifp)) + ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate, + ifp); +#endif + + else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr))) || + (ifa = ifa_ifwithroute(rt->rt_flags, + rt_key(rt), gate))) +#ifndef __REACTOS__ + ifp = ifa->ifa_ifp; +#else + ; +#endif + if (ifa) { + register struct ifaddr *oifa = rt->rt_ifa; + if (oifa != ifa) { +#ifndef __REACTOS__ + if (oifa && oifa->ifa_rtrequest) + oifa->ifa_rtrequest(RTM_DELETE, + rt, gate); +#endif + IFAFREE(rt->rt_ifa); + rt->rt_ifa = ifa; + ifa->ifa_refcnt++; + rt->rt_ifp = ifp; + } + } + rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, + &rt->rt_rmx); +#ifndef __REACTOS__ + if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) + rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, gate); +#endif + if (genmask) + rt->rt_genmask = genmask; + /* + * Fall into + */ + case RTM_LOCK: + rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits); + rt->rt_rmx.rmx_locks |= + (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks); + break; + } + break; + + default: + senderr(EOPNOTSUPP); + } + +flush: + if (rtm) { + if (error) + rtm->rtm_errno = error; + else + rtm->rtm_flags |= RTF_DONE; + } + if (rt) + rtfree(rt); + { + register struct rawcb *rp = 0; + /* + * Check to see if we don't want our own messages. + */ + if ((so->so_options & SO_USELOOPBACK) == 0) { + if (route_cb.any_count <= 1) { + if (rtm) + Free(rtm); + m_freem(m); + return (error); + } + /* There is another listener, so construct message */ + rp = sotorawcb(so); + } + if (rtm) { + m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); + Free(rtm); + } + if (rp) + rp->rcb_proto.sp_family = 0; /* Avoid us */ + if (dst) + route_proto.sp_protocol = dst->sa_family; + raw_input(m, &route_proto, &route_src, &route_dst); + if (rp) + rp->rcb_proto.sp_family = PF_ROUTE; + } + return (error); +} + +void +rt_setmetrics(which, in, out) + u_long which; + register struct rt_metrics *in, *out; +{ +#define metric(f, e) if (which & (f)) out->e = in->e; + metric(RTV_RPIPE, rmx_recvpipe); + metric(RTV_SPIPE, rmx_sendpipe); + metric(RTV_SSTHRESH, rmx_ssthresh); + metric(RTV_RTT, rmx_rtt); + metric(RTV_RTTVAR, rmx_rttvar); + metric(RTV_HOPCOUNT, rmx_hopcount); + metric(RTV_MTU, rmx_mtu); + metric(RTV_EXPIRE, rmx_expire); +#undef metric +} + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) + +static void +rt_xaddrs(cp, cplim, rtinfo) + register caddr_t cp, cplim; + register struct rt_addrinfo *rtinfo; +{ + register struct sockaddr *sa; + register int i; + + bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); + for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { + if ((rtinfo->rti_addrs & (1 << i)) == 0) + continue; + rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; + ADVANCE(cp, sa); + } +} + +static struct mbuf * +rt_msg1(type, rtinfo) + int type; + register struct rt_addrinfo *rtinfo; +{ + register struct rt_msghdr *rtm; + register struct mbuf *m; + register int i; + register struct sockaddr *sa; + int len, dlen; + + m = m_gethdr(M_DONTWAIT, MT_DATA); + if (m == 0) + return (m); + switch (type) { + + case RTM_DELADDR: + case RTM_NEWADDR: + len = sizeof(struct ifa_msghdr); + break; + + case RTM_IFINFO: + len = sizeof(struct if_msghdr); + break; + + default: + len = sizeof(struct rt_msghdr); + } + if (len > MHLEN) + panic("rt_msg1"); + m->m_pkthdr.len = m->m_len = len; + m->m_pkthdr.rcvif = 0; + rtm = mtod(m, struct rt_msghdr *); + bzero((caddr_t)rtm, len); + for (i = 0; i < RTAX_MAX; i++) { + if ((sa = rtinfo->rti_info[i]) == NULL) + continue; + rtinfo->rti_addrs |= (1 << i); + dlen = ROUNDUP(sa->sa_len); + m_copyback(m, len, dlen, (caddr_t)sa); + len += dlen; + } + if (m->m_pkthdr.len != len) { + m_freem(m); + return (NULL); + } + rtm->rtm_msglen = len; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = type; + return (m); +} + +static int +rt_msg2(type, rtinfo, cp, w) + int type; + register struct rt_addrinfo *rtinfo; + caddr_t cp; + struct walkarg *w; +{ + register int i; + int len, dlen, second_time = 0; + caddr_t cp0; + + rtinfo->rti_addrs = 0; +again: + switch (type) { + + case RTM_DELADDR: + case RTM_NEWADDR: + len = sizeof(struct ifa_msghdr); + break; + + case RTM_IFINFO: + len = sizeof(struct if_msghdr); + break; + + default: + len = sizeof(struct rt_msghdr); + } + cp0 = cp; + if (cp0) + cp += len; + for (i = 0; i < RTAX_MAX; i++) { + register struct sockaddr *sa; + + if ((sa = rtinfo->rti_info[i]) == 0) + continue; + rtinfo->rti_addrs |= (1 << i); + dlen = ROUNDUP(sa->sa_len); + if (cp) { + bcopy((caddr_t)sa, cp, (unsigned)dlen); + cp += dlen; + } + len += dlen; + } + if (cp == 0 && w != NULL && !second_time) { + register struct walkarg *rw = w; + + rw->w_needed += len; + if (rw->w_needed <= 0 && rw->w_where) { + if (rw->w_tmemsize < len) { + if (rw->w_tmem) + free(rw->w_tmem, M_RTABLE); + rw->w_tmem = (caddr_t) + malloc(len, M_RTABLE, M_NOWAIT); + if (rw->w_tmem) + rw->w_tmemsize = len; + } + if (rw->w_tmem) { + cp = rw->w_tmem; + second_time = 1; + goto again; + } else + rw->w_where = 0; + } + } + if (cp) { + register struct rt_msghdr *rtm = (struct rt_msghdr *)cp0; + + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = type; + rtm->rtm_msglen = len; + } + return (len); +} + /* * This routine is called to generate a message from the routing * socket indicating that a redirect has occured, a routing lookup @@ -58,7 +530,6 @@ rt_missmsg(type, rtinfo, flags, error) int type, flags, error; register struct rt_addrinfo *rtinfo; { -#if 0 register struct rt_msghdr *rtm; register struct mbuf *m; struct sockaddr *sa = rtinfo->rti_info[RTAX_DST]; @@ -74,6 +545,275 @@ rt_missmsg(type, rtinfo, flags, error) rtm->rtm_addrs = rtinfo->rti_addrs; route_proto.sp_protocol = sa ? sa->sa_family : 0; raw_input(m, &route_proto, &route_src, &route_dst); -#endif - panic("Unimplemented function\n"); } + +/* + * This routine is called to generate a message from the routing + * socket indicating that the status of a network interface has changed. + */ +void +rt_ifmsg(ifp) + register struct ifnet *ifp; +{ + register struct if_msghdr *ifm; + struct mbuf *m; + struct rt_addrinfo info; + + if (route_cb.any_count == 0) + return; + bzero((caddr_t)&info, sizeof(info)); + m = rt_msg1(RTM_IFINFO, &info); + if (m == 0) + return; + ifm = mtod(m, struct if_msghdr *); + ifm->ifm_index = ifp->if_index; + ifm->ifm_flags = (u_short)ifp->if_flags; + ifm->ifm_data = ifp->if_data; + ifm->ifm_addrs = 0; + route_proto.sp_protocol = 0; + raw_input(m, &route_proto, &route_src, &route_dst); +} + +/* + * This is called to generate messages from the routing socket + * indicating a network interface has had addresses associated with it. + * if we ever reverse the logic and replace messages TO the routing + * socket indicate a request to configure interfaces, then it will + * be unnecessary as the routing socket will automatically generate + * copies of it. + */ +void +rt_newaddrmsg(cmd, ifa, error, rt) + int cmd, error; + register struct ifaddr *ifa; + register struct rtentry *rt; +{ + struct rt_addrinfo info; + struct sockaddr *sa = 0; + int pass; + struct mbuf *m = 0; +#ifndef __REACTOS__ + struct ifnet *ifp = ifa->ifa_ifp; +#endif + + if (route_cb.any_count == 0) + return; + for (pass = 1; pass < 3; pass++) { + bzero((caddr_t)&info, sizeof(info)); + if ((cmd == RTM_ADD && pass == 1) || + (cmd == RTM_DELETE && pass == 2)) { + register struct ifa_msghdr *ifam; + int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR; + + ifaaddr = sa = ifa->ifa_addr; +#ifndef __REACTOS__ + ifpaddr = ifp->if_addrlist->ifa_addr; +#endif + netmask = ifa->ifa_netmask; + brdaddr = ifa->ifa_dstaddr; + if ((m = rt_msg1(ncmd, &info)) == NULL) + continue; + ifam = mtod(m, struct ifa_msghdr *); +#ifndef __REACTOS__ + ifam->ifam_index = ifp->if_index; +#endif + ifam->ifam_metric = ifa->ifa_metric; + ifam->ifam_flags = ifa->ifa_flags; + ifam->ifam_addrs = info.rti_addrs; + } + if ((cmd == RTM_ADD && pass == 2) || + (cmd == RTM_DELETE && pass == 1)) { + register struct rt_msghdr *rtm; + + if (rt == 0) + continue; + netmask = rt_mask(rt); + dst = sa = rt_key(rt); + gate = rt->rt_gateway; + if ((m = rt_msg1(cmd, &info)) == NULL) + continue; + rtm = mtod(m, struct rt_msghdr *); +#ifndef __REACTOS__ + rtm->rtm_index = ifp->if_index; +#endif + rtm->rtm_flags |= rt->rt_flags; + rtm->rtm_errno = error; + rtm->rtm_addrs = info.rti_addrs; + } + route_proto.sp_protocol = sa ? sa->sa_family : 0; + raw_input(m, &route_proto, &route_src, &route_dst); + } +} + +/* + * This is used in dumping the kernel table via sysctl(). + */ +int +sysctl_dumpentry(rn, w) + struct radix_node *rn; + register struct walkarg *w; +{ + register struct rtentry *rt = (struct rtentry *)rn; + int error = 0, size; + struct rt_addrinfo info; + + if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) + return 0; + bzero((caddr_t)&info, sizeof(info)); + dst = rt_key(rt); + gate = rt->rt_gateway; + netmask = rt_mask(rt); + genmask = rt->rt_genmask; + size = rt_msg2(RTM_GET, &info, 0, w); + if (w->w_where && w->w_tmem) { + register struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; + + rtm->rtm_flags = rt->rt_flags; + rtm->rtm_use = rt->rt_use; + rtm->rtm_rmx = rt->rt_rmx; + rtm->rtm_index = rt->rt_ifp->if_index; + rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; + rtm->rtm_addrs = info.rti_addrs; + error = copyout((caddr_t)rtm, w->w_where, size); + if (error) + w->w_where = NULL; + else + w->w_where += size; + } + return (error); +} + +int +sysctl_iflist(af, w) + int af; + register struct walkarg *w; +{ + register struct ifnet *ifp; + register struct ifaddr *ifa; + struct rt_addrinfo info; + int len, error = 0; + + bzero((caddr_t)&info, sizeof(info)); + for (ifp = ifnet; ifp; ifp = ifp->if_next) { + if (w->w_arg && w->w_arg != ifp->if_index) + continue; + ifa = ifp->if_addrlist; + ifpaddr = ifa->ifa_addr; + len = rt_msg2(RTM_IFINFO, &info, (caddr_t)0, w); + ifpaddr = 0; + if (w->w_where && w->w_tmem) { + register struct if_msghdr *ifm; + + ifm = (struct if_msghdr *)w->w_tmem; + ifm->ifm_index = ifp->if_index; + ifm->ifm_flags = (u_short)ifp->if_flags; + ifm->ifm_data = ifp->if_data; + ifm->ifm_addrs = info.rti_addrs; + error = copyout((caddr_t)ifm, w->w_where, len); + if (error) + return (error); + w->w_where += len; + } +#ifndef __REACTOS__ + while ((ifa = ifa->ifa_next) != 0) { + if (af && af != ifa->ifa_addr->sa_family) + continue; + ifaaddr = ifa->ifa_addr; + netmask = ifa->ifa_netmask; + brdaddr = ifa->ifa_dstaddr; + len = rt_msg2(RTM_NEWADDR, &info, 0, w); + if (w->w_where && w->w_tmem) { + register struct ifa_msghdr *ifam; + + ifam = (struct ifa_msghdr *)w->w_tmem; + ifam->ifam_index = ifa->ifa_ifp->if_index; + ifam->ifam_flags = ifa->ifa_flags; + ifam->ifam_metric = ifa->ifa_metric; + ifam->ifam_addrs = info.rti_addrs; + error = copyout(w->w_tmem, w->w_where, len); + if (error) + return (error); + w->w_where += len; + } + } +#endif + ifaaddr = netmask = brdaddr = 0; + } + return (0); +} + +int +sysctl_rtable(name, namelen, where, given, new, newlen) + int *name; + int namelen; + caddr_t where; + size_t *given; + caddr_t *new; + size_t newlen; +{ + register struct radix_node_head *rnh; + int i, s, error = EINVAL; + u_char af; + struct walkarg w; + + if (new) + return (EPERM); + if (namelen != 3) + return (EINVAL); + af = name[0]; + Bzero(&w, sizeof(w)); + w.w_where = where; + w.w_given = *given; + w.w_needed = 0 - w.w_given; + w.w_op = name[1]; + w.w_arg = name[2]; + + s = splnet(); + switch (w.w_op) { + + case NET_RT_DUMP: + case NET_RT_FLAGS: + for (i = 1; i <= AF_MAX; i++) + if ((rnh = rt_tables[i]) && (af == 0 || af == i) && + (error = rnh->rnh_walktree(rnh, + sysctl_dumpentry, &w))) + break; + break; + + case NET_RT_IFLIST: + error = sysctl_iflist(af, &w); + } + splx(s); + if (w.w_tmem) + free(w.w_tmem, M_RTABLE); + w.w_needed += w.w_given; + if (where) { + *given = w.w_where - where; + if (*given < w.w_needed) + return (ENOMEM); + } else { + *given = (11 * w.w_needed) / 10; + } + return (error); +} + +/* + * Definitions of protocols supported in the ROUTE domain. + */ + +extern struct domain routedomain; /* or at least forward */ + +struct protosw routesw[] = { +{ SOCK_RAW, &routedomain, 0, PR_ATOMIC|PR_ADDR, + raw_input, route_output, raw_ctlinput, 0, + route_usrreq, + raw_init, 0, 0, 0, + sysctl_rtable, +} +}; + +struct domain routedomain = + { PF_ROUTE, "route", route_init, 0, 0, + routesw, &routesw[sizeof(routesw)/sizeof(routesw[0])] }; + +DOMAIN_SET(route); diff --git a/reactos/drivers/lib/oskittcp/oskittcp/sleep.c b/reactos/drivers/lib/oskittcp/oskittcp/sleep.c index 615b8e79bb3..b9aa1b4cbd1 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/sleep.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/sleep.c @@ -59,7 +59,7 @@ int tsleep( void *token, int priority, char *wmesg, int tmio ) { return 0; } -void wakeup( struct socket *so, struct selinfo *si, void *token ) { +void wakeup( struct socket *so, void *token ) { KIRQL OldIrql; KEVENT Event; PLIST_ENTRY Entry; @@ -73,13 +73,13 @@ void wakeup( struct socket *so, struct selinfo *si, void *token ) { OS_DbgPrint(OSK_MID_TRACE,("Socket connected!\n")); flags |= SEL_CONNECT; } - if( so->so_rcv.sb_cc && si ) { + if( so->so_rcv.sb_cc > 0 ) { OS_DbgPrint(OSK_MID_TRACE,("Socket readable\n")); flags |= SEL_READ; } - OS_DbgPrint(OSK_MID_TRACE,("Wakeup %x (socket %x, si_flags %x, state %x)!\n", - token, so, si ? si->si_flags : 0, + OS_DbgPrint(OSK_MID_TRACE,("Wakeup %x (socket %x, state %x)!\n", + token, so, so->so_state)); if( OtcpEvent.SocketState ) diff --git a/reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c b/reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c index 6e1825f6ec8..50b01cfa71b 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c @@ -74,30 +74,54 @@ struct inpcbinfo tcbinfo; #endif /* TUBA_INCLUDE */ +/* + * Insert segment ti into reassembly queue of tcp with + * control block tp. Return TH_FIN if reassembly now includes + * a segment with FIN. The macro form does the common case inline + * (segment is the next to be received on an established connection, + * and the queue is empty), avoiding linkage into and removal + * from the queue and repetition of various conversions. + * Set DELACK for segments received in order, but ack immediately + * when segments are out of order (so fast retransmit can work). + */ +#ifdef TCP_ACK_HACK #define TCP_REASS(tp, ti, m, so, flags) { \ if ((ti)->ti_seq == (tp)->rcv_nxt && \ (tp)->seg_next == (struct tcpiphdr *)(tp) && \ (tp)->t_state == TCPS_ESTABLISHED) { \ - tp->t_flags |= TF_DELACK; \ - if (!(ti)->ti_flags & TH_FIN && \ - !(ti)->ti_flags & TH_RST) { \ - (tp)->rcv_nxt += (ti)->ti_len - sizeof(struct ip); \ - OS_DbgPrint(OSK_MID_TRACE,("(REASS2) Added %d to rcv_nxt\n", \ - (ti)->ti_len - sizeof(struct ip))); \ - } else { \ - so->so_rcv.sb_sel.si_flags |= SEL_FIN; \ - } \ + if (ti->ti_flags & TH_PUSH) \ + tp->t_flags |= TF_ACKNOW; \ + else \ + tp->t_flags |= TF_DELACK; \ + (tp)->rcv_nxt += (ti)->ti_len; \ flags = (ti)->ti_flags & TH_FIN; \ - tcpstat.tcps_rcvpack++; \ - tcpstat.tcps_rcvbyte += (ti)->ti_len; \ - sbappend(so, &so->so_rcv, (m)); \ + tcpstat.tcps_rcvpack++;\ + tcpstat.tcps_rcvbyte += (ti)->ti_len;\ + sbappend(&(so)->so_rcv, (m)); \ sorwakeup(so); \ } else { \ (flags) = tcp_reass((tp), (ti), (m)); \ tp->t_flags |= TF_ACKNOW; \ } \ } - +#else +#define TCP_REASS(tp, ti, m, so, flags) { \ + if ((ti)->ti_seq == (tp)->rcv_nxt && \ + (tp)->seg_next == (struct tcpiphdr *)(tp) && \ + (tp)->t_state == TCPS_ESTABLISHED) { \ + tp->t_flags |= TF_DELACK; \ + (tp)->rcv_nxt += (ti)->ti_len; \ + flags = (ti)->ti_flags & TH_FIN; \ + tcpstat.tcps_rcvpack++;\ + tcpstat.tcps_rcvbyte += (ti)->ti_len;\ + sbappend(&(so)->so_rcv, (m)); \ + sorwakeup(so); \ + } else { \ + (flags) = tcp_reass((tp), (ti), (m)); \ + tp->t_flags |= TF_ACKNOW; \ + } \ +} +#endif #ifndef TUBA_INCLUDE int @@ -121,11 +145,10 @@ tcp_reass(tp, ti, m) * Find a segment which begins after this one does. */ for (q = tp->seg_next; q != (struct tcpiphdr *)tp; - q = (struct tcpiphdr *)q->ti_next) { - printf("Finding segment: %x\n", q); - if (SEQ_GT(q->ti_seq, ti->ti_seq)) - break; - } + q = (struct tcpiphdr *)q->ti_next) + if (SEQ_GT(q->ti_seq, ti->ti_seq)) + break; + /* * If there is a preceding segment, it may provide some of * our data already. If so, drop the data from the incoming @@ -195,39 +218,22 @@ present: if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) return (0); do { - tp->rcv_nxt += ti->ti_len - sizeof( struct ip ); + tp->rcv_nxt += ti->ti_len; OS_DbgPrint(OSK_MID_TRACE,("Added %d to rcv_nxt (result %d)\n", - ti->ti_len - sizeof(struct ip), tp->rcv_nxt)); + ti->ti_len, tp->rcv_nxt)); flags = ti->ti_flags & TH_FIN; remque(ti); m = REASS_MBUF(ti); ti = (struct tcpiphdr *)ti->ti_next; if (so->so_state & SS_CANTRCVMORE) - m_freem(m); - else { - sbappend(so, &so->so_rcv, (m)); - } + m_freem(m); + else + sbappend(&so->so_rcv, m); } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); sorwakeup(so); return (flags); } -void rip_input_mini(so, ti, m) - struct socket *so; - struct tcpiphdr *ti; - struct mbuf *m; -{ - register struct ip *ip = mtod(m, struct ip *); - register struct inpcb *inp; - struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET }; - - ripsrc.sin_addr = ti->ti_src; - - sbappendaddr(&so->so_rcv, - (struct sockaddr *)&ripsrc, m, - (struct mbuf *)0); -} - /* * TCP input routine, follows pages 65-76 of the * protocol specification dated September, 1981 very closely. @@ -239,8 +245,6 @@ tcp_input(m, iphlen) { register struct tcpiphdr *ti; register struct inpcb *inp; - struct sockaddr_in addr = { 0 }; - struct mbuf mhdr = { 0 }, mpayload = { 0 }; caddr_t optp = NULL; int optlen = 0; int len, tlen, off; @@ -258,9 +262,8 @@ tcp_input(m, iphlen) #ifdef TCPDEBUG short ostate = 0; #endif - bzero((char *)&to, sizeof(to)); - + tcpstat.tcps_rcvtotal++; /* * Get IP and TCP header together in first mbuf. @@ -268,32 +271,30 @@ tcp_input(m, iphlen) */ ti = mtod(m, struct tcpiphdr *); if (iphlen > sizeof (struct ip)) - ip_stripoptions(m, (struct mbuf *)0); + ip_stripoptions(m, (struct mbuf *)0); if (m->m_len < sizeof (struct tcpiphdr)) { - if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == 0) { - tcpstat.tcps_rcvshort++; - return; - } - ti = mtod(m, struct tcpiphdr *); + if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == 0) { + tcpstat.tcps_rcvshort++; + return; + } + ti = mtod(m, struct tcpiphdr *); } - + /* * Checksum extended TCP header and data. */ - tlen = ntohs(((struct ip *)ti)->ip_len); - len = sizeof (struct ip); - OS_DbgPrint(OSK_MID_TRACE,("tlen = %x, len = %x, m_len = %d\n", tlen, len, m->m_len)); - OS_DbgPrint(OSK_MID_TRACE,("ti->ti_len = %x\n", htons(ti->ti_len))); - ti->ti_sum = in_cksum(m, len); - OskitDumpBuffer(m->m_data, len); + tlen = ((struct ip *)ti)->ip_len; + len = sizeof (struct ip) + tlen; ti->ti_next = ti->ti_prev = 0; ti->ti_x1 = 0; + ti->ti_len = (u_short)tlen; + HTONS(ti->ti_len); + ti->ti_sum = in_cksum(m, len); if (ti->ti_sum) { - tcpstat.tcps_rcvbadsum++; - OS_DbgPrint(OSK_MID_TRACE,("Dropping packet due to bad csum (%x)\n", ti->ti_sum)); - goto drop; + printf("TCP: Bad Checksum\n"); + tcpstat.tcps_rcvbadsum++; + goto drop; } - ti->ti_len = htons((u_short)tlen); #endif /* TUBA_INCLUDE */ /* @@ -334,8 +335,6 @@ tcp_input(m, iphlen) m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); - OskitDumpBuffer(m->m_data, m->m_len); - /* * Locate pcb for segment. */ @@ -374,22 +373,6 @@ findpcb: tiwin = ti->ti_win; so = inp->inp_socket; - -#if 0 - mhdr.m_type = MT_HEADER; - memcpy(mhdr.m_pktdat, ti, sizeof(ti)); - mhdr.m_data = mhdr.m_pktdat; - mhdr.m_len = 0; - mhdr.m_flags = M_PKTHDR | M_EOR; - mhdr.m_next = &mpayload; - mpayload.m_type = MT_DATA; - mpayload.m_data = m->m_data + sizeof(*ti); - mpayload.m_len = m->m_len - sizeof(*ti); - mpayload.m_flags = M_EOR; - - rip_input_mini(so, ti, &mhdr); -#endif - if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) { #ifdef TCPDEBUG if (so->so_options & SO_DEBUG) { @@ -598,19 +581,14 @@ findpcb: * we have enough buffer space to take it. */ ++tcpstat.tcps_preddat; - tp->rcv_nxt += ti->ti_len - sizeof(struct ip); + tp->rcv_nxt += ti->ti_len; OS_DbgPrint(OSK_MID_TRACE,("Added %d to rcv_nxt\n", ti->ti_len - sizeof(struct ip))); tcpstat.tcps_rcvpack++; tcpstat.tcps_rcvbyte += ti->ti_len; /* * Add data to socket buffer. */ - OS_DbgPrint - (OSK_MID_TRACE,("Adding %d to socket buffer\n", - m->m_len)); - - sbappend(so, &so->so_rcv, (m)); - so->so_rcv.sb_cc += m->m_len; + sbappend(&so->so_rcv, m); sorwakeup(so); #ifdef TCP_ACK_HACK /* @@ -684,7 +662,7 @@ findpcb: am->m_len = sizeof (struct sockaddr_in); sin = mtod(am, struct sockaddr_in *); sin->sin_family = AF_INET; - /*sin->sin_len = sizeof(*sin); */ + sin->sin_len = sizeof(*sin); sin->sin_addr = ti->ti_src; sin->sin_port = ti->ti_sport; bzero((caddr_t)sin->sin_zero, sizeof(sin->sin_zero)); @@ -693,10 +671,10 @@ findpcb: inp->inp_laddr = ti->ti_dst; if (in_pcbconnect(inp, am)) { inp->inp_laddr = laddr; - /*(void) m_free(am);*/ + (void) m_free(am); goto drop; } - /*(void) m_free(am);*/ + (void) m_free(am); tp->t_template = tcp_template(tp); if (tp->t_template == 0) { tp = tcp_drop(tp, ENOBUFS); @@ -762,7 +740,7 @@ findpcb: */ tp->rcv_adv += min(tp->rcv_wnd, TCP_MAXWIN); tcpstat.tcps_connects++; - //soisconnected(so); + soisconnected(so); tp->t_timer[TCPT_KEEP] = tcp_keepinit; dropsocket = 0; /* committed to socket */ tcpstat.tcps_accepts++; @@ -855,7 +833,7 @@ findpcb: goto dropwithreset; } tcpstat.tcps_connects++; - //soisconnected(so); + soisconnected(so); /* Do window scaling on this connection? */ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == (TF_RCVD_SCALE|TF_REQ_SCALE)) { @@ -887,14 +865,8 @@ findpcb: tp->t_flags &= ~TF_NEEDFIN; tiflags &= ~TH_SYN; } else { - OS_DbgPrint - (OSK_MID_TRACE, - ("Socket %x entered ESTABLISHED state\n", - so)); - tp->t_state = TCPS_ESTABLISHED; - soisconnected(so); - tp->t_timer[TCPT_KEEP] = tcp_keepidle; - socwakeup(so); + tp->t_state = TCPS_ESTABLISHED; + tp->t_timer[TCPT_KEEP] = tcp_keepidle; } } else { /* @@ -1189,9 +1161,8 @@ trimthenstep6: * error and we send an RST and drop the connection. */ if (tiflags & TH_SYN) { - OS_DbgPrint(OSK_MID_TRACE,("SYN In window\n")); - tp = tcp_drop(tp, ECONNRESET); - goto dropwithreset; + tp = tcp_drop(tp, ECONNRESET); + goto dropwithreset; } /* @@ -1223,7 +1194,7 @@ trimthenstep6: goto dropwithreset; tcpstat.tcps_connects++; - //soisconnected(so); + soisconnected(so); /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == (TF_RCVD_SCALE|TF_REQ_SCALE)) { @@ -1432,7 +1403,7 @@ process_ACK: ourfinisacked = 0; } if (so->so_snd.sb_flags & SB_NOTIFY) - sowwakeup(so); + sowwakeup(so); tp->snd_una = ti->ti_ack; if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; @@ -1539,9 +1510,6 @@ step6: * actually wanting to send this much urgent data. */ if (ti->ti_urp + so->so_rcv.sb_cc > sb_max) { - OS_DbgPrint(OSK_MID_TRACE, - ("%x: Urgent pointer out of range: %x\n", - ti->ti_urp)); ti->ti_urp = 0; /* XXX */ tiflags &= ~TH_URG; /* XXX */ goto dodata; /* XXX */ @@ -1599,12 +1567,9 @@ dodata: /* XXX */ * case PRU_RCVD). If a FIN has already been received on this * connection then we just ignore the text. */ - - OS_DbgPrint(OSK_MID_TRACE,("TIFlags: %x\n", tiflags)); - if ((ti->ti_len || (tiflags&TH_FIN)) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { - TCP_REASS(tp, ti, m, so, tiflags); + TCP_REASS(tp, ti, m, so, tiflags); /* * Note the amount of data that peer has sent into * our window, in order to estimate the sender's @@ -1612,8 +1577,8 @@ dodata: /* XXX */ */ len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt); } else { - /*m_freem(m);*/ - tiflags &= ~TH_FIN; + m_freem(m); + tiflags &= ~TH_FIN; } /* @@ -1692,10 +1657,6 @@ dodata: /* XXX */ /* * Return any desired output. */ - OS_DbgPrint(OSK_MID_TRACE, - ("needoutput: %d, tp->t_flags & TF_ACKNOW: %d\n", - needoutput, tp->t_flags & TF_ACKNOW)); - if (needoutput || (tp->t_flags & TF_ACKNOW)) (void) tcp_output(tp); return; @@ -1750,6 +1711,7 @@ drop: if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0); #endif + m_freem(m); /* destroy temporarily created socket */ if (dropsocket) (void) soabort(so); @@ -2023,6 +1985,9 @@ tcp_mss(tp, offer) tp->t_maxopd = tp->t_maxseg = tcp_mssdflt; return; } +#ifndef __REACTOS__ + ifp = rt->rt_ifp; +#endif so = inp->inp_socket; taop = rmx_taop(rt->rt_rmx); @@ -2082,7 +2047,7 @@ tcp_mss(tp, offer) mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcpiphdr); else { - mss = rt->rt_mtu - sizeof(struct tcpiphdr); + mss = ifp->if_mtu - sizeof(struct tcpiphdr); if (!in_localaddr(inp->inp_faddr)) mss = min(mss, tcp_mssdflt); } @@ -2177,7 +2142,10 @@ tcp_mssopt(tp) rt = tcp_rtlookup(tp->t_inpcb); if (rt == NULL) return tcp_mssdflt; - - return rt->rt_mtu - sizeof(struct tcpiphdr); +#ifndef __REACTOS__ + return rt->rt_ifp->if_mtu - sizeof(struct tcpiphdr); +#else + return tcp_mssdflt; +#endif } #endif /* TUBA_INCLUDE */ diff --git a/reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c b/reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c index 6263033ed0a..e4df92c8d38 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c @@ -33,7 +33,7 @@ * @(#)tcp_output.c 8.3 (Berkeley) 12/30/93 */ -#define TCPOUTFLAGS +#define TCPOUTFLAGS #include #include #include @@ -76,7 +76,7 @@ tcp_output(tp) { register struct socket *so = tp->t_inpcb->inp_socket; register long len, win; - int off, flags, error = EINVAL; + int off, flags, error; register struct mbuf *m; register struct tcpiphdr *ti; u_char opt[TCP_MAXOLEN]; @@ -85,7 +85,7 @@ tcp_output(tp) struct rmxp_tao *taop; struct rmxp_tao tao_noncached; - OS_DbgPrint(OSK_MID_TRACE,("Start\n")); + OS_DbgPrint(OSK_MID_TRACE,("Called\n")); /* * Determine length of data that should be transmitted, @@ -101,9 +101,8 @@ tcp_output(tp) * slow start to get ack "clock" running again. */ tp->snd_cwnd = tp->t_maxseg; - again: - OS_DbgPrint(OSK_MID_TRACE,("Again...\n")); + OS_DbgPrint(OSK_MID_TRACE,("again:\n")); sendalot = 0; off = tp->snd_nxt - tp->snd_una; win = min(tp->snd_wnd, tp->snd_cwnd); @@ -167,8 +166,10 @@ again: flags &= ~TH_SYN; off--, len++; if (len > 0 && tp->t_state == TCPS_SYN_SENT && - taop->tao_ccsent == 0) - return 0; + taop->tao_ccsent == 0) { + OS_DbgPrint(OSK_MID_TRACE,("leaving 0\n")); + return 0; + } } /* @@ -310,9 +311,11 @@ again: /* * No reason to send a segment, just return. */ - /*return (0);*/ + OS_DbgPrint(OSK_MID_TRACE,("leaving 0\n")); + return (0); send: + OS_DbgPrint(OSK_MID_TRACE,("send:\n")); /* * Before ESTABLISHED, force sending of initial options * unless TCP set not to do any options. @@ -460,81 +463,85 @@ send: panic("tcphdr too big"); /*#endif*/ - /* * Grab a header mbuf, attaching a copy of data to * be transmitted, and initialize the header from * the template for sends on this connection. */ if (len) { - if (tp->t_force && len == 1) - tcpstat.tcps_sndprobe++; - else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { - tcpstat.tcps_sndrexmitpack++; - tcpstat.tcps_sndrexmitbyte += len; - } else { - tcpstat.tcps_sndpack++; - tcpstat.tcps_sndbyte += len; - } -#ifdef notyet - if ((m = m_copypack(so->so_snd.sb_mb, off, - (int)len, max_linkhdr + hdrlen)) == 0) { - error = ENOBUFS; - goto out; - } - /* - * m_copypack left space for our hdr; use it. - */ - m->m_len += hdrlen; - m->m_data -= hdrlen; -#else - MGETHDR(m, M_DONTWAIT, MT_HEADER); - if (m == NULL) { - error = ENOBUFS; - goto out; - } - m->m_data += max_linkhdr; - m->m_len = hdrlen; - if (len <= MHLEN - hdrlen - max_linkhdr) { - m_copydata(so->so_snd.sb_mb, off, (int) len, - mtod(m, caddr_t) + hdrlen); - m->m_len += len; - } else { - m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len); - if (m->m_next == 0) { - (void) m_free(m); - error = ENOBUFS; - goto out; + if (tp->t_force && len == 1) + tcpstat.tcps_sndprobe++; + else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { + tcpstat.tcps_sndrexmitpack++; + tcpstat.tcps_sndrexmitbyte += len; + } else { + tcpstat.tcps_sndpack++; + tcpstat.tcps_sndbyte += len; + } +#ifdef notyet + if ((m = m_copypack(so->so_snd.sb_mb, off, + (int)len, max_linkhdr + hdrlen)) == 0) { + error = ENOBUFS; + goto out; + } + /* + * m_copypack left space for our hdr; use it. + */ + m->m_len += hdrlen; + m->m_data -= hdrlen; +#else + MGETHDR(m, M_DONTWAIT, MT_HEADER); + if (m == NULL) { + error = ENOBUFS; + goto out; + } + m->m_data += max_linkhdr; + m->m_len = hdrlen; + if (len <= MHLEN - hdrlen - max_linkhdr) { + OS_DbgPrint(OSK_MID_TRACE,("Preparing %d bytes to send\n", + len)); + OskitDumpBuffer(mtod(m, caddr_t), len); + m_copydata(so->so_snd.sb_mb, off, (int) len, + mtod(m, caddr_t) + hdrlen); + m->m_len += len; + } else { + m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len); + OS_DbgPrint(OSK_MID_TRACE,("Preparing %d bytes to send\n", + len)); + OskitDumpBuffer(mtod(m, caddr_t), len); + if (m->m_next == 0) { + (void) m_free(m); + error = ENOBUFS; + goto out; + } } - } #endif - /* - * If we're sending everything we've got, set PUSH. - * (This will keep happy those implementations which only - * give data to the user when a buffer fills or - * a PUSH comes in.) - */ - if (off + len == so->so_snd.sb_cc) - flags |= TH_PUSH; + /* + * If we're sending everything we've got, set PUSH. + * (This will keep happy those implementations which only + * give data to the user when a buffer fills or + * a PUSH comes in.) + */ + if (off + len == so->so_snd.sb_cc) + flags |= TH_PUSH; } else { - if (tp->t_flags & TF_ACKNOW) - tcpstat.tcps_sndacks++; - else if (flags & (TH_SYN|TH_FIN|TH_RST)) - tcpstat.tcps_sndctrl++; - else if (SEQ_GT(tp->snd_up, tp->snd_una)) - tcpstat.tcps_sndurg++; - else - tcpstat.tcps_sndwinup++; - - MGETHDR(m, M_DONTWAIT, MT_HEADER); - if (m == NULL) { - error = ENOBUFS; - goto out; - } - m->m_data += max_linkhdr; - m->m_len = hdrlen; + if (tp->t_flags & TF_ACKNOW) + tcpstat.tcps_sndacks++; + else if (flags & (TH_SYN|TH_FIN|TH_RST)) + tcpstat.tcps_sndctrl++; + else if (SEQ_GT(tp->snd_up, tp->snd_una)) + tcpstat.tcps_sndurg++; + else + tcpstat.tcps_sndwinup++; + + MGETHDR(m, M_DONTWAIT, MT_HEADER); + if (m == NULL) { + error = ENOBUFS; + goto out; + } + m->m_data += max_linkhdr; + m->m_len = hdrlen; } - m->m_pkthdr.rcvif = (struct ifnet *)0; ti = mtod(m, struct tcpiphdr *); if (tp->t_template == 0) @@ -546,11 +553,9 @@ send: * window for use in delaying messages about window sizes. * If resending a FIN, be sure not to use a new sequence number. */ - if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && tp->snd_nxt == tp->snd_max) tp->snd_nxt--; - /* * If we are doing retransmissions, then snd_nxt will * not reflect the first unsent octet. For ACK only @@ -568,7 +573,6 @@ send: ti->ti_seq = htonl(tp->snd_nxt); else ti->ti_seq = htonl(tp->snd_max); - ti->ti_ack = htonl(tp->rcv_nxt); printf("ti->ti_ack = %d\n", ti->ti_ack); @@ -576,26 +580,21 @@ send: (void)memcpy(ti + 1, opt, optlen); ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2; } - ti->ti_flags = flags; - /* * Calculate receive window. Don't shrink window, * but avoid silly window syndrome. */ if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg) win = 0; - if (win > (long)TCP_MAXWIN << tp->rcv_scale) win = (long)TCP_MAXWIN << tp->rcv_scale; - if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) win = (long)(tp->rcv_adv - tp->rcv_nxt); - ti->ti_win = htons((u_short) (win>>tp->rcv_scale)); if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { - ti->ti_urp = htons((u_short)(tp->snd_up - tp->snd_nxt)); - ti->ti_flags |= TH_URG; + ti->ti_urp = htons((u_short)(tp->snd_up - tp->snd_nxt)); + ti->ti_flags |= TH_URG; } else /* * If no urgent pointer to send, then we pull @@ -609,15 +608,9 @@ send: * Put TCP length in extended header, and then * checksum extended header and data. */ - - if (len + optlen) { - ti->ti_src.s_addr = tp->t_inpcb->inp_laddr.s_addr; - ti->ti_dst.s_addr = tp->t_inpcb->inp_faddr.s_addr; - ti->ti_pr = 6; - ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + - optlen + len)); - } - + if (len + optlen) + ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + + optlen + len)); ti->ti_sum = in_cksum(m, (int)(hdrlen + len)); /* @@ -707,21 +700,20 @@ send: * 2) the MTU is not locked (if it is, then discovery has been * disabled) */ - if ((rt = &tp->t_inpcb->inp_route.ro_rt) + if ((rt = tp->t_inpcb->inp_route.ro_rt) && rt->rt_flags & RTF_UP && !(rt->rt_rmx.rmx_locks & RTV_MTU)) { ((struct ip *)ti)->ip_off |= IP_DF; } #endif - - OS_DbgPrint(OSK_MID_TRACE,("Calling ip_output\n")); - error = ip_output(so, m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, + error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, so->so_options & SO_DONTROUTE, 0); } if (error) { out: if (error == ENOBUFS) { tcp_quench(tp->t_inpcb, 0); + OS_DbgPrint(OSK_MID_TRACE,("quench 0\n")); return (0); } #if 1 @@ -733,14 +725,17 @@ out: * not do so here. */ tcp_mtudisc(tp->t_inpcb, 0); + OS_DbgPrint(OSK_MID_TRACE,("mtudisc 0\n")); return 0; } #endif if ((error == EHOSTUNREACH || error == ENETDOWN) && TCPS_HAVERCVDSYN(tp->t_state)) { tp->t_softerror = error; + OS_DbgPrint(OSK_MID_TRACE,("softerror %d\n", error)); return (0); } + OS_DbgPrint(OSK_MID_TRACE,("error %d\n", error)); return (error); } tcpstat.tcps_sndtotal++; @@ -755,10 +750,9 @@ out: tp->rcv_adv = tp->rcv_nxt + win; tp->last_ack_sent = tp->rcv_nxt; tp->t_flags &= ~(TF_ACKNOW|TF_DELACK); - OS_DbgPrint(OSK_MID_TRACE,("sendalot: %d (flags %x)\n", - sendalot, tp->t_flags)); if (sendalot) goto again; + OS_DbgPrint(OSK_MID_TRACE,("leaving 0\n")); return (0); } diff --git a/reactos/drivers/lib/oskittcp/oskittcp/tcp_subr.c b/reactos/drivers/lib/oskittcp/oskittcp/tcp_subr.c index fc3eafdd639..4632b688ef1 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/tcp_subr.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/tcp_subr.c @@ -64,6 +64,7 @@ #ifdef TCPDEBUG #include #endif +#include /* patchable/settable parameters for tcp */ int tcp_mssdflt = TCP_MSS; @@ -114,8 +115,8 @@ tcp_template(tp) register struct tcpiphdr *n; if ((n = tp->t_template) == 0) { - m = m_get(M_DONTWAIT, MT_HEADER); - OS_DbgPrint(OSK_MID_TRACE,("Allocated template mbuf at %x\n", m)); + m = m_get(M_DONTWAIT, MT_HEADER); + OS_DbgPrint(OSK_MID_TRACE,("tp->t_template = %x\n", m)); if (m == NULL) return (0); m->m_len = sizeof (struct tcpiphdr); @@ -126,6 +127,7 @@ tcp_template(tp) n->ti_pr = IPPROTO_TCP; n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); n->ti_src = inp->inp_laddr; + OS_DbgPrint(OSK_MID_TRACE,("INP_LADDR = %x\n", n->ti_src)); n->ti_dst = inp->inp_faddr; n->ti_sport = inp->inp_lport; n->ti_dport = inp->inp_fport; @@ -218,7 +220,7 @@ tcp_respond(tp, ti, m, ack, seq, flags) if (tp == NULL || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) tcp_trace(TA_OUTPUT, 0, tp, ti, 0); #endif - (void) ip_output(0, m, NULL, ro, 0, NULL); + (void) ip_output(m, NULL, ro, 0, NULL); } /* @@ -314,7 +316,9 @@ tcp_close(tp) * Don't update the default route's characteristics and don't * update anything that the user "locked". */ - if (tp->t_rttupdated >= 16 && (rt = &inp->inp_route.ro_rt)) { + if (tp->t_rttupdated >= 16 && + (rt = inp->inp_route.ro_rt) && + ((struct sockaddr_in *)rt_key(rt))->sin_addr.s_addr != INADDR_ANY) { register u_long i = 0; if ((rt->rt_rmx.rmx_locks & RTV_RTT) == 0) { @@ -378,12 +382,8 @@ tcp_close(tp) remque(t->ti_prev); m_freem(m); } - if (tp->t_template) { - (void) m_free(dtom(tp->t_template)); - OS_DbgPrint(OSK_MID_TRACE,("Freeing template mbuf at %x\n", - tp->t_template)); - tp->t_template = 0; - } + if (tp->t_template) + (void) m_free(dtom(tp->t_template)); free(tp, M_PCB); inp->inp_ppcb = 0; soisdisconnected(so); @@ -427,7 +427,7 @@ tcp_notify(inp, error) so->so_error = error; else tp->t_softerror = error; - wakeup(so, NULL, (caddr_t) &so->so_timeo); + wakeup( so, (caddr_t) &so->so_timeo); sorwakeup(so); sowwakeup(so); } @@ -564,15 +564,16 @@ tcp_rtlookup(inp) struct rtentry *rt; ro = &inp->inp_route; - rt = &ro->ro_rt; - if (!(rt->rt_flags & RTF_UP)) { + rt = ro->ro_rt; + if (rt == NULL || !(rt->rt_flags & RTF_UP)) { /* No route yet, so try to acquire one */ if (inp->inp_faddr.s_addr != INADDR_ANY) { ro->ro_dst.sa_family = AF_INET; - /* ro->ro_dst.sa_len = sizeof(ro->ro_dst); */ + ro->ro_dst.sa_len = sizeof(ro->ro_dst); ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = inp->inp_faddr; - rt = &ro->ro_rt; + rtalloc(ro); + rt = ro->ro_rt; } } return rt; diff --git a/reactos/drivers/lib/oskittcp/oskittcp/tcp_usrreq.c b/reactos/drivers/lib/oskittcp/oskittcp/tcp_usrreq.c index c780f43452d..f315e3d1030 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/tcp_usrreq.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/tcp_usrreq.c @@ -82,58 +82,81 @@ tcp_usrreq(so, req, m, nam, control) int req; struct mbuf *m, *nam, *control; { - register struct inpcb *inp; - register struct tcpcb *tp = 0; - struct sockaddr_in *sinp; - int s; - int error = 0; + register struct inpcb *inp; + register struct tcpcb *tp = 0; + struct sockaddr_in *sinp; + int s; + int error = 0; +#ifdef TCPDEBUG + int ostate; +#endif - if (req == PRU_CONTROL) - return (in_control(so, (u_long)m, (caddr_t)nam, - (struct ifnet *)control)); - if (control && control->m_len) { - m_freem(control); - if (m) - m_freem(m); - return (EINVAL); - } - - s = splnet(); - inp = sotoinpcb(so); + if (req == PRU_CONTROL) + return (in_control(so, (u_long)m, (caddr_t)nam, + (struct ifnet *)control)); + if (control && control->m_len) { + m_freem(control); + if (m) + m_freem(m); + return (EINVAL); + } - /* - * When a TCP is attached to a socket, then there will be - * a (struct inpcb) pointed at by the socket, and this - * structure will point at a subsidary (struct tcpcb). - */ - if (inp == 0 && req != PRU_ATTACH) { - splx(s); - /* safer version of fix for mbuf leak */ - if (m && (req == PRU_SEND || req == PRU_SENDOOB)) - m_freem(m); - } + s = splnet(); + inp = sotoinpcb(so); + /* + * When a TCP is attached to a socket, then there will be + * a (struct inpcb) pointed at by the socket, and this + * structure will point at a subsidary (struct tcpcb). + */ + if (inp == 0 && req != PRU_ATTACH) { + splx(s); +#if 0 + /* + * The following corrects an mbuf leak under rare + * circumstances, but has not been fully tested. + */ + if (m && req != PRU_SENSE) + m_freem(m); +#else + /* safer version of fix for mbuf leak */ + if (m && (req == PRU_SEND || req == PRU_SENDOOB)) + m_freem(m); +#endif + return (EINVAL); /* XXX */ + } + if (inp) { + tp = intotcpcb(inp); + /* WHAT IF TP IS 0? */ +#ifdef KPROF + tcp_acounts[tp->t_state][req]++; +#endif +#ifdef TCPDEBUG + ostate = tp->t_state; + } else + ostate = 0; +#else /* TCPDEBUG */ + } +#endif /* TCPDEBUG */ + + switch (req) { - if( inp ) - tp = intotcpcb(inp); - - switch (req) { /* * TCP attaches to socket via PRU_ATTACH, reserving space, * and an internet control block. */ - case PRU_ATTACH: - if (inp) { - error = EISCONN; - break; - } - error = tcp_attach(so); - if (error) - break; - if ((so->so_options & SO_LINGER) && so->so_linger == 0) - so->so_linger = TCP_LINGERTIME * hz; - tp = sototcpcb(so); - break; - + case PRU_ATTACH: + if (inp) { + error = EISCONN; + break; + } + error = tcp_attach(so); + if (error) + break; + if ((so->so_options & SO_LINGER) && so->so_linger == 0) + so->so_linger = TCP_LINGERTIME * hz; + tp = sototcpcb(so); + break; + /* * PRU_DETACH detaches the TCP protocol from the socket. * If the protocol state is non-embryonic, then can't @@ -141,37 +164,42 @@ tcp_usrreq(so, req, m, nam, control) * which may finish later; embryonic TCB's can just * be discarded here. */ - case PRU_DETACH: - if (tp->t_state > TCPS_LISTEN) - tp = tcp_disconnect(tp); - else - tp = tcp_close(tp); - break; - + case PRU_DETACH: + if (tp->t_state > TCPS_LISTEN) + tp = tcp_disconnect(tp); + else + tp = tcp_close(tp); + break; + /* * Give the socket an address. */ - case PRU_BIND: - /* - * Must check for multicast addresses and disallow binding - * to them. - */ - sinp = mtod(nam, struct sockaddr_in *); - error = in_pcbbind(inp, nam); - if (error) - break; - break; - + case PRU_BIND: + /* + * Must check for multicast addresses and disallow binding + * to them. + */ + sinp = mtod(nam, struct sockaddr_in *); + if (sinp->sin_family == AF_INET && + IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) { + error = EAFNOSUPPORT; + break; + } + error = in_pcbbind(inp, nam); + if (error) + break; + break; + /* * Prepare to accept connections. */ - case PRU_LISTEN: - if (inp->inp_lport == 0) - error = in_pcbbind(inp, NULL); - if (error == 0) - tp->t_state = TCPS_LISTEN; - break; - + case PRU_LISTEN: + if (inp->inp_lport == 0) + error = in_pcbbind(inp, NULL); + if (error == 0) + tp->t_state = TCPS_LISTEN; + break; + /* * Initiate connection to peer. * Create a template for use in transmissions on this connection. @@ -179,26 +207,29 @@ tcp_usrreq(so, req, m, nam, control) * Start keep-alive timer, and seed output sequence space. * Send initial segment on connection. */ - case PRU_CONNECT: - /* - * Must disallow TCP ``connections'' to multicast addresses. - */ - sinp = mtod(nam, struct sockaddr_in *); - if ((error = tcp_connect(tp, nam)) != 0) { - OS_DbgPrint(OSK_MID_TRACE,("TC: %d\n", error)); - break; - } - error = tcp_output(tp); - OS_DbgPrint(OSK_MID_TRACE,("TO: %d\n", error)); - break; - + case PRU_CONNECT: + /* + * Must disallow TCP ``connections'' to multicast addresses. + */ + sinp = mtod(nam, struct sockaddr_in *); + if (sinp->sin_family == AF_INET + && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) { + error = EAFNOSUPPORT; + break; + } + + if ((error = tcp_connect(tp, nam)) != 0) + break; + error = tcp_output(tp); + break; + /* * Create a TCP connection between two sockets. */ - case PRU_CONNECT2: - error = EOPNOTSUPP; - break; - + case PRU_CONNECT2: + error = EOPNOTSUPP; + break; + /* * Initiate disconnect from peer. * If connection never passed embryonic stage, just drop; @@ -210,161 +241,163 @@ tcp_usrreq(so, req, m, nam, control) * * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB. */ - case PRU_DISCONNECT: - tp = tcp_disconnect(tp); - break; - + case PRU_DISCONNECT: + tp = tcp_disconnect(tp); + break; + /* * Accept a connection. Essentially all the work is * done at higher levels; just return the address * of the peer, storing through addr. */ - case PRU_ACCEPT: - in_setpeeraddr(inp, nam); - break; - + case PRU_ACCEPT: + in_setpeeraddr(inp, nam); + break; + /* * Mark the connection as being incapable of further output. */ - case PRU_SHUTDOWN: - socantsendmore(so); - tp = tcp_usrclosed(tp); - if (tp) - error = tcp_output(tp); - break; - + case PRU_SHUTDOWN: + socantsendmore(so); + tp = tcp_usrclosed(tp); + if (tp) + error = tcp_output(tp); + break; + /* * After a receive, possibly send window update to peer. */ - case PRU_RCVD: - (void) tcp_output(tp); - break; - + case PRU_RCVD: + (void) tcp_output(tp); + break; + /* * Do a send by putting data in output queue and updating urgent * marker if URG set. Possibly send more data. */ - case PRU_SEND_EOF: - case PRU_SEND: - sbappend(so, &so->so_snd, m); - if (nam && tp->t_state < TCPS_SYN_SENT) { - /* - * Do implied connect if not yet connected, - * initialize window to default value, and - * initialize maxseg/maxopd using peer's cached - * MSS. - */ - error = tcp_connect(tp, nam); - if (error) + case PRU_SEND_EOF: + case PRU_SEND: + sbappend(&so->so_snd, m); + OS_DbgPrint(OSK_MID_TRACE,("%d Bytes to send:\n", m->m_len)); + OskitDumpBuffer(m->m_data, m->m_len); + if (nam && tp->t_state < TCPS_SYN_SENT) { + /* + * Do implied connect if not yet connected, + * initialize window to default value, and + * initialize maxseg/maxopd using peer's cached + * MSS. + */ + error = tcp_connect(tp, nam); + if (error) + break; + tp->snd_wnd = TTCP_CLIENT_SND_WND; + tcp_mss(tp, -1); + } + + if (req == PRU_SEND_EOF) { + /* + * Close the send side of the connection after + * the data is sent. + */ + socantsendmore(so); + tp = tcp_usrclosed(tp); + } + if (tp != NULL) + error = tcp_output(tp); break; - tp->snd_wnd = TTCP_CLIENT_SND_WND; - tcp_mss(tp, -1); - } - - if (req == PRU_SEND_EOF) { - /* - * Close the send side of the connection after - * the data is sent. - */ - socantsendmore(so); - tp = tcp_usrclosed(tp); - } - if (tp != NULL) - error = tcp_output(tp); - break; - + /* * Abort the TCP. */ - case PRU_ABORT: - tp = tcp_drop(tp, ECONNABORTED); - break; - - case PRU_SENSE: - ((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat; - (void) splx(s); - return (0); - - case PRU_RCVOOB: - if ((so->so_oobmark == 0 && - (so->so_state & SS_RCVATMARK) == 0) || - so->so_options & SO_OOBINLINE || - tp->t_oobflags & TCPOOB_HADDATA) { - error = EINVAL; - break; - } - if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) { - error = EWOULDBLOCK; - break; - } - m->m_len = 1; - *mtod(m, caddr_t) = tp->t_iobc; - if (((int)nam & MSG_PEEK) == 0) - tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA); - break; - - case PRU_SENDOOB: - if (sbspace(&so->so_snd) < -512) { - m_freem(m); - error = ENOBUFS; - break; - } - /* - * According to RFC961 (Assigned Protocols), - * the urgent pointer points to the last octet - * of urgent data. We continue, however, - * to consider it to indicate the first octet - * of data past the urgent section. - * Otherwise, snd_up should be one lower. - */ - sbappend(so, &so->so_snd, m); - if (nam && tp->t_state < TCPS_SYN_SENT) { - /* - * Do implied connect if not yet connected, - * initialize window to default value, and - * initialize maxseg/maxopd using peer's cached - * MSS. - */ - error = tcp_connect(tp, nam); - if (error) + case PRU_ABORT: + tp = tcp_drop(tp, ECONNABORTED); break; - tp->snd_wnd = TTCP_CLIENT_SND_WND; - tcp_mss(tp, -1); - } - tp->snd_up = tp->snd_una + so->so_snd.sb_cc; - tp->t_force = 1; - error = tcp_output(tp); - tp->t_force = 0; - break; - case PRU_SOCKADDR: - in_setsockaddr(inp, nam); - break; + case PRU_SENSE: + ((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat; + (void) splx(s); + return (0); - case PRU_PEERADDR: - in_setpeeraddr(inp, nam); - break; + case PRU_RCVOOB: + if ((so->so_oobmark == 0 && + (so->so_state & SS_RCVATMARK) == 0) || + so->so_options & SO_OOBINLINE || + tp->t_oobflags & TCPOOB_HADDATA) { + error = EINVAL; + break; + } + if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) { + error = EWOULDBLOCK; + break; + } + m->m_len = 1; + *mtod(m, caddr_t) = tp->t_iobc; + if (((int)nam & MSG_PEEK) == 0) + tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA); + break; + + case PRU_SENDOOB: + if (sbspace(&so->so_snd) < -512) { + m_freem(m); + error = ENOBUFS; + break; + } + /* + * According to RFC961 (Assigned Protocols), + * the urgent pointer points to the last octet + * of urgent data. We continue, however, + * to consider it to indicate the first octet + * of data past the urgent section. + * Otherwise, snd_up should be one lower. + */ + sbappend(&so->so_snd, m); + if (nam && tp->t_state < TCPS_SYN_SENT) { + /* + * Do implied connect if not yet connected, + * initialize window to default value, and + * initialize maxseg/maxopd using peer's cached + * MSS. + */ + error = tcp_connect(tp, nam); + if (error) + break; + tp->snd_wnd = TTCP_CLIENT_SND_WND; + tcp_mss(tp, -1); + } + tp->snd_up = tp->snd_una + so->so_snd.sb_cc; + tp->t_force = 1; + error = tcp_output(tp); + tp->t_force = 0; + break; + + case PRU_SOCKADDR: + in_setsockaddr(inp, nam); + break; + + case PRU_PEERADDR: + in_setpeeraddr(inp, nam); + break; /* * TCP slow timer went off; going through this * routine for tracing's sake. */ - case PRU_SLOWTIMO: - tp = tcp_timers(tp, (int)nam); + case PRU_SLOWTIMO: + tp = tcp_timers(tp, (int)nam); #ifdef TCPDEBUG - req |= (int)nam << 8; /* for debug's sake */ + req |= (int)nam << 8; /* for debug's sake */ #endif - break; - - default: - panic("tcp_usrreq"); - } + break; + + default: + panic("tcp_usrreq"); + } #ifdef TCPDEBUG - if (tp && (so->so_options & SO_DEBUG)) - tcp_trace(TA_USER, ostate, tp, (struct tcpiphdr *)0, req); + if (tp && (so->so_options & SO_DEBUG)) + tcp_trace(TA_USER, ostate, tp, (struct tcpiphdr *)0, req); #endif - splx(s); - return (error); + splx(s); + return (error); } /* @@ -376,126 +409,100 @@ tcp_usrreq(so, req, m, nam, control) * sending CC options and if the connection duration was < MSL, then * truncate the previous TIME-WAIT state and proceed. * Initialize connection parameters and enter SYN-SENT state. - */ + */ int tcp_connect(tp, nam) register struct tcpcb *tp; struct mbuf *nam; { - struct inpcb *inp/* = tp->t_inpcb */, *oinp; - struct socket *so; - struct tcpcb *otp; - struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); - struct sockaddr_in ifaddr; - int error; - struct rmxp_tao *taop; - struct rmxp_tao tao_noncached; + struct inpcb *inp = tp->t_inpcb, *oinp; + struct socket *so = inp->inp_socket; + struct tcpcb *otp; + struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); + struct sockaddr_in *ifaddr; + int error; + struct rmxp_tao *taop; + struct rmxp_tao tao_noncached; - if( !tp ) - panic( "No tcpcb provided.\n" ); + OS_DbgPrint(OSK_MID_TRACE,("Called\n")); - if( !tp->t_inpcb ) - panic( "No inpcb provided.\n" ); + if (inp->inp_lport == 0) { + error = in_pcbbind(inp, NULL); + if (error) + return error; + } - inp = tp->t_inpcb; - - if( !inp->inp_socket ) - panic( "No socket provided.\n" ); - - so = inp->inp_socket; - - if (inp->inp_lport == 0) { - error = in_pcbbind(inp, NULL); - if (error) { - OS_DbgPrint(OSK_MID_TRACE,("error %d\n", error)); + /* + * Cannot simply call in_pcbconnect, because there might be an + * earlier incarnation of this same connection still in + * TIME_WAIT state, creating an ADDRINUSE error. + */ + error = in_pcbladdr(inp, nam, &ifaddr); + if (error) { + OS_DbgPrint(OSK_MID_TRACE,("leaving %d\n", error)); return error; } - } - /* - * Cannot simply call in_pcbconnect, because there might be an - * earlier incarnation of this same connection still in - * TIME_WAIT state, creating an ADDRINUSE error. - */ - error = in_pcbladdr(inp, nam, &ifaddr); - - if (error) { - OS_DbgPrint(OSK_MID_TRACE,("error %d\n", error)); - return error; - } - - oinp = in_pcblookup(inp->inp_pcbinfo->listhead, - sin->sin_addr, sin->sin_port, - inp->inp_laddr.s_addr != INADDR_ANY ? inp->inp_laddr - : ifaddr.sin_addr, - inp->inp_lport, 0); - - if (oinp) { - - if (oinp != inp && (otp = intotcpcb(oinp)) != NULL && - otp->t_state == TCPS_TIME_WAIT && - otp->t_duration < TCPTV_MSL && - (otp->t_flags & TF_RCVD_CC)) - otp = tcp_close(otp); - else { - - OS_DbgPrint(OSK_MID_TRACE,("error EADDRINUSE\n")); - return EADDRINUSE; + oinp = in_pcblookup(inp->inp_pcbinfo->listhead, + sin->sin_addr, sin->sin_port, + inp->inp_laddr.s_addr != INADDR_ANY ? inp->inp_laddr + : ifaddr->sin_addr, + inp->inp_lport, 0); + if (oinp) { + if (oinp != inp && (otp = intotcpcb(oinp)) != NULL && + otp->t_state == TCPS_TIME_WAIT && + otp->t_duration < TCPTV_MSL && + (otp->t_flags & TF_RCVD_CC)) + otp = tcp_close(otp); + else { + OS_DbgPrint(OSK_MID_TRACE,("leaving EADDRINUSE\n")); + return EADDRINUSE; + } } - - } - - if (inp->inp_laddr.s_addr == INADDR_ANY) - inp->inp_laddr = ifaddr.sin_addr; - - inp->inp_faddr = sin->sin_addr; - inp->inp_fport = sin->sin_port; - - in_pcbrehash(inp); - - tp->t_template = tcp_template(tp); - - if (tp->t_template == 0) { - in_pcbdisconnect(inp); - OS_DbgPrint(OSK_MID_TRACE,("error ENOBUFS\n")); - return ENOBUFS; - } - - - /* Compute window scaling to request. */ - while (tp->request_r_scale < TCP_MAX_WINSHIFT && - (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) - tp->request_r_scale++; - - - soisconnecting(so); - - tcpstat.tcps_connattempt++; - tp->t_state = TCPS_SYN_SENT; - tp->t_timer[TCPT_KEEP] = tcp_keepinit; - tp->rcv_nxt = 0; - tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2; - - tcp_sendseqinit(tp); - - /* - * Generate a CC value for this connection and - * check whether CC or CCnew should be used. - */ - if ((taop = tcp_gettaocache(tp->t_inpcb)) == NULL) { - taop = &tao_noncached; - bzero(taop, sizeof(*taop)); - } + if (inp->inp_laddr.s_addr == INADDR_ANY) + inp->inp_laddr = ifaddr->sin_addr; + inp->inp_faddr = sin->sin_addr; + inp->inp_fport = sin->sin_port; + in_pcbrehash(inp); - tp->cc_send = CC_INC(tcp_ccgen); - if (taop->tao_ccsent != 0 && - CC_GEQ(tp->cc_send, taop->tao_ccsent)) { - taop->tao_ccsent = tp->cc_send; - } else { - taop->tao_ccsent = 0; - tp->t_flags |= TF_SENDCCNEW; - } + tp->t_template = tcp_template(tp); + if (tp->t_template == 0) { + in_pcbdisconnect(inp); + OS_DbgPrint(OSK_MID_TRACE,("Leaving ENOBUFS\n")); + return ENOBUFS; + } - return 0; + /* Compute window scaling to request. */ + while (tp->request_r_scale < TCP_MAX_WINSHIFT && + (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) + tp->request_r_scale++; + + soisconnecting(so); + tcpstat.tcps_connattempt++; + tp->t_state = TCPS_SYN_SENT; + tp->t_timer[TCPT_KEEP] = tcp_keepinit; + tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2; + tcp_sendseqinit(tp); + + /* + * Generate a CC value for this connection and + * check whether CC or CCnew should be used. + */ + if ((taop = tcp_gettaocache(tp->t_inpcb)) == NULL) { + taop = &tao_noncached; + bzero(taop, sizeof(*taop)); + } + + tp->cc_send = CC_INC(tcp_ccgen); + if (taop->tao_ccsent != 0 && + CC_GEQ(tp->cc_send, taop->tao_ccsent)) { + taop->tao_ccsent = tp->cc_send; + } else { + taop->tao_ccsent = 0; + tp->t_flags |= TF_SENDCCNEW; + } + + OS_DbgPrint(OSK_MID_TRACE,("Leaving 0\n")); + return 0; } int @@ -638,7 +645,6 @@ tcp_attach(so) so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */ in_pcbdetach(inp); so->so_state |= nofd; - OS_DbgPrint(OSK_MID_TRACE,("ENOBUFS: no tcpcb allocated\n")); return (ENOBUFS); } tp->t_state = TCPS_CLOSED; @@ -730,42 +736,42 @@ tcp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) void *newp; size_t newlen; { - /* All sysctl names at this level are terminal. */ - if (namelen != 1) - return (ENOTDIR); - - switch (name[0]) { - case TCPCTL_DO_RFC1323: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_do_rfc1323)); - case TCPCTL_DO_RFC1644: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_do_rfc1644)); - case TCPCTL_MSSDFLT: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_mssdflt)); - case TCPCTL_STATS: - return (sysctl_rdstruct(oldp, oldlenp, newp, &tcpstat, - sizeof tcpstat)); - case TCPCTL_RTTDFLT: - return (sysctl_int(oldp, oldlenp, newp, newlen, &tcp_rttdflt)); - case TCPCTL_KEEPIDLE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_keepidle)); - case TCPCTL_KEEPINTVL: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_keepintvl)); - case TCPCTL_SENDSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - (int *)&tcp_sendspace)); /* XXX */ - case TCPCTL_RECVSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - (int *)&tcp_recvspace)); /* XXX */ - case TCPCTL_KEEPINIT: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_keepinit)); - default: - return (ENOPROTOOPT); - } + /* All sysctl names at this level are terminal. */ + if (namelen != 1) + return (ENOTDIR); + + switch (name[0]) { + case TCPCTL_DO_RFC1323: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_do_rfc1323)); + case TCPCTL_DO_RFC1644: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_do_rfc1644)); + case TCPCTL_MSSDFLT: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_mssdflt)); + case TCPCTL_STATS: + return (sysctl_rdstruct(oldp, oldlenp, newp, &tcpstat, + sizeof tcpstat)); + case TCPCTL_RTTDFLT: + return (sysctl_int(oldp, oldlenp, newp, newlen, &tcp_rttdflt)); + case TCPCTL_KEEPIDLE: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_keepidle)); + case TCPCTL_KEEPINTVL: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_keepintvl)); + case TCPCTL_SENDSPACE: + return (sysctl_int(oldp, oldlenp, newp, newlen, + (int *)&tcp_sendspace)); /* XXX */ + case TCPCTL_RECVSPACE: + return (sysctl_int(oldp, oldlenp, newp, newlen, + (int *)&tcp_recvspace)); /* XXX */ + case TCPCTL_KEEPINIT: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_keepinit)); + default: + return (ENOPROTOOPT); + } /* NOTREACHED */ } diff --git a/reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c b/reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c index 222efa3739f..d19f70f49dc 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c @@ -149,7 +149,11 @@ m_retry(i, t) * I'm getting rid of the utterly ugly redefinition of m_retry * - same for m_retryhdr below */ +#ifndef OSKIT + MGET(m,i,t); +#else MGET_DONT_RECURSE(m, i, t); +#endif if (m != NULL) mbstat.m_wait++; else @@ -167,7 +171,11 @@ m_retryhdr(i, t) register struct mbuf *m; m_reclaim(); +#ifndef OSKIT + MGETHDR(m, i, t); +#else MGETHDR_DONT_RECURSE(m, i, t); +#endif if (m != NULL) mbstat.m_wait++; else @@ -250,7 +258,7 @@ m_freem(m) if (m == NULL) return; do { - MFREE(m, n); + MFREE(m, n); m = n; } while (m); } @@ -307,7 +315,7 @@ m_copym(m, off0, len, wait) int copyhdr = 0; if (off < 0 || len < 0) - panic("m_copym"); + panic("m_copym: off %d, len %d", off, len); if (off == 0 && m->m_flags & M_PKTHDR) copyhdr = 1; while (off > 0) { @@ -395,6 +403,8 @@ m_copydata(m, off, len, cp) panic("m_copydata"); count = min(m->m_len - off, len); bcopy(mtod(m, caddr_t) + off, cp, count); + OS_DbgPrint(OSK_MID_TRACE,("buf %x, len %d\n", m, m->m_len)); + OskitDumpBuffer(m->m_data, m->m_len); len -= count; cp += count; off = 0; @@ -668,7 +678,11 @@ m_devget(buf, totlen, off0, ifp, copy) MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == 0) return (0); +#ifndef __REACTOS__ m->m_pkthdr.rcvif = ifp; +#else + m->m_pkthdr.rcvif = 0; +#endif m->m_pkthdr.len = totlen; m->m_len = MHLEN; @@ -702,7 +716,11 @@ m_devget(buf, totlen, off0, ifp, copy) if (copy) copy(cp, mtod(m, caddr_t), (unsigned)len); else +#ifdef __REACTOS__ + memcpy(mtod(m, caddr_t), cp, len); +#else bcopy(cp, mtod(m, caddr_t), (unsigned)len); +#endif cp += len; *mp = m; mp = &m->m_next; diff --git a/reactos/drivers/lib/oskittcp/oskittcp/uipc_socket.c b/reactos/drivers/lib/oskittcp/oskittcp/uipc_socket.c index 1320b84268b..9b9dae0fff5 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/uipc_socket.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/uipc_socket.c @@ -414,6 +414,7 @@ restart: if (flags & MSG_EOR) top->m_flags |= M_EOR; } else do { +#ifndef __REACTOS__ if (top == 0) { MGETHDR(m, M_WAIT, MT_DATA); mlen = MHLEN; @@ -423,6 +424,12 @@ restart: MGET(m, M_WAIT, MT_DATA); mlen = MLEN; } +#else + MGETHDR(m, M_WAIT, MT_DATA); + mlen = MLEN; + m->m_pkthdr.len = 0; + m->m_pkthdr.rcvif = (struct ifnet *)0; +#endif if (resid >= MINCLSIZE) { MCLGET(m, M_WAIT); if ((m->m_flags & M_EXT) == 0) @@ -444,6 +451,7 @@ nopages: error = uiomove(mtod(m, caddr_t), (int)len, uio); resid = uio->uio_resid; #else + memcpy(mtod(m, caddr_t), mtod(top, caddr_t), len); resid = 0; #endif m->m_len = len; @@ -494,6 +502,7 @@ out: if (control) m_freem(control); #endif /* The caller owns top and control */ + OS_DbgPrint(OSK_MID_TRACE,("Leaving\n")); return (error); } @@ -847,5 +856,5 @@ sohasoutofband(so) gsignal(-so->so_pgid, SIGURG); else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0) psignal(p, SIGURG); - wakeup(so, NULL, 0); + wakeup(so, 0); } diff --git a/reactos/drivers/lib/oskittcp/oskittcp/uipc_socket2.c b/reactos/drivers/lib/oskittcp/oskittcp/uipc_socket2.c index ec24f57dfb1..359e9f9abee 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/uipc_socket2.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/uipc_socket2.c @@ -97,9 +97,9 @@ void soisconnecting(so) register struct socket *so; { - - so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); - so->so_state |= SS_ISCONNECTING; + OS_DbgPrint(OSK_MID_TRACE,("Called %x\n", so)); + so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); + so->so_state |= SS_ISCONNECTING; } void @@ -108,16 +108,18 @@ soisconnected(so) { register struct socket *head = so->so_head; + OS_DbgPrint(OSK_MID_TRACE,("Called %x\n", so)); + so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING); so->so_state |= SS_ISCONNECTED; if (head && soqremque(so, 0)) { - soqinsque(head, so, 1); - sorwakeup(head); - wakeup(so, NULL, (caddr_t)&head->so_timeo); + soqinsque(head, so, 1); + sorwakeup(head); + wakeup(so, (caddr_t)&head->so_timeo); } else { - wakeup(so, NULL, (caddr_t)&so->so_timeo); - sorwakeup(so); - socwakeup(so); + wakeup(so, (caddr_t)&so->so_timeo); + sorwakeup(so); + sowwakeup(so); } } @@ -125,24 +127,25 @@ void soisdisconnecting(so) register struct socket *so; { - - so->so_state &= ~SS_ISCONNECTING; - so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); - wakeup(so, NULL, (caddr_t)&so->so_timeo); - sowwakeup(so); - sorwakeup(so); + OS_DbgPrint(OSK_MID_TRACE,("Called %x\n", so)); + so->so_state &= ~SS_ISCONNECTING; + so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); + wakeup(so, (caddr_t)&so->so_timeo); + sowwakeup(so); + sorwakeup(so); } void soisdisconnected(so) register struct socket *so; { - - so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); - so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); - wakeup(so, NULL, (caddr_t)&so->so_timeo); - sowwakeup(so); - sorwakeup(so); + OS_DbgPrint(OSK_MID_TRACE,("Called %x\n", so)); + + so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); + so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); + wakeup(so, (caddr_t)&so->so_timeo); + sowwakeup(so); + sorwakeup(so); } /* @@ -164,6 +167,8 @@ sonewconn1(head, connstatus) register struct socket *so; int soqueue = connstatus ? 1 : 0; + OS_DbgPrint(OSK_MID_TRACE,("Called %x\n", head)); + if ((head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2) && (head->so_qlen + head->so_q0len > sominqueue)) return ((struct socket *)0); @@ -188,7 +193,7 @@ sonewconn1(head, connstatus) } if (connstatus) { sorwakeup(head); - wakeup(so, NULL, (caddr_t)&head->so_timeo); + wakeup(head, (caddr_t)&head->so_timeo); so->so_state |= connstatus; } return (so); @@ -321,7 +326,23 @@ sowakeup(so, sb) { struct proc *p; - wakeup(so, &sb->sb_sel, (caddr_t)&sb->sb_cc); + wakeup(so, &sb->sb_sel); +#ifndef OSKIT + /* + * in the OS Kit, we do not want notifications to stop + */ + sb->sb_flags &= ~SB_SEL; +#endif + if (sb->sb_flags & SB_WAIT) { + sb->sb_flags &= ~SB_WAIT; + wakeup(so, (caddr_t)&sb->sb_cc); + } + if (so->so_state & SS_ASYNC) { + if (so->so_pgid < 0) + gsignal(-so->so_pgid, SIGIO); + else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0) + psignal(p, SIGIO); + } } /* @@ -361,6 +382,7 @@ soreserve(so, sndcc, rcvcc) register struct socket *so; u_long sndcc, rcvcc; { + if (sbreserve(&so->so_snd, sndcc) == 0) goto bad; if (sbreserve(&so->so_rcv, rcvcc) == 0) @@ -442,52 +464,31 @@ sbrelease(sb) * discarded and mbufs are compacted where possible. */ void -sbappend(so, sb, m) - struct socket *so; - struct sockbuf *sb; - struct mbuf *m; +sbappend(sb, m) + struct sockbuf *sb; + struct mbuf *m; { - register struct mbuf *n, *new_mbuf; + register struct mbuf *n; - free( malloc( 2 ) ); + OS_DbgPrint(OSK_MID_TRACE,("Called\n")); if (m == 0) return; - n = sb->sb_mb; - OS_DbgPrint(OSK_MID_TRACE,("sbappendrecord: %x\n", n)); - - while( n && n->m_nextpkt ) n = n->m_nextpkt; - - new_mbuf = malloc( sizeof( *m ) + m->m_len ); - memset( new_mbuf, 0, sizeof( *m ) ); - - free( malloc( 2 ) ); - - new_mbuf->m_type = MT_DATA; - free( malloc( 2 ) ); - - new_mbuf->m_len = m->m_len; - free( malloc( 2 ) ); - - new_mbuf->m_data = ((caddr_t)new_mbuf) + sizeof(*new_mbuf); - free( malloc( 2 ) ); - - memcpy( new_mbuf->m_data, m->m_data, m->m_len ); - - free( malloc( 2 ) ); - - if( n ) { - n->m_nextpkt = new_mbuf; - OS_DbgPrint(OSK_MID_TRACE,("SK BUFF NEW: %x\n", n->m_nextpkt)); - } else { - sb->sb_mb = new_mbuf; - OS_DbgPrint(OSK_MID_TRACE, - ("SK BUFF HEAD: %x (new pkt %d bytes)\n", - sb->sb_mb, sb->sb_mb->m_len)); + if (n) { + while (n->m_nextpkt) + n = n->m_nextpkt; + do { + if (n->m_flags & M_EOR) { + sbappendrecord(sb, m); /* XXXXXX!!!! */ + OS_DbgPrint(OSK_MID_TRACE,("Leaving (rec)\n")); + return; + } + } while (n->m_next && (n = n->m_next)); } + sbcompress(sb, m, n); - free( malloc( 2 ) ); + OS_DbgPrint(OSK_MID_TRACE,("Leaving\n")); } #ifdef SOCKBUF_DEBUG @@ -535,7 +536,6 @@ sbappendrecord(sb, m0) * Put the first mbuf on the queue. * Note this permits zero length records. */ - sballoc(sb, m0); if (m) m->m_nextpkt = m0; @@ -609,10 +609,10 @@ sbappendaddr(sb, asa, m0, control) struct mbuf *m0, *control; { register struct mbuf *m, *n; - int space = /*asa->sa_len;*/ sizeof(struct sockaddr); + int space = asa->sa_len; if (m0 && (m0->m_flags & M_PKTHDR) == 0) - panic("sbappendaddr"); +panic("sbappendaddr"); if (m0) space += m0->m_pkthdr.len; for (n = control; n; n = n->m_next) { @@ -622,11 +622,13 @@ if (m0 && (m0->m_flags & M_PKTHDR) == 0) } if (space > sbspace(sb)) return (0); + if (asa->sa_len > MLEN) + return (0); MGET(m, M_DONTWAIT, MT_SONAME); if (m == 0) return (0); - m->m_len = sizeof(struct sockaddr); - bcopy((caddr_t)asa, mtod(m, caddr_t), sizeof(struct sockaddr)); + m->m_len = asa->sa_len; + bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len); if (n) n->m_next = m0; /* concatenate data to control */ else @@ -706,8 +708,6 @@ sbcompress(sb, m, n) (unsigned)m->m_len); n->m_len += m->m_len; sb->sb_cc += m->m_len; - OS_DbgPrint(OSK_MID_TRACE,("SB->SB_CC = %d\n", - sb->sb_cc)); m = m_free(m); continue; } @@ -742,10 +742,8 @@ sbflush(sb) panic("sbflush"); while (sb->sb_mbcnt) sbdrop(sb, (int)sb->sb_cc); -#if 0 if (sb->sb_cc || sb->sb_mb) panic("sbflush 2"); -#endif } /* @@ -772,8 +770,6 @@ sbdrop(sb, len) m->m_len -= len; m->m_data += len; sb->sb_cc -= len; - OS_DbgPrint(OSK_MID_TRACE,("SB->SB_CC = %d\n", - sb->sb_cc)); break; } len -= m->m_len; diff --git a/reactos/drivers/net/tcpip/datalink/arp.c b/reactos/drivers/net/tcpip/datalink/arp.c index c9cd5ad71b9..fc293f3a682 100644 --- a/reactos/drivers/net/tcpip/datalink/arp.c +++ b/reactos/drivers/net/tcpip/datalink/arp.c @@ -10,7 +10,6 @@ #include "precomp.h" - PNDIS_PACKET PrepareARPPacket( USHORT HardwareType, USHORT ProtocolType, @@ -55,7 +54,7 @@ PNDIS_PACKET PrepareARPPacket( NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, Size ); if( !NT_SUCCESS(NdisStatus) ) return NULL; - GetDataPtr( NdisPacket, 0, &DataBuffer, &Contig ); + GetDataPtr( NdisPacket, 0, (PCHAR *)&DataBuffer, (PUINT)&Contig ); RtlZeroMemory(DataBuffer, Size); Header = (PARP_HEADER)((ULONG_PTR)DataBuffer + MaxLLHeaderSize); @@ -139,6 +138,8 @@ BOOLEAN ARPTransmit( ProtoAddrLen = 16; /* Length of IPv6 address */ break; default: + TI_DbgPrint(DEBUG_ARP,("Bad Address Type %x\n", Address->Type)); + KeBugCheck(0); /* Should not happen */ return FALSE; } @@ -156,6 +157,8 @@ BOOLEAN ARPTransmit( PC(NdisPacket)->DLComplete = ARPTransmitComplete; + TI_DbgPrint(DEBUG_ARP,("Sending ARP Packet\n")); + (*Interface->Transmit)(Interface->Context, NdisPacket, MaxLLHeaderSize, NULL, LAN_PROTO_ARP); diff --git a/reactos/drivers/net/tcpip/datalink/lan.c b/reactos/drivers/net/tcpip/datalink/lan.c index bb143b1e16f..b79fda965e0 100644 --- a/reactos/drivers/net/tcpip/datalink/lan.c +++ b/reactos/drivers/net/tcpip/datalink/lan.c @@ -173,7 +173,9 @@ VOID STDCALL ProtocolSendComplete( TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); AdjustPacket(Packet, Adapter->HeaderSize, PC(Packet)->DLOffset); + TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n")); (*PC(Packet)->DLComplete)(Adapter->Context, Packet, Status); + TI_DbgPrint(DEBUG_DATALINK, ("Finished\n")); } @@ -218,7 +220,9 @@ VOID STDCALL ProtocolTransferDataComplete( OskitDumpBuffer( IPPacket.Header, BytesTransferred ); PacketType = ((PETH_HEADER)IPPacket.Header)->EType; - IPPacket.Header += MaxLLHeaderSize; + IPPacket.Header = ((PCHAR)IPPacket.Header) + sizeof(ETH_HEADER); + IPPacket.Position = sizeof(ETH_HEADER); + IPPacket.TotalSize -= sizeof(ETH_HEADER); TI_DbgPrint (DEBUG_DATALINK, @@ -271,7 +275,6 @@ NDIS_STATUS STDCALL ProtocolReceive( PCHAR BufferData; NDIS_STATUS NdisStatus; PNDIS_PACKET NdisPacket; - PNDIS_BUFFER NdisBuffer; PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; PETH_HEADER EHeader = (PETH_HEADER)HeaderBuffer; @@ -319,19 +322,23 @@ NDIS_STATUS STDCALL ProtocolReceive( } IPPacket.NdisPacket = NdisPacket; + IPPacket.Position = 0; +#if 0 if (LookaheadBufferSize < PacketSize) { +#endif TI_DbgPrint(DEBUG_DATALINK, ("pretransfer LookaheadBufferSize %d packsize %d\n",LookaheadBufferSize,PacketSize)); /* Get the data */ - NdisTransferData(&NdisStatus, - Adapter->NdisHandle, - MacReceiveContext, - 0, - PacketSize, - NdisPacket, - &BytesTransferred); + NdisTransferData(&NdisStatus, + Adapter->NdisHandle, + MacReceiveContext, + 0, + PacketSize + HeaderBufferSize, + NdisPacket, + &BytesTransferred); +#if 0 } else { - TI_DbgPrint(DEBUG_DATALINK, ("copy\n")); + TI_DbgPrint(DEBUG_DATALINK, ("copy\n")); NdisStatus = NDIS_STATUS_SUCCESS; BytesTransferred = PacketSize; RtlCopyMemory(BufferData, @@ -340,13 +347,14 @@ NDIS_STATUS STDCALL ProtocolReceive( RtlCopyMemory(BufferData + HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize); } +#endif TI_DbgPrint(DEBUG_DATALINK, ("Calling complete\n")); if (NdisStatus != NDIS_STATUS_PENDING) ProtocolTransferDataComplete(BindingContext, NdisPacket, NdisStatus, - BytesTransferred); + PacketSize + HeaderBufferSize); /* Release the packet descriptor */ KeReleaseSpinLockFromDpcLevel(&Adapter->Lock); @@ -581,11 +589,9 @@ VOID BindAdapter( * bind the adapter to IP layer */ { - INT i; PIP_INTERFACE IF; PIP_ADDRESS Address = 0; PIP_ADDRESS Netmask = 0; - PNDIS_PACKET Packet; NDIS_STATUS NdisStatus; LLIP_BIND_INFO BindInfo; ULONG Lookahead = LOOKAHEAD_SIZE; @@ -732,7 +738,6 @@ NDIS_STATUS LANRegisterAdapter( PLAN_ADAPTER IF; NDIS_STATUS NdisStatus; NDIS_STATUS OpenStatus; - PNDIS_CONFIGURATION_PARAMETER Parameter; UINT MediaIndex; NDIS_MEDIUM MediaArray[MAX_MEDIA]; UINT AddressOID; diff --git a/reactos/drivers/net/tcpip/include/address.h b/reactos/drivers/net/tcpip/include/address.h index 450f96889c2..87cca427482 100644 --- a/reactos/drivers/net/tcpip/include/address.h +++ b/reactos/drivers/net/tcpip/include/address.h @@ -37,9 +37,8 @@ BOOLEAN AddrIsUnspecified( NTSTATUS AddrGetAddress( PTRANSPORT_ADDRESS AddrList, - PIP_ADDRESS *Address, - PUSHORT Port, - PIP_ADDRESS *Cache); + PIP_ADDRESS Address, + PUSHORT Port); NTSTATUS AddrBuildAddress( PTA_ADDRESS TdiAddress, diff --git a/reactos/drivers/net/tcpip/include/debug.h b/reactos/drivers/net/tcpip/include/debug.h index fffbe2c7781..56a8bf2767f 100644 --- a/reactos/drivers/net/tcpip/include/debug.h +++ b/reactos/drivers/net/tcpip/include/debug.h @@ -17,7 +17,7 @@ #define DEBUG_CHECK 0x00000100 #define DEBUG_MEMORY 0x00000200 -#define DEBUG_BUFFER 0x00000400 +#define DEBUG_PBUFFER 0x00000400 #define DEBUG_IRP 0x00000800 #define DEBUG_REFCOUNT 0x00001000 #define DEBUG_ADDRFILE 0x00002000 diff --git a/reactos/drivers/net/tcpip/include/info.h b/reactos/drivers/net/tcpip/include/info.h index bb14a1d72a8..cc27ac1d69e 100644 --- a/reactos/drivers/net/tcpip/include/info.h +++ b/reactos/drivers/net/tcpip/include/info.h @@ -123,6 +123,8 @@ typedef union TDI_INFO { TDI_PROVIDER_STATISTICS ProviderStats; } TDI_INFO, *PTDI_INFO; +TDI_STATUS InfoCopyOut( PCHAR DataOut, UINT SizeOut, + PNDIS_BUFFER ClientBuf, PUINT ClientBufSize ); TDI_STATUS InfoTdiQueryInformationEx( PTDI_REQUEST Request, diff --git a/reactos/drivers/net/tcpip/include/interface.h b/reactos/drivers/net/tcpip/include/interface.h index 7269208438d..299e7aa289d 100644 --- a/reactos/drivers/net/tcpip/include/interface.h +++ b/reactos/drivers/net/tcpip/include/interface.h @@ -8,7 +8,7 @@ NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface, PULONG Address ); UINT CountInterfaces(); - +UINT CountInterfaceAddresses( PIP_INTERFACE Interface ); NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed ); NTSTATUS GetInterfaceName( PIP_INTERFACE Interface, PCHAR NameBuffer, UINT NameMaxLen ); diff --git a/reactos/drivers/net/tcpip/include/ip.h b/reactos/drivers/net/tcpip/include/ip.h index a9d5f952617..7c84b47dead 100644 --- a/reactos/drivers/net/tcpip/include/ip.h +++ b/reactos/drivers/net/tcpip/include/ip.h @@ -161,6 +161,8 @@ typedef struct _IP_INTERFACE { PUCHAR Address; /* Pointer to interface address */ UINT AddressLength; /* Length of address in bytes */ LL_TRANSMIT_ROUTINE Transmit; /* Pointer to transmit function */ + + PVOID TCPContext; /* TCP Content for this interface */ } IP_INTERFACE, *PIP_INTERFACE; @@ -199,6 +201,10 @@ extern UINT MinLLFrameSize; PIP_PACKET IPCreatePacket( ULONG Type); +PIP_PACKET IPInitializePacket( + PIP_PACKET IPPacket, + ULONG Type); + PNET_TABLE_ENTRY IPCreateNTE( PIP_INTERFACE IF, PIP_ADDRESS Address, @@ -239,7 +245,7 @@ VOID STDCALL IPTimeout( PVOID SystemArgument2); VOID IPDispatchProtocol( - PIP_INTERFACE IF, + PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket); VOID IPRegisterProtocol( diff --git a/reactos/drivers/net/tcpip/include/irp.h b/reactos/drivers/net/tcpip/include/irp.h new file mode 100644 index 00000000000..d49231b4411 --- /dev/null +++ b/reactos/drivers/net/tcpip/include/irp.h @@ -0,0 +1,12 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: include/irp.h + * PURPOSE: IRP routines + */ +#ifndef __IRP_H +#define __IRP_H + +NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ); + +#endif/*__IRP_H*/ diff --git a/reactos/drivers/net/tcpip/include/lan.h b/reactos/drivers/net/tcpip/include/lan.h index fc59398c09f..18d9b8ddaa9 100644 --- a/reactos/drivers/net/tcpip/include/lan.h +++ b/reactos/drivers/net/tcpip/include/lan.h @@ -92,6 +92,13 @@ NTSTATUS LANRegisterProtocol( VOID LANUnregisterProtocol( VOID); +NDIS_STATUS NDISCall( + PLAN_ADAPTER Adapter, + NDIS_REQUEST_TYPE Type, + NDIS_OID OID, + PVOID Buffer, + UINT Length); + #endif /* __LAN_H */ /* EOF */ diff --git a/reactos/drivers/net/tcpip/include/neighbor.h b/reactos/drivers/net/tcpip/include/neighbor.h index 1c401f863ba..8b7f71ecfb9 100644 --- a/reactos/drivers/net/tcpip/include/neighbor.h +++ b/reactos/drivers/net/tcpip/include/neighbor.h @@ -26,11 +26,11 @@ typedef struct NEIGHBOR_CACHE_ENTRY { UINT EventTimer; /* Ticks since last event */ UINT EventCount; /* Number of events */ PIP_INTERFACE Interface; /* Pointer to interface */ - PIP_ADDRESS Address; /* IP address of neighbor */ UINT LinkAddressLength; /* Length of link address */ PVOID LinkAddress; /* Pointer to link address */ PNDIS_PACKET WaitQueue; /* Pointer to NDIS packets waiting to be sent */ + IP_ADDRESS Address; /* IP address of neighbor */ } NEIGHBOR_CACHE_ENTRY, *PNEIGHBOR_CACHE_ENTRY; /* NCE states */ diff --git a/reactos/drivers/net/tcpip/include/precomp.h b/reactos/drivers/net/tcpip/include/precomp.h index 96b26a2fc3d..8532a9ff6e5 100644 --- a/reactos/drivers/net/tcpip/include/precomp.h +++ b/reactos/drivers/net/tcpip/include/precomp.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -28,3 +29,4 @@ #include #include #include +#include diff --git a/reactos/drivers/net/tcpip/include/route.h b/reactos/drivers/net/tcpip/include/route.h index 4eb9ff3c1f7..cab0422bf43 100644 --- a/reactos/drivers/net/tcpip/include/route.h +++ b/reactos/drivers/net/tcpip/include/route.h @@ -75,6 +75,11 @@ VOID RouteInvalidateNTE( VOID RouteInvalidateNCE( PNEIGHBOR_CACHE_ENTRY NCE); +NTSTATUS +RouteFriendlyAddRoute( PIPROUTE_ENTRY ire ); + +UINT CountRouteNodes( PROUTE_CACHE_NODE Node ); + #endif /* __ROUTE_H */ /* EOF */ diff --git a/reactos/drivers/net/tcpip/include/routines.h b/reactos/drivers/net/tcpip/include/routines.h index 2c546f5247c..cdb65c889a4 100644 --- a/reactos/drivers/net/tcpip/include/routines.h +++ b/reactos/drivers/net/tcpip/include/routines.h @@ -13,17 +13,17 @@ UINT Random(VOID); UINT CopyBufferToBufferChain( PNDIS_BUFFER DstBuffer, UINT DstOffset, - PUCHAR SrcData, + PCHAR SrcData, UINT Length); UINT CopyBufferChainToBuffer( - PUCHAR DstData, + PCHAR DstData, PNDIS_BUFFER SrcBuffer, UINT SrcOffset, UINT Length); UINT CopyPacketToBuffer( - PUCHAR DstData, + PCHAR DstData, PNDIS_PACKET SrcPacket, UINT SrcOffset, UINT Length); @@ -49,6 +49,15 @@ UINT ResizePacket( PNDIS_PACKET Packet, UINT Size); +NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, + PCHAR Data, UINT Len, + PCHAR File, UINT Line ); + +void GetDataPtr( PNDIS_PACKET Packet, + UINT Offset, + PCHAR *DataOut, + PUINT Size ); + #ifdef DBG VOID DisplayIPPacket( PIP_PACKET IPPacket); diff --git a/reactos/drivers/net/tcpip/include/tcp.h b/reactos/drivers/net/tcpip/include/tcp.h index d3f876926b8..d15dabc4a0f 100644 --- a/reactos/drivers/net/tcpip/include/tcp.h +++ b/reactos/drivers/net/tcpip/include/tcp.h @@ -109,6 +109,15 @@ NTSTATUS TCPSendData( ULONG Flags, PULONG DataUsed); +NTSTATUS TCPClose +( PTDI_REQUEST Request ); + +PVOID TCPPrepareInterface( PIP_INTERFACE IF ); + +NTSTATUS TCPTranslateError( int OskitError ); + +VOID TCPTimeout(); + NTSTATUS TCPStartup( VOID); diff --git a/reactos/drivers/net/tcpip/include/titypes.h b/reactos/drivers/net/tcpip/include/titypes.h index ced8385c559..7f4d53945f6 100644 --- a/reactos/drivers/net/tcpip/include/titypes.h +++ b/reactos/drivers/net/tcpip/include/titypes.h @@ -111,7 +111,7 @@ typedef VOID (*DATAGRAM_COMPLETION_ROUTINE)( typedef struct _DATAGRAM_RECEIVE_REQUEST { LIST_ENTRY ListEntry; /* Entry on list */ - PIP_ADDRESS RemoteAddress; /* Remote address we receive from (NULL means any) */ + IP_ADDRESS RemoteAddress; /* Remote address we receive from (NULL means any) */ USHORT RemotePort; /* Remote port we receive from (0 means any) */ PTDI_CONNECTION_INFORMATION ReturnInfo; /* Return information */ PNDIS_BUFFER Buffer; /* Pointer to receive buffer */ diff --git a/reactos/drivers/net/tcpip/makefile b/reactos/drivers/net/tcpip/makefile index c49417175c8..f2924533430 100644 --- a/reactos/drivers/net/tcpip/makefile +++ b/reactos/drivers/net/tcpip/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.19 2004/08/15 23:41:23 chorns Exp $ +# $Id: makefile,v 1.20 2004/08/19 21:38:58 arty Exp $ PATH_TO_TOP = ../../.. @@ -14,6 +14,8 @@ TARGET_PCH = include/precomp.h TARGET_CFLAGS = \ -D__USE_W32API \ -DNDIS40 \ + -DMEMTRACK \ + -Wall -Werror \ -I./include \ -I$(PATH_TO_TOP)/drivers/lib/oskittcp/include \ -I$(PATH_TO_TOP)/w32api/include \ diff --git a/reactos/drivers/net/tcpip/network/icmp.c b/reactos/drivers/net/tcpip/network/icmp.c index e272d58f705..862ae50c732 100644 --- a/reactos/drivers/net/tcpip/network/icmp.c +++ b/reactos/drivers/net/tcpip/network/icmp.c @@ -236,8 +236,7 @@ VOID ICMPTransmit( IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0); /* Get a route to the destination address */ - PNEIGHBOR_CACHE_ENTRY *NCE = RouterGetRoute( &IPPacket->DstAddr, NULL ); - if (RouteGetRouteToDestination(&IPPacket->DstAddr, NTE, &RCN) == IP_SUCCESS) { + if (RouteGetRouteToDestination(&IPPacket->DstAddr, NULL, &RCN) == IP_SUCCESS) { /* Send the packet */ if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS) { FreeNdisPacket(IPPacket->NdisPacket); diff --git a/reactos/drivers/net/tcpip/network/ip.c b/reactos/drivers/net/tcpip/network/ip.c index c6bef3d4db6..652652c67ca 100644 --- a/reactos/drivers/net/tcpip/network/ip.c +++ b/reactos/drivers/net/tcpip/network/ip.c @@ -636,7 +636,7 @@ VOID STDCALL IPTimeout( VOID IPDispatchProtocol( - PIP_INTERFACE IPInterface, + PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket) /* * FUNCTION: IP protocol dispatcher @@ -663,7 +663,7 @@ VOID IPDispatchProtocol( } /* Call the appropriate protocol handler */ - (*ProtocolTable[Protocol])(IPInterface, IPPacket); + (*ProtocolTable[Protocol])(NTE, IPPacket); } @@ -775,7 +775,7 @@ BOOLEAN IPRegisterInterface( PROUTE_CACHE_NODE RCN; PNEIGHBOR_CACHE_ENTRY NCE; - TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X).\n", IF)); + TI_DbgPrint(MID_TRACE, ("Called. IF (0x%X).\n", IF)); KeAcquireSpinLock(&IF->Lock, &OldIrql); @@ -826,6 +826,9 @@ BOOLEAN IPRegisterInterface( &IF->ListEntry, &InterfaceListLock); + /* Allow TCP to hang some configuration on this interface */ + IF->TCPContext = TCPPrepareInterface( IF ); + KeReleaseSpinLock(&IF->Lock, OldIrql); return TRUE; diff --git a/reactos/drivers/net/tcpip/network/neighbor.c b/reactos/drivers/net/tcpip/network/neighbor.c index eeca634a840..51e41f62639 100644 --- a/reactos/drivers/net/tcpip/network/neighbor.c +++ b/reactos/drivers/net/tcpip/network/neighbor.c @@ -110,7 +110,6 @@ VOID NBTimeout( for (NCE = NeighborCache[i].Cache; NCE != NULL; NCE = NCE->Next) { /* Check if event timer is running */ - ASSERT(NCE->EventTimer >= 0); if (NCE->EventTimer > 0) { NCE->EventTimer--; if (NCE->EventTimer == 0) { @@ -232,7 +231,7 @@ VOID NBSendSolicit( CurrentEntry = NCE->Interface->NTEListHead.Flink; NTE = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry); - ARPTransmit(NCE->Address, NTE); + ARPTransmit(&NCE->Address, NTE); } else { @@ -277,6 +276,8 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor( "LinkAddress (0x%X) LinkAddressLength (%d) State (0x%X)\n", Interface, Address, LinkAddress, LinkAddressLength, State)); + ASSERT(Address->Type == IP_ADDRESS_V4); + NCE = ExAllocatePool(NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength); if (NCE == NULL) { @@ -292,7 +293,7 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor( /* Reference once for beeing alive and once for the caller */ NCE->RefCount = 2; NCE->Interface = Interface; - NCE->Address = Address; + NCE->Address = *Address; NCE->LinkAddressLength = LinkAddressLength; NCE->LinkAddress = (PVOID)&NCE[1]; if (LinkAddress != NULL) @@ -390,7 +391,7 @@ PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor( NCE = NeighborCache[HashValue].Cache; - while ((NCE) && (!AddrIsEqual(Address, NCE->Address))) + while ((NCE) && (!AddrIsEqual(Address, &NCE->Address))) { NCE = NCE->Next; } @@ -431,7 +432,7 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor( { ReferenceObject(Address); NCE = NBAddNeighbor(Interface, Address, NULL, - Interface->AddressLength, NUD_INCOMPLETE); + Interface->AddressLength, NUD_INCOMPLETE); NCE->EventTimer = 1; NCE->EventCount = 0; } @@ -492,7 +493,7 @@ VOID NBRemoveNeighbor( TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE)); - HashValue = *(PULONG)(&NCE->Address->Address); + HashValue = *(PULONG)(&NCE->Address.Address); HashValue ^= HashValue >> 16; HashValue ^= HashValue >> 8; HashValue ^= HashValue >> 4; @@ -522,9 +523,6 @@ VOID NBRemoveNeighbor( /* Remove all references from route cache */ RouteInvalidateNCE(CurNCE); - /* Remove reference to the address */ - DereferenceObject(CurNCE->Address); - #ifdef DBG CurNCE->RefCount--; diff --git a/reactos/drivers/net/tcpip/network/receive.c b/reactos/drivers/net/tcpip/network/receive.c index 0d6bb629607..c8dba5c9d7e 100644 --- a/reactos/drivers/net/tcpip/network/receive.c +++ b/reactos/drivers/net/tcpip/network/receive.c @@ -12,7 +12,6 @@ #include "precomp.h" - LIST_ENTRY ReassemblyListHead; KSPIN_LOCK ReassemblyListLock; NPAGED_LOOKASIDE_LIST IPDRList; @@ -187,6 +186,8 @@ PIP_PACKET ReassembleDatagram( * The lock is held when this routine is called * RETURNS: * Pointer to IP packet, NULL if there was not enough free resources + * NOTES: + * At this point, header is expected to point to the IP header */ { PIP_PACKET IPPacket; @@ -199,7 +200,7 @@ PIP_PACKET ReassembleDatagram( TI_DbgPrint(DEBUG_IP, ("IPDR->DataSize = %d\n", IPDR->DataSize)); TI_DbgPrint(DEBUG_IP, ("Fragment header:\n")); - OskitDumpBuffer(IPDR->IPv4Header, IPDR->HeaderSize); + OskitDumpBuffer((PCHAR)IPDR->IPv4Header, IPDR->HeaderSize); /* FIXME: Assume IPv4 */ IPPacket = IPCreatePacket(IP_ADDRESS_V4); @@ -209,7 +210,7 @@ PIP_PACKET ReassembleDatagram( IPPacket->TotalSize = IPDR->HeaderSize + IPDR->DataSize; IPPacket->ContigSize = IPPacket->TotalSize; IPPacket->HeaderSize = IPDR->HeaderSize; - IPPacket->Position = IPDR->HeaderSize; + /*IPPacket->Position = IPDR->HeaderSize;*/ RtlCopyMemory(&IPPacket->SrcAddr, &IPDR->SrcAddr, sizeof(IP_ADDRESS)); RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS)); @@ -431,13 +432,14 @@ VOID ProcessFragment( return; } - TI_DbgPrint(DEBUG_IP, ("Fragment data buffer allocated at (0x%X) Size (%d).\n", - Fragment->Data, Fragment->Size)); - + /* Position here is an offset from the NdisPacket start, not the header */ + TI_DbgPrint(DEBUG_IP, ("Fragment data buffer allocated at (0x%X) Size (%d) Pos (%d).\n", + Fragment->Data, Fragment->Size, IPPacket->Position)); + /* Copy datagram data into fragment buffer */ CopyPacketToBuffer(Fragment->Data, IPPacket->NdisPacket, - IPPacket->Position + MaxLLHeaderSize, + IPPacket->Position, Fragment->Size); Fragment->Offset = FragFirst; @@ -472,7 +474,7 @@ VOID ProcessFragment( DISPLAY_IP_PACKET(Datagram); /* Give the packet to the protocol dispatcher */ - IPDispatchProtocol(IF, Datagram); + IPDispatchProtocol(NTE, Datagram); /* We're done with this datagram */ exFreePool(Datagram->Header); @@ -522,7 +524,7 @@ VOID IPDatagramReassemblyTimeout( { } -VOID IPv4Receive( PIP_INTERFACE IF, PIP_PACKET IPPacket) +VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket) /* * FUNCTION: Receives an IPv4 datagram (or fragment) * ARGUMENTS: @@ -563,10 +565,13 @@ VOID IPv4Receive( PIP_INTERFACE IF, PIP_PACKET IPPacket) AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr); AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr); - IPPacket->Position = IPPacket->HeaderSize; - IPPacket->Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize) + 14; /* XXX 14 */ + IPPacket->Position += IPPacket->HeaderSize; + IPPacket->Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize); - OskitDumpBuffer(IPPacket->Data - IPPacket->HeaderSize, IPPacket->TotalSize); + TI_DbgPrint(MID_TRACE,("IPPacket->Position = %d\n", + IPPacket->Position)); + + OskitDumpBuffer(IPPacket->Header, IPPacket->TotalSize); /* FIXME: Possibly forward packets with multicast addresses */ @@ -588,7 +593,7 @@ VOID IPv4Receive( PIP_INTERFACE IF, PIP_PACKET IPPacket) if (NCE) { /* FIXME: Possibly fragment datagram */ /* Forward the packet */ - IPSendFragment(IPPacket, NCE); + IPSendFragment(IPPacket->NdisPacket, NCE); } else { TI_DbgPrint(MIN_TRACE, ("No route to destination (0x%X).\n", IPPacket->DstAddr.Address.IPv4Address)); diff --git a/reactos/drivers/net/tcpip/network/route.c b/reactos/drivers/net/tcpip/network/route.c index 67830adcf55..5a5829db827 100644 --- a/reactos/drivers/net/tcpip/network/route.c +++ b/reactos/drivers/net/tcpip/network/route.c @@ -498,7 +498,7 @@ UINT RouteGetRouteToDestination( Destination, NTE)); TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NTE (%s).\n", - A2S(Destination), A2S(NTE->Address))); + A2S(Destination), NTE ? A2S(NTE->Address) : "")); KeAcquireSpinLock(&RouteCacheLock, &OldIrql); @@ -608,7 +608,9 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination( Destination, NTE, IF, NCE)); TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NTE (%s) NCE (%s).\n", - A2S(Destination), A2S(NTE->Address), A2S(NCE->Address))); + A2S(Destination), + A2S(NTE->Address), + A2S(&NCE->Address))); KeAcquireSpinLock(&RouteCacheLock, &OldIrql); @@ -722,10 +724,6 @@ VOID RouteInvalidateNCE( NTSTATUS RouteFriendlyAddRoute( PIPROUTE_ENTRY ire ) { - PNET_TABLE_ENTRY Nte; - PNEIGHBOR_CACHE_ENTRY Nce; - PIP_INTERFACE If; - IP_ADDRESS Dest; KIRQL OldIrql; diff --git a/reactos/drivers/net/tcpip/network/router.c b/reactos/drivers/net/tcpip/network/router.c index b77a4ae9f02..bc4c2113238 100644 --- a/reactos/drivers/net/tcpip/network/router.c +++ b/reactos/drivers/net/tcpip/network/router.c @@ -284,7 +284,7 @@ PIP_INTERFACE RouterFindOnLinkInterface( TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X) NTE (0x%X).\n", Address, NTE)); TI_DbgPrint(DEBUG_ROUTER, ("Address (%s) NTE (%s).\n", - A2S(Address), A2S(NTE->Address))); + A2S(Address), NTE ? A2S(NTE->Address) : "")); CurrentEntry = PrefixListHead.Flink; while (CurrentEntry != &PrefixListHead) { @@ -327,7 +327,9 @@ PFIB_ENTRY RouterAddRoute( "Router (0x%X) Metric (%d).\n", NetworkAddress, Netmask, Router, Metric)); TI_DbgPrint(DEBUG_ROUTER, ("NetworkAddress (%s) Netmask (%s) Router (%s).\n", - A2S(NetworkAddress), A2S(Netmask), A2S(Router->Address))); + A2S(NetworkAddress), + A2S(Netmask), + A2S(&Router->Address))); FIBE = ExAllocatePool(NonPagedPool, sizeof(FIB_ENTRY)); if (!FIBE) { @@ -391,7 +393,7 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute( if ((!NTE) || (NTE->Interface == NCE->Interface)) { if (Destination) - Length = CommonPrefixLength(Destination, NCE->Address); + Length = CommonPrefixLength(Destination, &NCE->Address); else Length = 0; diff --git a/reactos/drivers/net/tcpip/network/transmit.c b/reactos/drivers/net/tcpip/network/transmit.c index 81b44ed1f9e..2c2fd4e07c8 100644 --- a/reactos/drivers/net/tcpip/network/transmit.c +++ b/reactos/drivers/net/tcpip/network/transmit.c @@ -183,7 +183,7 @@ VOID IPSendComplete( /* FIXME: Stop sending fragments and cleanup datagram buffers if there was an error */ - if (PC(NdisPacket)->Complete) + if (PC(NdisPacket) && PC(NdisPacket)->Complete) /* This datagram was only one fragment long so call completion handler now */ (*PC(NdisPacket)->Complete)(PC(NdisPacket)->Context, NdisPacket, NdisStatus); else { @@ -230,6 +230,8 @@ NTSTATUS IPSendFragment( TI_DbgPrint(MAX_TRACE, ("NCE->State = %d.\n", NCE->State)); + PC(NdisPacket)->DLComplete = IPSendComplete; + switch (NCE->State) { case NUD_PERMANENT: /* Neighbor is always valid */ @@ -270,7 +272,6 @@ NTSTATUS IPSendFragment( return STATUS_SUCCESS; } - PC(NdisPacket)->DLComplete = IPSendComplete; (*NCE->Interface->Transmit)(NCE->Interface->Context, NdisPacket, MaxLLHeaderSize, @@ -303,7 +304,7 @@ NTSTATUS IPSendDatagram( TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) RCN (0x%X)\n", IPPacket, RCN)); DISPLAY_IP_PACKET(IPPacket); - OskitDumpBuffer( IPPacket->Header, IPPacket->TotalSize ); + /*OskitDumpBuffer( IPPacket->Header, IPPacket->TotalSize );*/ NCE = RCN->NCE; diff --git a/reactos/drivers/net/tcpip/tcpip/address.c b/reactos/drivers/net/tcpip/tcpip/address.c index ad589052afb..161ac21ee3c 100644 --- a/reactos/drivers/net/tcpip/tcpip/address.c +++ b/reactos/drivers/net/tcpip/tcpip/address.c @@ -10,6 +10,7 @@ #include "precomp.h" +extern int sprintf( char *out, const char *fmt, ... ); #ifdef DBG @@ -26,7 +27,6 @@ PCHAR A2S( */ { ULONG ip; - CHAR b[10]; PCHAR p; p = A2SStr; @@ -38,15 +38,19 @@ PCHAR A2S( } switch (Address->Type) { - case IP_ADDRESS_V4: - ip = DN2H(Address->Address.IPv4Address); - sprintf(p, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); - break; - - case IP_ADDRESS_V6: - /* FIXME: IPv6 is not supported */ - strcpy(p, "(IPv6 address not supported)"); - break; + case IP_ADDRESS_V4: + ip = DN2H(Address->Address.IPv4Address); + sprintf(p, "%d.%d.%d.%d", + (INT)((ip >> 24) & 0xFF), + (INT)((ip >> 16) & 0xFF), + (INT)((ip >> 8) & 0xFF), + (INT)(ip & 0xFF)); + break; + + case IP_ADDRESS_V6: + /* FIXME: IPv6 is not supported */ + strcpy(p, "(IPv6 address not supported)"); + break; } return p; } @@ -131,9 +135,8 @@ BOOLEAN AddrIsUnspecified( */ NTSTATUS AddrGetAddress( PTRANSPORT_ADDRESS AddrList, - PIP_ADDRESS *Address, - PUSHORT Port, - PIP_ADDRESS *Cache) + PIP_ADDRESS Address, + PUSHORT Port) { PTA_ADDRESS CurAddr; INT i; @@ -146,45 +149,14 @@ NTSTATUS AddrGetAddress( case TDI_ADDRESS_TYPE_IP: if (CurAddr->AddressLength >= TDI_ADDRESS_LENGTH_IP) { /* This is an IPv4 address */ - PIP_ADDRESS IPAddress; PTDI_ADDRESS_IP ValidAddr = (PTDI_ADDRESS_IP)CurAddr->Address; - *Port = ValidAddr->sin_port; - - if ((Cache) && (*Cache)) { - if (((*Cache)->Type == IP_ADDRESS_V4) && - ((*Cache)->Address.IPv4Address == ValidAddr->in_addr)) { - *Address = *Cache; - return STATUS_SUCCESS; - } else { - /* Release the cached address as we cannot use it this time */ - DereferenceObject(*Cache); - *Cache = NULL; - } - } - - IPAddress = ExAllocatePoolWithTag(NonPagedPool, - sizeof(IP_ADDRESS), - FOURCC('I','P','v','4')); - if (IPAddress) { - AddrInitIPv4(IPAddress, ValidAddr->in_addr); - *Address = IPAddress; - - /* Update address cache */ - if (Cache) { - *Cache = IPAddress; - ReferenceObject(*Cache); - } - return STATUS_SUCCESS; - } else - return STATUS_INSUFFICIENT_RESOURCES; - } else - return STATUS_INVALID_ADDRESS; - default: - /* This is an unsupported address type. - Skip it and go to the next in the list */ - CurAddr = (PTA_ADDRESS)((ULONG_PTR)CurAddr->Address + CurAddr->AddressLength); - } + Address->Type = CurAddr->AddressType; + ValidAddr = (PTDI_ADDRESS_IP)CurAddr->Address; + AddrInitIPv4(Address, ValidAddr->in_addr); + return STATUS_SUCCESS; + } + } } return STATUS_INVALID_ADDRESS; @@ -208,9 +180,6 @@ NTSTATUS AddrBuildAddress( PTDI_ADDRESS_IP ValidAddr; PIP_ADDRESS IPAddress; - TI_DbgPrint(MID_TRACE,("Address in:\n")); - OskitDumpBuffer( TdiAddress, sizeof(*TdiAddress) ); - if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP) { TI_DbgPrint (MID_TRACE,("AddressType %x, Not valid\n", @@ -235,9 +204,6 @@ NTSTATUS AddrBuildAddress( *Address = IPAddress; *Port = ValidAddr->sin_port; - TI_DbgPrint(MID_TRACE,("Address out:\n")); - OskitDumpBuffer( IPAddress, sizeof(*IPAddress) ); - return STATUS_SUCCESS; } diff --git a/reactos/drivers/net/tcpip/tcpip/dispatch.c b/reactos/drivers/net/tcpip/tcpip/dispatch.c index 9662b261e89..92113d477fc 100644 --- a/reactos/drivers/net/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/net/tcpip/tcpip/dispatch.c @@ -11,7 +11,6 @@ #include "precomp.h" - NTSTATUS DispPrepareIrpForCancel( PTRANSPORT_CONTEXT Context, PIRP Irp, @@ -256,7 +255,7 @@ NTSTATUS DispTdiAssociateAddress( PIO_STACK_LOCATION IrpSp; PCONNECTION_ENDPOINT Connection; PFILE_OBJECT FileObject; - PADDRESS_FILE AddrFile; + PADDRESS_FILE AddrFile = NULL; NTSTATUS Status; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -315,11 +314,10 @@ NTSTATUS DispTdiAssociateAddress( AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; if (!AddrFile) { - ObDereferenceObject(FileObject); - TI_DbgPrint(MID_TRACE, ("No address file object.\n")); - return STATUS_INVALID_PARAMETER; + ObDereferenceObject(FileObject); + TI_DbgPrint(MID_TRACE, ("No address file object.\n")); + return STATUS_INVALID_PARAMETER; } - /* The connection endpoint references the address file object */ ReferenceObject(AddrFile); Connection->AddressFile = AddrFile; @@ -330,7 +328,7 @@ NTSTATUS DispTdiAssociateAddress( /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */ ObDereferenceObject(FileObject); - return STATUS_SUCCESS; + return Status; } @@ -376,12 +374,21 @@ NTSTATUS DispTdiConnect( Request.RequestNotifyObject = DispDataRequestComplete; Request.RequestContext = Irp; - /* XXX Handle connected UDP, etc... */ - Status = TCPConnect( - &Request, - Parameters->RequestConnectionInformation, - Parameters->ReturnConnectionInformation); +#if 0 + Status = TCPBind( Connection, + &Connection->SocketContext, + Parameters->RequestConnectionInformation ); + + TI_DbgPrint(MID_TRACE, ("TCP Bind returned %08x\n", Status)); + + if( NT_SUCCESS(Status) ) +#endif + Status = TCPConnect( + &Request, + Parameters->RequestConnectionInformation, + Parameters->ReturnConnectionInformation); + TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status)); return Status; @@ -532,7 +539,6 @@ NTSTATUS DispTdiListen( PIO_STACK_LOCATION IrpSp; PTDI_REQUEST Request; NTSTATUS Status; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index 436834153d4..ddeda9e8bcd 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -134,8 +134,6 @@ VOID DeleteConnectionEndpoint( PCONNECTION_ENDPOINT Connection) { KIRQL OldIrql; - PLIST_ENTRY CurrentEntry; - PLIST_ENTRY NextEntry; TI_DbgPrint(MID_TRACE, ("Called.\n")); @@ -304,7 +302,7 @@ NTSTATUS FileOpenAddress( case IPPROTO_TCP: /* FIXME: If specified port is 0, a port is chosen dynamically */ AddrFile->Port = Address->Address[0].Address[0].sin_port; - AddrFile->Send = TCPSendData; + AddrFile->Send = NULL; /* TCPSendData */ break; case IPPROTO_UDP: @@ -434,7 +432,6 @@ NTSTATUS FileOpenConnection( { NTSTATUS Status; PCONNECTION_ENDPOINT Connection; - PADDRESS_FILE AddrFile; TI_DbgPrint(MID_TRACE, ("Called.\n")); @@ -463,7 +460,7 @@ NTSTATUS FileOpenConnection( SOCK_STREAM, IPPROTO_TCP ); DbgPrint("STATUS from OSKITTCP was %08x\n", Status); - + /* Initialize received segments queue */ InitializeListHead(&Connection->ReceivedSegments); @@ -497,7 +494,6 @@ TI_DbgPrint(MIN_TRACE, ("X1 Blink 0x%x\n", Connection->ReceivedSegments.Blink)); NTSTATUS FileCloseConnection( PTDI_REQUEST Request) { - KIRQL OldIrql; PCONNECTION_ENDPOINT Connection; NTSTATUS Status = STATUS_SUCCESS; @@ -569,7 +565,6 @@ NTSTATUS FileCloseControlChannel( PTDI_REQUEST Request) { PCONTROL_CHANNEL ControlChannel = Request->Handle.ControlChannel; - KIRQL OldIrql; NTSTATUS Status = STATUS_SUCCESS; ExFreePool(ControlChannel); diff --git a/reactos/drivers/net/tcpip/tcpip/iinfo.c b/reactos/drivers/net/tcpip/tcpip/iinfo.c index c621da7e569..ac62a7243ed 100644 --- a/reactos/drivers/net/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/net/tcpip/tcpip/iinfo.c @@ -10,7 +10,6 @@ #include "precomp.h" - TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID, PIP_INTERFACE Interface, PNDIS_BUFFER Buffer, @@ -19,7 +18,6 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID, PIFENTRY OutData; PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context; PCHAR IFDescr; - KIRQL OldIrql; ULONG Size; UINT DescrLenMax = MAX_IFDESCR_LEN - 1; @@ -48,7 +46,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID, IFDescr = (PCHAR)&OutData[1]; if( IF ) { - GetInterfaceSpeed( Interface, &OutData->Speed ); + GetInterfaceSpeed( Interface, (PUINT)&OutData->Speed ); TI_DbgPrint(MAX_TRACE, ("IF Speed = %d * 100bps\n", OutData->Speed)); memcpy(OutData->PhysAddr,Interface->Address,Interface->AddressLength); @@ -67,7 +65,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID, TI_DbgPrint(MAX_TRACE, ("Finished IFEntry MIB (%04x:%d) size %d\n", ID->tei_entity, ID->tei_instance, Size)); - Status = InfoCopyOut( OutData, Size, Buffer, BufferSize ); + Status = InfoCopyOut( (PCHAR)OutData, Size, Buffer, BufferSize ); ExFreePool( OutData ); return Status; @@ -84,7 +82,7 @@ TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass, InfoType == INFO_TYPE_PROVIDER && InfoId == ENTITY_TYPE_ID ) { ULONG Temp = IF_MIB; - return InfoCopyOut( &Temp, sizeof(Temp), Buffer, BufferSize ); + return InfoCopyOut( (PCHAR)&Temp, sizeof(Temp), Buffer, BufferSize ); } else if( InfoClass == INFO_CLASS_PROTOCOL && InfoType == INFO_TYPE_PROVIDER && InfoId == IF_MIB_STATS_ID ) { diff --git a/reactos/drivers/net/tcpip/tcpip/info.c b/reactos/drivers/net/tcpip/tcpip/info.c index b66dbccea66..a5bb9106424 100644 --- a/reactos/drivers/net/tcpip/tcpip/info.c +++ b/reactos/drivers/net/tcpip/tcpip/info.c @@ -10,6 +10,7 @@ #include "precomp.h" #include +#include TDI_STATUS InfoCopyOut( PCHAR DataOut, UINT SizeOut, PNDIS_BUFFER ClientBuf, PUINT ClientBufSize ) { @@ -54,7 +55,7 @@ VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) { VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) { KIRQL OldIrql; - UINT Count = 0, i; + UINT i; KeAcquireSpinLock( &EntityListLock, &OldIrql ); @@ -78,8 +79,6 @@ TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer, { UINT Count, Size, BufSize = *BufferSize; KIRQL OldIrql; - TDIEntityID *EntityOutList; - PLIST_ENTRY CurrentIFEntry; TI_DbgPrint(MAX_TRACE,("About to copy %d TDIEntityIDs to user\n", EntityCount)); @@ -132,7 +131,6 @@ TDI_STATUS InfoTdiQueryInformationEx( UINT i; PVOID context; NTSTATUS Status = STATUS_SUCCESS; - TDIEntityID EntityId; BOOL FoundEntity = FALSE; InfoRequest_f InfoRequest; diff --git a/reactos/drivers/net/tcpip/tcpip/irp.c b/reactos/drivers/net/tcpip/tcpip/irp.c index e05bfddcde5..e6a93677300 100644 --- a/reactos/drivers/net/tcpip/tcpip/irp.c +++ b/reactos/drivers/net/tcpip/tcpip/irp.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS TCP/IP protocol driver * FILE: tcpip/dispatch.h * PURPOSE: TDI dispatch routines - * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * PROGRAMMERS: arty * REVISIONS: * CSH 01/08-2000 Created * TODO: Validate device object in all dispatch routines diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index e9a5da0e9ca..54a3aaee1ff 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -7,11 +7,9 @@ * REVISIONS: * CSH 01/08-2000 Created */ - #include "precomp.h" - -#define NDEBUG +//#define NDEBUG #ifndef NDEBUG DWORD DebugTraceLevel = 0x7fffffff; @@ -707,7 +705,6 @@ DriverEntry( UNICODE_STRING strDeviceName; UNICODE_STRING strNdisDeviceName; NDIS_STATUS NdisStatus; - NDIS_STRING DeviceName; TI_DbgPrint(MAX_TRACE, ("Called.\n")); @@ -717,8 +714,6 @@ DriverEntry( TrackTag(FBSD_MALLOC); TrackTag(EXALLOC_TAG); - InitOskitTCP(); - /* TdiInitialize() ? */ /* FIXME: Create symbolic links in Win32 namespace */ diff --git a/reactos/drivers/net/tcpip/tcpip/ninfo.c b/reactos/drivers/net/tcpip/tcpip/ninfo.c index c66a173a799..58393b8d8a1 100644 --- a/reactos/drivers/net/tcpip/tcpip/ninfo.c +++ b/reactos/drivers/net/tcpip/tcpip/ninfo.c @@ -10,7 +10,6 @@ #include "precomp.h" - TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) { @@ -49,7 +48,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer, KeReleaseSpinLock(&InterfaceListLock, OldIrql); - Status = InfoCopyOut( IpAddress, sizeof(*IpAddress) * Count, + Status = InfoCopyOut( (PCHAR)IpAddress, sizeof(*IpAddress) * Count, Buffer, BufferSize ); ExFreePool( IpAddress ); @@ -61,8 +60,6 @@ TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer, /* Get IPRouteEntry s for each of the routes in the system */ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) { - PIP_INTERFACE CurrentIF; - PLIST_ENTRY CurrentIFEntry; TDI_STATUS Status; KIRQL OldIrql; UINT RtCount = CountFIBs(), @@ -89,12 +86,12 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) { while( RtCurrent < RouteEntries + RtCount ) { /* Copy Desitnation */ if( RCacheCur->NetworkAddress && RCacheCur->Netmask && - RCacheCur->Router && RCacheCur->Router->Address ) { + RCacheCur->Router ) { TI_DbgPrint(MAX_TRACE, ("%d: NA %08x NM %08x GW %08x MT %d\n", RtCurrent - RouteEntries, RCacheCur->NetworkAddress->Address, RCacheCur->Netmask->Address, - RCacheCur->Router->Address->Address, + RCacheCur->Router->Address.Address, RCacheCur->Metric)); RtlCopyMemory( &RtCurrent->Dest, @@ -106,7 +103,7 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) { /* Currently, this address is stuffed into the pointer. * That probably is not intended. */ RtlCopyMemory( &RtCurrent->Gw, - &RCacheCur->Router->Address->Address, + &RCacheCur->Router->Address.Address, sizeof(RtCurrent->Gw) ); RtCurrent->Metric1 = RCacheCur->Metric; RtCurrent->Type = 2 /* PF_INET */; @@ -126,13 +123,13 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) { RCacheCur->Netmask, RCacheCur->Router, RCacheCur->Router ? - RCacheCur->Router->Address : 0, + &RCacheCur->Router->Address : 0, RCacheCur->Metric)); } RtCurrent++; RCacheCur++; } - Status = InfoCopyOut( RouteEntries, Size, Buffer, BufferSize ); + Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize ); ExFreePool( RouteEntries ); ExFreePool( RCache ); @@ -171,7 +168,7 @@ TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer, SnmpInfo.NumAddr = AddrCount; SnmpInfo.NumRoutes = RouteCount; - Status = InfoCopyOut( &SnmpInfo, sizeof(SnmpInfo), + Status = InfoCopyOut( (PCHAR)&SnmpInfo, sizeof(SnmpInfo), Buffer, BufferSize ); TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status)); @@ -194,7 +191,7 @@ TDI_STATUS InfoNetworkLayerTdiQueryEx( UINT InfoClass, case INFO_CLASS_GENERIC: if( InfoType == INFO_TYPE_PROVIDER && InfoId == ENTITY_TYPE_ID ) { ULONG Return = CL_NL_IP; - Status = InfoCopyOut( &Return, sizeof(Return), + Status = InfoCopyOut( (PCHAR)&Return, sizeof(Return), Buffer, BufferSize ); } break; @@ -231,4 +228,6 @@ TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass, TDIEntityID *id, PCHAR Buffer, UINT BufferSize ) { + TDI_STATUS Status = TDI_INVALID_REQUEST; + return Status; } diff --git a/reactos/drivers/net/tcpip/tcpip/routines.c b/reactos/drivers/net/tcpip/tcpip/routines.c index 986d2262806..340782e2be1 100644 --- a/reactos/drivers/net/tcpip/tcpip/routines.c +++ b/reactos/drivers/net/tcpip/tcpip/routines.c @@ -10,7 +10,6 @@ #include "precomp.h" - static UINT RandomNumber = 0x12345678; @@ -31,7 +30,7 @@ UINT Random( __inline INT SkipToOffset( PNDIS_BUFFER Buffer, UINT Offset, - PUCHAR *Data, + PCHAR *Data, PUINT Size) /* * FUNCTION: Skip Offset bytes into a buffer chain @@ -56,7 +55,7 @@ __inline INT SkipToOffset( NdisQueryBuffer(Buffer, (PVOID)Data, Size); if (Offset < *Size) { - *Data = (PUCHAR)((ULONG_PTR) *Data + Offset); + *Data = (PCHAR)((ULONG_PTR) *Data + Offset); *Size -= Offset; break; } @@ -73,7 +72,7 @@ __inline INT SkipToOffset( UINT CopyBufferToBufferChain( PNDIS_BUFFER DstBuffer, UINT DstOffset, - PUCHAR SrcData, + PCHAR SrcData, UINT Length) /* * FUNCTION: Copies data from a buffer to an NDIS buffer chain @@ -90,9 +89,9 @@ UINT CopyBufferToBufferChain( */ { UINT BytesCopied, BytesToCopy, DstSize; - PUCHAR DstData; + PCHAR DstData; - TI_DbgPrint(DEBUG_BUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcData, Length)); + TI_DbgPrint(DEBUG_PBUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcData, Length)); /* Skip DstOffset bytes in the destination buffer chain */ if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1) @@ -105,7 +104,7 @@ UINT CopyBufferToBufferChain( RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy); BytesCopied += BytesToCopy; - SrcData = (PUCHAR)((ULONG_PTR)SrcData + BytesToCopy); + SrcData = (PCHAR)((ULONG_PTR)SrcData + BytesToCopy); Length -= BytesToCopy; if (Length == 0) @@ -128,7 +127,7 @@ UINT CopyBufferToBufferChain( UINT CopyBufferChainToBuffer( - PUCHAR DstData, + PCHAR DstData, PNDIS_BUFFER SrcBuffer, UINT SrcOffset, UINT Length) @@ -147,9 +146,9 @@ UINT CopyBufferChainToBuffer( */ { UINT BytesCopied, BytesToCopy, SrcSize; - PUCHAR SrcData; + PCHAR SrcData; - TI_DbgPrint(DEBUG_BUFFER, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData,SrcBuffer, SrcOffset, Length)); + TI_DbgPrint(DEBUG_PBUFFER, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData,SrcBuffer, SrcOffset, Length)); /* Skip SrcOffset bytes in the source buffer chain */ if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1) @@ -160,11 +159,11 @@ UINT CopyBufferChainToBuffer( for (;;) { BytesToCopy = MIN(SrcSize, Length); - TI_DbgPrint(DEBUG_BUFFER, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData)); + TI_DbgPrint(DEBUG_PBUFFER, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData)); RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy); BytesCopied += BytesToCopy; - DstData = (PUCHAR)((ULONG_PTR)DstData + BytesToCopy); + DstData = (PCHAR)((ULONG_PTR)DstData + BytesToCopy); Length -= BytesToCopy; if (Length == 0) @@ -187,7 +186,7 @@ UINT CopyBufferChainToBuffer( UINT CopyPacketToBuffer( - PUCHAR DstData, + PCHAR DstData, PNDIS_PACKET SrcPacket, UINT SrcOffset, UINT Length) @@ -210,7 +209,7 @@ UINT CopyPacketToBuffer( UINT FirstLength; UINT TotalLength; - TI_DbgPrint(DEBUG_BUFFER, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData, SrcPacket, SrcOffset, Length)); + TI_DbgPrint(DEBUG_PBUFFER, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData, SrcPacket, SrcOffset, Length)); NdisGetFirstBufferFromPacket(SrcPacket, &FirstBuffer, @@ -244,11 +243,11 @@ UINT CopyPacketToBufferChain( */ { PNDIS_BUFFER SrcBuffer; - PUCHAR DstData, SrcData; + PCHAR DstData, SrcData; UINT DstSize, SrcSize; UINT Count, Total; - TI_DbgPrint(DEBUG_BUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length)); + TI_DbgPrint(DEBUG_PBUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length)); /* Skip DstOffset bytes in the destination buffer chain */ NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); @@ -321,7 +320,7 @@ PVOID AdjustPacket( PNDIS_BUFFER NdisBuffer; INT Adjust; - TI_DbgPrint(DEBUG_BUFFER, ("Available = %d, Needed = %d.\n", Available, Needed)); + TI_DbgPrint(DEBUG_PBUFFER, ("Available = %d, Needed = %d.\n", Available, Needed)); Adjust = Available - Needed; @@ -367,7 +366,7 @@ UINT ResizePacket( #ifdef DBG static VOID DisplayIPHeader( - PUCHAR Header, + PCHAR Header, UINT Length) { /* FIXME: IPv4 only */ @@ -396,14 +395,13 @@ static VOID DisplayIPHeader( VOID DisplayIPPacket( PIP_PACKET IPPacket) { - UINT i; PCHAR p; UINT Length; PNDIS_BUFFER Buffer; PNDIS_BUFFER NextBuffer; - PUCHAR CharBuffer; + PCHAR CharBuffer; - if ((DebugTraceLevel & (DEBUG_BUFFER | DEBUG_IP)) != (DEBUG_BUFFER | DEBUG_IP)) { + if ((DebugTraceLevel & (DEBUG_PBUFFER | DEBUG_IP)) != (DEBUG_PBUFFER | DEBUG_IP)) { return; } @@ -448,7 +446,7 @@ VOID DisplayIPPacket( static VOID DisplayTCPHeader( - PUCHAR Header, + PCHAR Header, UINT Length) { /* FIXME: IPv4 only */ @@ -460,7 +458,7 @@ static VOID DisplayTCPHeader( return; } - TCPHeader = (PTCPv4_HEADER)((PUCHAR)IPHeader + (IPHeader->VerIHL & 0x0F) * 4); + TCPHeader = (PTCPv4_HEADER)((PCHAR)IPHeader + (IPHeader->VerIHL & 0x0F) * 4); DbgPrint("TCP header:\n"); DbgPrint(" SourcePort: %d\n", WN2H(TCPHeader->SourcePort)); @@ -485,9 +483,9 @@ VOID DisplayTCPPacket( PIP_PACKET IPPacket) { UINT Length; - PUCHAR Buffer; + PCHAR Buffer; - if ((DebugTraceLevel & (DEBUG_BUFFER | DEBUG_TCP)) != (DEBUG_BUFFER | DEBUG_TCP)) { + if ((DebugTraceLevel & (DEBUG_PBUFFER | DEBUG_TCP)) != (DEBUG_PBUFFER | DEBUG_TCP)) { return; } @@ -519,16 +517,16 @@ VOID DisplayTCPPacket( } } -#endif DBG /* DBG */ +#endif/* DBG */ void GetDataPtr( PNDIS_PACKET Packet, UINT Offset, - PUCHAR *DataOut, + PCHAR *DataOut, PUINT Size ) { PNDIS_BUFFER Buffer; NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL); - if( !Buffer ) return NULL; + if( !Buffer ) return; SkipToOffset( Buffer, Offset, DataOut, Size ); } @@ -586,7 +584,7 @@ VOID FreeNdisPacketX { PNDIS_BUFFER Buffer, NextBuffer; - TI_DbgPrint(DEBUG_BUFFER, ("Packet (0x%X)\n", Packet)); + TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet)); /* Free all the buffers in the packet first */ NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL); diff --git a/reactos/drivers/net/tcpip/tcpip/tinfo.c b/reactos/drivers/net/tcpip/tcpip/tinfo.c index a4261ac81e5..84435cef196 100644 --- a/reactos/drivers/net/tcpip/tcpip/tinfo.c +++ b/reactos/drivers/net/tcpip/tcpip/tinfo.c @@ -10,7 +10,6 @@ #include "precomp.h" - TDI_STATUS InfoTransportLayerTdiQueryEx( UINT InfoClass, UINT InfoType, UINT InfoId, @@ -22,7 +21,7 @@ TDI_STATUS InfoTransportLayerTdiQueryEx( UINT InfoClass, InfoType == INFO_TYPE_PROVIDER && InfoId == ENTITY_TYPE_ID ) { ULONG Temp = CL_TL_UDP; - return InfoCopyOut( &Temp, sizeof(Temp), Buffer, BufferSize ); + return InfoCopyOut( (PCHAR)&Temp, sizeof(Temp), Buffer, BufferSize ); } return TDI_INVALID_REQUEST; @@ -35,4 +34,5 @@ TDI_STATUS InfoTransportLayerTdiSetEx( UINT InfoClass, TDIEntityID *id, PCHAR Buffer, UINT BufferSize ) { + return TDI_INVALID_REQUEST; } diff --git a/reactos/drivers/net/tcpip/transport/datagram/datagram.c b/reactos/drivers/net/tcpip/transport/datagram/datagram.c index c6c313bf986..2223a39e88f 100644 --- a/reactos/drivers/net/tcpip/transport/datagram/datagram.c +++ b/reactos/drivers/net/tcpip/transport/datagram/datagram.c @@ -107,7 +107,6 @@ VOID SendDatagramComplete( KIRQL OldIrql; ULONG BytesSent; PVOID CompleteContext; - PNDIS_BUFFER NdisBuffer; PDATAGRAM_SEND_REQUEST SendRequest; DATAGRAM_COMPLETION_ROUTINE Complete; BOOLEAN QueueWorkItem; @@ -295,9 +294,7 @@ VOID DGDeliverData( while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) { Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); - if (!Current->RemoteAddress) - Found = TRUE; - else if (AddrIsEqual(Address, Current->RemoteAddress)) + if (AddrIsEqual(Address, &Current->RemoteAddress)) Found = TRUE; if (Found) @@ -329,11 +326,6 @@ VOID DGDeliverData( /* Complete the receive request */ (*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize); - /* Finally free the receive request */ - if (Current->RemoteAddress) - { - DereferenceObject(Current->RemoteAddress); - } exFreePool(Current); } } @@ -470,12 +462,6 @@ VOID DGCancelReceiveRequest( /* Complete the request and free its resources */ (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0); - /* Remote address can be NULL if the caller wants to receive - packets sent from any address */ - if (Current->RemoteAddress) - { - DereferenceObject(Current->RemoteAddress); - } exFreePool(Current); } else @@ -562,8 +548,7 @@ NTSTATUS DGSendDatagram( PTDI_REQUEST Request, if (NT_SUCCESS(Status)) { Status = AddrGetAddress(ConnInfo->RemoteAddress, &SendRequest->RemoteAddress, - &SendRequest->RemotePort, - &AddrFile->AddrCache); + &SendRequest->RemotePort); if (NT_SUCCESS(Status)) { KeReleaseSpinLock(&AddrFile->Lock, OldIrql); @@ -638,9 +623,8 @@ NTSTATUS DGReceiveDatagram( if (((ConnInfo->RemoteAddressLength != 0)) && (ConnInfo->RemoteAddress)) { Status = AddrGetAddress(ConnInfo->RemoteAddress, - &ReceiveRequest->RemoteAddress, - &ReceiveRequest->RemotePort, - &AddrFile->AddrCache); + &ReceiveRequest->RemoteAddress, + &ReceiveRequest->RemotePort); if (!NT_SUCCESS(Status)) { KeReleaseSpinLock(&AddrFile->Lock, OldIrql); @@ -651,7 +635,6 @@ NTSTATUS DGReceiveDatagram( else { ReceiveRequest->RemotePort = 0; - ReceiveRequest->RemoteAddress = NULL; } ReceiveRequest->ReturnInfo = ReturnInfo; ReceiveRequest->Buffer = Buffer; diff --git a/reactos/drivers/net/tcpip/transport/tcp/event.c b/reactos/drivers/net/tcpip/transport/tcp/event.c index 0531eccced3..9ea18d48ba1 100644 --- a/reactos/drivers/net/tcpip/transport/tcp/event.c +++ b/reactos/drivers/net/tcpip/transport/tcp/event.c @@ -10,7 +10,6 @@ #include "precomp.h" - extern ULONG TCP_IPIdentification; typedef VOID @@ -103,172 +102,74 @@ int TCPSocketState(void *ClientData, } void TCPPacketSendComplete( PVOID Context, - NDIS_STATUS NdisStatus, - DWORD BytesSent ) { + PNDIS_PACKET NdisPacket, + NDIS_STATUS NdisStatus ) { TI_DbgPrint(MID_TRACE,("called\n")); - PDATAGRAM_SEND_REQUEST Send = (PDATAGRAM_SEND_REQUEST)Context; - if( Send->Packet.NdisPacket ) - FreeNdisPacket( Send->Packet.NdisPacket ); - exFreePool( Send ); + /* FreeNdisPacket( NdisPacket ); */ } -NTSTATUS AddHeaderIPv4( - PDATAGRAM_SEND_REQUEST SendRequest, - PIP_ADDRESS LocalAddress, - USHORT LocalPort, - PIP_ADDRESS RemoteAddress, - USHORT RemotePort) { -/* - * FUNCTION: Adds an IPv4 and TCP header to an IP packet - * ARGUMENTS: - * SendRequest = Pointer to send request - * Connection = Pointer to connection endpoint - * LocalAddress = Pointer to our local address - * LocalPort = The port we send this segment from - * IPPacket = Pointer to IP packet - * RETURNS: - * Status of operation - */ - PIPv4_HEADER IPHeader; - PIP_PACKET IPPacket; - PVOID Header; - NDIS_STATUS NdisStatus; - PNDIS_BUFFER HeaderBuffer; - PCHAR BufferContent; - ULONG BufferSize; - ULONG PayloadBufferSize; - - IPPacket = &SendRequest->Packet; +#define STRINGIFY(x) #x - BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER); - Header = exAllocatePool(NonPagedPool, BufferSize); - if (!Header) - return STATUS_INSUFFICIENT_RESOURCES; - - TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n", BufferSize, Header)); - - NdisQueryPacketLength( IPPacket->NdisPacket, &PayloadBufferSize ); - - /* Allocate NDIS buffer for maximum Link level, IP and TCP header */ - NdisAllocateBuffer(&NdisStatus, - &HeaderBuffer, - GlobalBufferPool, - Header, - BufferSize); - if (NdisStatus != NDIS_STATUS_SUCCESS) { - exFreePool(Header); - TI_DbgPrint(MAX_TRACE, ("Error from NDIS: %08x\n", NdisStatus)); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Chain header at front of NDIS packet */ - NdisChainBufferAtFront(IPPacket->NdisPacket, HeaderBuffer); - IPPacket->HeaderSize = 20; - IPPacket->ContigSize = BufferSize; - IPPacket->TotalSize = IPPacket->HeaderSize + PayloadBufferSize; - IPPacket->Header = (PVOID)((ULONG_PTR)Header + MaxLLHeaderSize); - IPPacket->Flags = 0; - - /* Build IPv4 header */ - IPHeader = (PIPv4_HEADER)IPPacket->Header; - /* Version = 4, Length = 5 DWORDs */ - IPHeader->VerIHL = 0x45; - /* Normal Type-of-Service */ - IPHeader->Tos = 0; - /* Length of header and data */ - IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize); - /* Identification */ - IPHeader->Id = WH2N((USHORT)InterlockedIncrement(&TCP_IPIdentification)); - /* One fragment at offset 0 */ - IPHeader->FlagsFragOfs = WH2N((USHORT)IPv4_DF_MASK); - /* Time-to-Live is 128 */ - IPHeader->Ttl = 128; - /* Transmission Control Protocol */ - IPHeader->Protocol = IPPROTO_TCP; - /* Checksum is 0 (for later calculation of this) */ - IPHeader->Checksum = 0; - /* Source address */ - IPHeader->SrcAddr = LocalAddress->Address.IPv4Address; - /* Destination address. FIXME: IPv4 only */ - IPHeader->DstAddr = RemoteAddress->Address.IPv4Address; - - return STATUS_SUCCESS; -} - -int TCPPacketSend(void *ClientData, - void *WhichSocket, - void *WhichConnection, - OSK_PCHAR data, - OSK_UINT len ) { - PADDRESS_FILE AddrFile; - PNDIS_BUFFER NdisPacket; +int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { + NTSTATUS Status; NDIS_STATUS NdisStatus; KIRQL OldIrql; - PDATAGRAM_SEND_REQUEST SendRequest; - PNEIGHBOR_CACHE_ENTRY NCE = 0; - PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)WhichConnection; + ROUTE_CACHE_NODE *RCN; + IP_PACKET Packet = { 0 }; IP_ADDRESS RemoteAddress, LocalAddress; - USHORT RemotePort, LocalPort; - PULONG AckNumber = (PULONG)data; + PIPv4_HEADER Header; - TI_DbgPrint(MID_TRACE,("TCP OUTPUT:\n")); + TI_DbgPrint(MID_TRACE,("TCP OUTPUT (%x:%d):\n", data, len)); OskitDumpBuffer( data, len ); - SendRequest = - (PDATAGRAM_SEND_REQUEST) - exAllocatePool( NonPagedPool, sizeof( DATAGRAM_SEND_REQUEST ) ); - /* if( !SendRequest || !Connection ) return OSK_EINVAL; */ + if( *data == 0x45 ) { /* IPv4 */ + Header = (PIPv4_HEADER)data; + LocalAddress.Type = IP_ADDRESS_V4; + LocalAddress.Address.IPv4Address = Header->SrcAddr; + RemoteAddress.Type = IP_ADDRESS_V4; + RemoteAddress.Address.IPv4Address = Header->DstAddr; + } else { + DbgPrint("Don't currently handle IPv6\n"); + KeBugCheck(4); + } RemoteAddress.Type = LocalAddress.Type = IP_ADDRESS_V4; - OskitTCPGetAddress( WhichSocket, - &LocalAddress.Address.IPv4Address, - &LocalPort, - &RemoteAddress.Address.IPv4Address, - &RemotePort ); - - DbgPrint("OSKIT SENDING PACKET *** %x:%d -> %x:%d\n", + DbgPrint("OSKIT SENDING PACKET *** %x -> %x\n", LocalAddress.Address.IPv4Address, - LocalPort, - RemoteAddress.Address.IPv4Address, - RemotePort); + RemoteAddress.Address.IPv4Address); + + ASSERT( (LocalAddress.Address.IPv4Address & 0xc0000000) != 0xc0000000 ); + - NCE = RouterGetRoute( &RemoteAddress, NULL ); - - if( !NCE ) return OSK_EADDRNOTAVAIL; - - GetInterfaceIPv4Address(NCE->Interface, - ADE_UNICAST, - &LocalAddress.Address.IPv4Address ); + Status = RouteGetRouteToDestination( &RemoteAddress, + NULL, + &RCN ); + + if( !NT_SUCCESS(Status) || !RCN ) return OSK_EADDRNOTAVAIL; KeRaiseIrql( DISPATCH_LEVEL, &OldIrql ); NdisStatus = - AllocatePacketWithBuffer( &SendRequest->PacketToSend, data, len ); + AllocatePacketWithBuffer( &Packet.NdisPacket, data, len ); + if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MAX_TRACE, ("Error from NDIS: %08x\n", NdisStatus)); goto end; } - SendRequest->Packet.NdisPacket = SendRequest->PacketToSend; + AdjustPacket( Packet.NdisPacket, 0, MaxLLHeaderSize ); + GetDataPtr( Packet.NdisPacket, 0, (PCHAR *)&Packet.Header, &Packet.ContigSize ); + TI_DbgPrint(MAX_TRACE,("PC(Packet.NdisPacket) is %s (%x)\n", STRINGIFY(PC(Packet.NdisPacket)), PC(Packet.NdisPacket))); + PC(Packet.NdisPacket)->Complete = TCPPacketSendComplete; + OskitDumpBuffer((PCHAR)(PC(Packet.NdisPacket)),sizeof(*(PC(Packet.NdisPacket)))); - SendRequest->Complete = TCPPacketSendComplete; - SendRequest->Context = Connection; - SendRequest->RemoteAddress = RemoteAddress; - SendRequest->RemotePort = RemotePort; - NdisQueryPacketLength( SendRequest->Packet.NdisPacket, - &SendRequest->BufferSize ); + Packet.HeaderSize = sizeof(IPv4_HEADER); + Packet.TotalSize = len; + Packet.SrcAddr = LocalAddress; + Packet.DstAddr = RemoteAddress; - AddHeaderIPv4( SendRequest, - &LocalAddress, - LocalPort, - &RemoteAddress, - RemotePort ); - - if( Connection ) - DGTransmit( Connection->AddressFile, SendRequest ); - else - DbgPrint("Transmit called without connection.\n"); + IPSendFragment( Packet.NdisPacket, RCN->NCE ); end: KeLowerIrql( OldIrql ); diff --git a/reactos/drivers/net/tcpip/transport/tcp/if.c b/reactos/drivers/net/tcpip/transport/tcp/if.c index 2152882728a..a13070de911 100644 --- a/reactos/drivers/net/tcpip/transport/tcp/if.c +++ b/reactos/drivers/net/tcpip/transport/tcp/if.c @@ -37,135 +37,75 @@ struct ifnet *ifnet; * Routines with ifa_ifwith* names take sockaddr *'s as * parameters. */ -void -ifinit() -{ + +PVOID TCPPrepareInterface( PIP_INTERFACE IF ) { + NTSTATUS Status; + POSK_IFADDR ifaddr = exAllocatePool + ( NonPagedPool, sizeof(*ifaddr) + 2 * sizeof( struct sockaddr_in ) ); + struct sockaddr_in *addr_in = (struct sockaddr_in *)&ifaddr[1]; + struct sockaddr_in *dstaddr_in = (struct sockaddr_in *)&addr_in[1]; + if( !ifaddr ) return NULL; + + TI_DbgPrint(MID_TRACE,("Called\n")); + + ifaddr->ifa_dstaddr = (struct sockaddr *)dstaddr_in; + /* XXX - Point-to-point interfaces not supported yet */ + memset( &ifaddr->ifa_dstaddr, 0, sizeof( struct sockaddr ) ); + + ifaddr->ifa_addr = (struct sockaddr *)addr_in; + Status = GetInterfaceIPv4Address( IF, + ADE_UNICAST, + (PULONG)&addr_in->sin_addr.s_addr ); + + if( !NT_SUCCESS(Status) ) + addr_in->sin_addr.s_addr = 0; + + TI_DbgPrint(MID_TRACE,("Prepare interface %x : addr %x\n", + IF, addr_in->sin_addr.s_addr)); + + ifaddr->ifa_flags = 0; /* XXX what goes here? */ + ifaddr->ifa_refcnt = 0; /* Anachronistic */ + ifaddr->ifa_metric = 1; /* We can get it like in ninfo.c, if we want */ + ifaddr->ifa_mtu = IF->MTU; + + TI_DbgPrint(MID_TRACE,("Leaving\n")); + + return ifaddr; } -void -if_attach(ifp) - struct ifnet *ifp; -{ - KeBugCheck( 0xface ); -} - -struct ifnet * -ifunit(char *name) -{ - return 0; -} - -int ifa_iffind(addr, ifaddr, type) - struct sockaddr *addr; - struct ifaddr *ifaddr; - int type; -{ +POSK_IFADDR TCPFindInterface( void *ClientData, + OSK_UINT AddrType, + OSK_UINT FindType, + OSK_SOCKADDR *ReqAddr, + OSK_IFADDR *Interface ) { PNEIGHBOR_CACHE_ENTRY NCE; IP_ADDRESS Destination; - NTSTATUS Status; - struct sockaddr_in *addr_in = (struct sockaddr_in *)addr; + struct sockaddr_in *addr_in = (struct sockaddr_in *)ReqAddr; + + TI_DbgPrint(MID_TRACE,("called for type %d\n", FindType)); - TI_DbgPrint(MID_TRACE,("called for type %d\n", type)); - - if( !addr || !ifaddr ) { - TI_DbgPrint(MID_TRACE,("no addr or no ifaddr (%x %x)\n", - addr, ifaddr)); - return OSK_EINVAL; + if( !ReqAddr ) { + TI_DbgPrint(MID_TRACE,("no addr or no ifaddr (%x)\n", ReqAddr)); + return NULL; } Destination.Type = IP_ADDRESS_V4; Destination.Address.IPv4Address = addr_in->sin_addr.s_addr; + TI_DbgPrint(MID_TRACE,("Address is %x\n", addr_in->sin_addr.s_addr)); + NCE = RouterGetRoute(&Destination, NULL); if( !NCE || !NCE->Interface ) { TI_DbgPrint(MID_TRACE,("no neighbor cache or no interface (%x %x)\n", NCE, NCE->Interface)); - return OSK_EADDRNOTAVAIL; + return NULL; } - /* XXX - Point-to-point interfaces not supported yet */ - memset(&ifaddr->ifa_dstaddr, 0, sizeof( struct sockaddr ) ); + addr_in = (struct sockaddr_in *) + ((POSK_IFADDR)NCE->Interface->TCPContext)->ifa_addr; + TI_DbgPrint(MID_TRACE,("returning addr %x\n", addr_in->sin_addr.s_addr)); - addr_in->sin_family = PF_INET; - addr_in = (struct sockaddr_in *)&ifaddr->ifa_addr; - Status = GetInterfaceIPv4Address( NCE->Interface, - type, - &addr_in->sin_addr.s_addr ); - - if( !NT_SUCCESS(Status) ) - addr_in->sin_addr.s_addr = 0; - - ifaddr->ifa_flags = 0; /* XXX what goes here? */ - ifaddr->ifa_refcnt = 0; /* Anachronistic */ - ifaddr->ifa_metric = 1; /* We can get it like in ninfo.c, if we want */ - ifaddr->ifa_mtu = NCE->Interface->MTU; - - TI_DbgPrint(MID_TRACE,("status in iffind: %x\n", Status)); - - return NT_SUCCESS(Status) ? 0 : OSK_EADDRNOTAVAIL; + return NCE->Interface->TCPContext; } -/* - * Find an interface on a specific network. If many, choice - * is most specific found. - */ -int ifa_ifwithnet(addr, ifaddr) - struct sockaddr *addr; - struct ifaddr *ifaddr; -{ - return ifa_iffind(addr, ifaddr, ADE_UNICAST); -} - -/* - * Locate the point to point interface with a given destination address. - */ -/*ARGSUSED*/ -struct ifaddr * -ifa_ifwithdstaddr(addr, ifaddr) - register struct sockaddr *addr; - register struct ifaddr *ifaddr; -{ - return ifa_iffind(addr, ifaddr, ADE_POINTOPOINT); -} - -/* - * Locate an interface based on a complete address. - */ -/*ARGSUSED*/ -int ifa_ifwithaddr(addr, ifaddr) - struct sockaddr *addr; - struct ifaddr *ifaddr; -{ - int error = ifa_ifwithnet( addr, ifaddr ); - struct sockaddr_in *addr_in = (struct sockaddr_in *)addr; - struct sockaddr_in *faddr_in = (struct sockaddr_in *)ifaddr->ifa_addr; - if( error != 0 ) return error; - else return - (faddr_in->sin_addr.s_addr == addr_in->sin_addr.s_addr) ? - 0 : OSK_EADDRNOTAVAIL; -} - -/* - * Handle interface watchdog timer routines. Called - * from softclock, we decrement timers (if set) and - * call the appropriate interface routine on expiration. - */ -void -if_slowtimo(arg) - void *arg; -{ -#if 0 - register struct ifnet *ifp; - int s = splimp(); - - for (ifp = ifnet; ifp; ifp = ifp->if_next) { - if (ifp->if_timer == 0 || --ifp->if_timer) - continue; - if (ifp->if_watchdog) - (*ifp->if_watchdog)(ifp->if_unit); - } - splx(s); - timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); -#endif -} diff --git a/reactos/drivers/net/tcpip/transport/tcp/tcp.c b/reactos/drivers/net/tcpip/transport/tcp/tcp.c index 3fcbadc69ec..c684f63e235 100644 --- a/reactos/drivers/net/tcpip/transport/tcp/tcp.c +++ b/reactos/drivers/net/tcpip/transport/tcp/tcp.c @@ -25,23 +25,13 @@ VOID TCPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket) * This is the low level interface for receiving TCP data */ { - PCHAR BufferData = exAllocatePool( NonPagedPool, IPPacket->TotalSize ); - - if( BufferData ) { - TI_DbgPrint(MID_TRACE,("Sending packet %d (%d) to oskit\n", - IPPacket->TotalSize, - IPPacket->HeaderSize)); - - memcpy( BufferData, IPPacket->Header, IPPacket->HeaderSize ); - memcpy( BufferData + IPPacket->HeaderSize, IPPacket->Data, - IPPacket->TotalSize - IPPacket->HeaderSize ); - - OskitTCPReceiveDatagram( BufferData, - IPPacket->TotalSize, - IPPacket->HeaderSize ); - - exFreePool( BufferData ); - } + TI_DbgPrint(MID_TRACE,("Sending packet %d (%d) to oskit\n", + IPPacket->TotalSize, + IPPacket->HeaderSize)); + + OskitTCPReceiveDatagram( IPPacket->Header, + IPPacket->TotalSize, + IPPacket->HeaderSize ); } /* event.c */ @@ -51,15 +41,19 @@ int TCPSocketState( void *ClientData, OSK_UINT NewState ); int TCPPacketSend( void *ClientData, - void *WhichSocket, - void *WhichConnection, OSK_PCHAR Data, OSK_UINT Len ); +POSK_IFADDR TCPFindInterface( void *ClientData, + OSK_UINT AddrType, + OSK_UINT FindType, + OSK_SOCKADDR *ReqAddr ); + OSKITTCP_EVENT_HANDLERS EventHandlers = { NULL, /* Client Data */ TCPSocketState, /* SocketState */ TCPPacketSend, /* PacketSend */ + TCPFindInterface, /* FindInterface */ }; NTSTATUS TCPStartup(VOID) @@ -130,13 +124,47 @@ NTSTATUS TCPTranslateError( int OskitError ) { return Status; } +#if 0 +NTSTATUS TCPBind +( PTDI_REQUEST Request, + PTDI_CONNECTION_INFORMATION ConnInfo ) { + NTSTATUS Status; + PCONNECTION_ENDPOINT Connection = Request->Handle.ConnectionContext; + SOCKADDR_IN AddressToConnect; + PIP_ADDRESS LocalAddress; + USHORT LocalPort; + + TI_DbgPrint(MID_TRACE,("Called\n")); + + Status = AddrBuildAddress + ((PTA_ADDRESS)ConnInfo->LocalAddress, + &LocalAddress, + &LocalPort); + + AddressToBind.sin_family = AF_INET; + memcpy( &AddressToBind.sin_addr, + &LocalAddress->Address.IPv4Address, + sizeof(AddressToBind.sin_addr) ); + AddressToBind.sin_port = LocalPort; + + Status = OskitTCPBind( Connection->SocketContext, + Connection, + &AddressToBind, + sizeof(AddressToBind)); + + TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status)); + + return Status; +} +#endif + NTSTATUS TCPConnect ( PTDI_REQUEST Request, PTDI_CONNECTION_INFORMATION ConnInfo, PTDI_CONNECTION_INFORMATION ReturnInfo ) { KIRQL OldIrql; NTSTATUS Status; - SOCKADDR_IN AddressToConnect; + SOCKADDR_IN AddressToConnect = { 0 }, AddressToBind = { 0 }; PCONNECTION_ENDPOINT Connection = Request->Handle.ConnectionContext; PIP_ADDRESS RemoteAddress; USHORT RemotePort; @@ -169,6 +197,12 @@ NTSTATUS TCPConnect } AddressToConnect.sin_family = AF_INET; + AddressToBind = AddressToConnect; + + OskitTCPBind( Connection->SocketContext, + Connection, + &AddressToBind, + sizeof(AddressToBind) ); memcpy( &AddressToConnect.sin_addr, &RemoteAddress->Address.IPv4Address, @@ -210,6 +244,7 @@ NTSTATUS TCPListen NTSTATUS TCPAccept ( PTDI_REQUEST Request, VOID **NewSocketContext ) { + return STATUS_UNSUCCESSFUL; } NTSTATUS TCPReceiveData @@ -270,7 +305,6 @@ NTSTATUS TCPSendData PCONNECTION_ENDPOINT Connection; PCHAR BufferData; ULONG PacketSize; - int error; Connection = Request->Handle.ConnectionContext; @@ -282,17 +316,21 @@ NTSTATUS TCPSendData TI_DbgPrint(MID_TRACE,("Connection->SocketContext = %x\n", Connection->SocketContext)); + OskitDumpBuffer( BufferData, PacketSize ); + Status = OskitTCPSend( Connection->SocketContext, - BufferData, PacketSize, DataUsed, 0 ); + BufferData, PacketSize, (PUINT)DataUsed, 0 ); KeReleaseSpinLock(&Connection->Lock, OldIrql); return Status; } -NTSTATUS TCPTimeout(VOID) { +VOID TCPTimeout(VOID) { static int Times = 0; - if( (Times++ % 100) == 0 ) TimerOskitTCP(); + if( (Times++ % 5) == 0 ) { + TimerOskitTCP(); + } } /* EOF */ diff --git a/reactos/drivers/net/tcpip/transport/udp/udp.c b/reactos/drivers/net/tcpip/transport/udp/udp.c index cc7901805bb..b84c96bfbd5 100644 --- a/reactos/drivers/net/tcpip/transport/udp/udp.c +++ b/reactos/drivers/net/tcpip/transport/udp/udp.c @@ -117,7 +117,6 @@ NTSTATUS BuildUDPPacket( */ { NTSTATUS Status; - NDIS_STATUS NdisStatus; PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context; PIP_PACKET Packet = &SendRequest->Packet; @@ -126,7 +125,7 @@ NTSTATUS BuildUDPPacket( /* Prepare packet */ /* FIXME: Assumes IPv4 */ - IPInitializePacket(IP_ADDRESS_V4, &SendRequest->Packet); + IPInitializePacket(&SendRequest->Packet, IP_ADDRESS_V4); if (!Packet) return STATUS_INSUFFICIENT_RESOURCES;