oskittcp: new import. less diff output versus pure sources.
authorArt Yerkes <art.yerkes@gmail.com>
Thu, 19 Aug 2004 21:39:00 +0000 (21:39 +0000)
committerArt Yerkes <art.yerkes@gmail.com>
Thu, 19 Aug 2004 21:39:00 +0000 (21:39 +0000)
no deleted code this time around.  all properly ifdef'd
more use of bsd style adapter structs and adapter queries with provided
support by tcpip.sys.
correct prototypes
some diff output is reformatting

tcpip: some bug fixes, -Wall -Werror on, all prototypes in
remove the need for MaxLLHeaderSize anywhere except lan.c
unify meaning of Header and Data members of IP_PACKET
unify PCHAR types in routines.c
move one more address into the struct, eliminating management and extra
poll alloc in NCE
eliminate wrong use of PIP_INTERFACE as NTE pointer in dispatch functions
other fixes

svn path=/trunk/; revision=10601

67 files changed:
reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/if.h
reactos/drivers/lib/oskittcp/include/freebsd/src/sys/net/route.h
reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/in_pcb.h
reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet/ip_var.h
reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/mbuf.h
reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/proc.h
reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/select.h
reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys/socketvar.h
reactos/drivers/lib/oskittcp/include/oskittcp.h
reactos/drivers/lib/oskittcp/include/oskittypes.h
reactos/drivers/lib/oskittcp/makefile
reactos/drivers/lib/oskittcp/notes.txt [new file with mode: 0644]
reactos/drivers/lib/oskittcp/oskittcp/in_cksum.c
reactos/drivers/lib/oskittcp/oskittcp/in_pcb.c
reactos/drivers/lib/oskittcp/oskittcp/interface.c
reactos/drivers/lib/oskittcp/oskittcp/ip_output.c
reactos/drivers/lib/oskittcp/oskittcp/raw_cb.c [new file with mode: 0644]
reactos/drivers/lib/oskittcp/oskittcp/raw_ip.c [new file with mode: 0644]
reactos/drivers/lib/oskittcp/oskittcp/raw_usrreq.c [new file with mode: 0644]
reactos/drivers/lib/oskittcp/oskittcp/route.c
reactos/drivers/lib/oskittcp/oskittcp/rtsock.c
reactos/drivers/lib/oskittcp/oskittcp/sleep.c
reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c
reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c
reactos/drivers/lib/oskittcp/oskittcp/tcp_subr.c
reactos/drivers/lib/oskittcp/oskittcp/tcp_usrreq.c
reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c
reactos/drivers/lib/oskittcp/oskittcp/uipc_socket.c
reactos/drivers/lib/oskittcp/oskittcp/uipc_socket2.c
reactos/drivers/net/tcpip/datalink/arp.c
reactos/drivers/net/tcpip/datalink/lan.c
reactos/drivers/net/tcpip/include/address.h
reactos/drivers/net/tcpip/include/debug.h
reactos/drivers/net/tcpip/include/info.h
reactos/drivers/net/tcpip/include/interface.h
reactos/drivers/net/tcpip/include/ip.h
reactos/drivers/net/tcpip/include/irp.h [new file with mode: 0644]
reactos/drivers/net/tcpip/include/lan.h
reactos/drivers/net/tcpip/include/neighbor.h
reactos/drivers/net/tcpip/include/precomp.h
reactos/drivers/net/tcpip/include/route.h
reactos/drivers/net/tcpip/include/routines.h
reactos/drivers/net/tcpip/include/tcp.h
reactos/drivers/net/tcpip/include/titypes.h
reactos/drivers/net/tcpip/makefile
reactos/drivers/net/tcpip/network/icmp.c
reactos/drivers/net/tcpip/network/ip.c
reactos/drivers/net/tcpip/network/neighbor.c
reactos/drivers/net/tcpip/network/receive.c
reactos/drivers/net/tcpip/network/route.c
reactos/drivers/net/tcpip/network/router.c
reactos/drivers/net/tcpip/network/transmit.c
reactos/drivers/net/tcpip/tcpip/address.c
reactos/drivers/net/tcpip/tcpip/dispatch.c
reactos/drivers/net/tcpip/tcpip/fileobjs.c
reactos/drivers/net/tcpip/tcpip/iinfo.c
reactos/drivers/net/tcpip/tcpip/info.c
reactos/drivers/net/tcpip/tcpip/irp.c
reactos/drivers/net/tcpip/tcpip/main.c
reactos/drivers/net/tcpip/tcpip/ninfo.c
reactos/drivers/net/tcpip/tcpip/routines.c
reactos/drivers/net/tcpip/tcpip/tinfo.c
reactos/drivers/net/tcpip/transport/datagram/datagram.c
reactos/drivers/net/tcpip/transport/tcp/event.c
reactos/drivers/net/tcpip/transport/tcp/if.c
reactos/drivers/net/tcpip/transport/tcp/tcp.c
reactos/drivers/net/tcpip/transport/udp/udp.c

index aca7de7..fcf6dad 100644 (file)
@@ -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 *));
index ef78cbb..3173211 100644 (file)
@@ -36,8 +36,6 @@
 #ifndef _NET_ROUTE_H_
 #define _NET_ROUTE_H_
 
-#include <oskittypes.h>
-
 /*
  * Kernel resident routing tables.
  *
  * 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 <net/radix.h>
 #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 <oskittcp.h>
-
-#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;
index 0a8b58d..2b8cba7 100644 (file)
@@ -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 *));
index 351ebf1..9aa1e4c 100644 (file)
@@ -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 *));
index 50138e2..aa04002 100644 (file)
 #include <sys/malloc.h>
 #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
  * 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 <oskit/io/bufio.h>
 /* 
  * 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_ */
index 03b31b9..413569a 100644 (file)
@@ -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;
index bbb19ff..18d3fc6 100644 (file)
@@ -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_ */
index 2c90e24..5afe348 100644 (file)
@@ -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 *));
index 3d07a09..133ca43 100644 (file)
@@ -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__)
index 1040980..9fad9f9 100644 (file)
@@ -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*/
index 3178bbf..4c3fca7 100644 (file)
@@ -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 (file)
index 0000000..d5f2921
--- /dev/null
@@ -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.
+
index 4175f8c..de93c1e 100644 (file)
@@ -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
index f050eb6..4307890 100644 (file)
@@ -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 (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;
-           /*
-            * 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));
+               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) { }
index f37494d..a6f51c9 100644 (file)
@@ -1,4 +1,3 @@
-
 #include <oskittcp.h>
 #include <oskitdebug.h>
 #include <ntddk.h>
@@ -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;
 
-    OskitDumpBuffer( Data, Len );
+    /* 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);
 
-    memset( Ip, 0, sizeof( *Ip ) );
-    Ip->m_len = Len;
-    Ip->m_data = NewData;
-    memcpy( Ip->m_data, Data, Len );
+    OS_DbgPrint(OSK_MAX_TRACE, 
+               ("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len,
+                IpHeaderLen));
+
+    OskitDumpBuffer( 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;
+}
+
index 7e53ee3..587d305 100644 (file)
 
 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++;
-
-    /*
-     * 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 );
+       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;
+
+#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);
+
+       return (error);
+bad:
+       m_freem(m0);
+       goto done;
+}
 
-    OS_DbgPrint(OSK_MID_TRACE,("Error from upper layer: %d\n", 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;
 
-    return (error);
+       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 (file)
index 0000000..c0d39d8
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/raw_cb.h>
+#include <netinet/in.h>
+
+#include <oskittcp.h>
+
+/*
+ * 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 (file)
index 0000000..9bb88d7
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+#include <sys/queue.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+#ifndef __REACTOS__
+#include <netinet/ip_mroute.h>
+#endif
+
+#include <netinet/ip_fw.h>
+#include <oskittcp.h>
+
+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 (file)
index 0000000..286bcce
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/netisr.h>
+#include <net/raw_cb.h>
+
+#include <oskittcp.h>
+
+/*
+ * 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);
+}
index a7b2f1e..b864966 100644 (file)
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
+#ifndef __REACTOS__
 #include <netinet/ip_mroute.h>
+#endif
+#include <oskittcp.h>
 
 #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);
 }
index 51cc2ef..17a25ff 100644 (file)
 #include <net/route.h>
 #include <net/raw_cb.h>
 
+#include <oskittcp.h>
+
+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);
+}
+
+/*
+ * 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
-       panic("Unimplemented function\n");
+                       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);
index 615b8e7..b9aa1b4 100644 (file)
@@ -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 ) 
index 6e1825f..50b01cf 100644 (file)
@@ -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) { \
+               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_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; \
-                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; \
-               } \
+               (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; \
        } \
 }
-
+#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 */
index 6263033..e4df92c 100644 (file)
@@ -33,7 +33,7 @@
  *     @(#)tcp_output.c        8.3 (Berkeley) 12/30/93
  */
 
-#define        TCPOUTFLAGS
+#define TCPOUTFLAGS
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
@@ -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;
-           }
+               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;
+               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;
+               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);
 }
 
index fc3eafd..4632b68 100644 (file)
@@ -64,6 +64,7 @@
 #ifdef TCPDEBUG
 #include <netinet/tcp_debug.h>
 #endif
+#include <oskittcp.h>
 
 /* 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;
index c780f43..f315e3d 100644 (file)
@@ -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;
-
-    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);
-
-    /*
-     * 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);
-    }
+       register struct inpcb *inp;
+       register struct tcpcb *tp = 0;
+       struct sockaddr_in *sinp;
+       int s;
+       int error = 0;
+#ifdef TCPDEBUG
+       int ostate;
+#endif
 
-    if( inp )
-       tp = intotcpcb(inp);
-    
-    switch (req) {
+       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);
        /*
-        * TCP attaches to socket via PRU_ATTACH, reserving space,
-        * and an internet control block.
+        * 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).
         */
-    case PRU_ATTACH:
+       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) {
-           error = EISCONN;
-           break;
+               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 */
        }
-       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;
-       
+#endif /* TCPDEBUG */
+
+       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;
+
        /*
         * 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;
+
+       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_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;
-           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_SOCKADDR:
+               in_setsockaddr(inp, nam);
+               break;
 
-    case PRU_PEERADDR:
-       in_setpeeraddr(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;
+       /*
+        * 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;
+       }
+       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,("Leaving ENOBUFS\n"));
+               return ENOBUFS;
+       }
 
-    if( !inp->inp_socket )
-       panic( "No socket provided.\n" );
+       /* 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++;
 
-    so = inp->inp_socket;
+       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);
 
-    if (inp->inp_lport == 0) {
-       error = in_pcbbind(inp, NULL);
-       if (error) {
-           OS_DbgPrint(OSK_MID_TRACE,("error %d\n", error));
-           return error;
+       /*
+        * 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));
        }
-    }
-    /*
-     * 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;
+
+       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;
        }
-    
-    }
-    
-    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));
-    }
-
-    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;
-    }
-
-    return 0;
+
+       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 */
 }
index 222efa3..d19f70f 100644 (file)
@@ -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;
index 1320b84..9b9dae0 100644 (file)
@@ -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);
 }
index ec24f57..359e9f9 100644 (file)
@@ -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;
index c9cd5ad..fc293f3 100644 (file)
@@ -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);
 
index bb143b1..b79fda9 100644 (file)
@@ -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;
index 450f968..87cca42 100644 (file)
@@ -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,
index fffbe2c..56a8bf2 100644 (file)
@@ -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
index bb14a1d..cc27ac1 100644 (file)
@@ -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,
index 7269208..299e7aa 100644 (file)
@@ -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 );
index a9d5f95..7c84b47 100644 (file)
@@ -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 (file)
index 0000000..d49231b
--- /dev/null
@@ -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*/
index fc59398..18d9b8d 100644 (file)
@@ -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 */
index 1c401f8..8b7f71e 100644 (file)
@@ -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 */
index 96b26a2..8532a9f 100644 (file)
@@ -21,6 +21,7 @@
 #include <pool.h>
 #include <arp.h>
 #include <lan.h>
+#include <irp.h>
 #include <tilists.h>
 #include <dispatch.h>
 #include <fileobjs.h>
@@ -28,3 +29,4 @@
 #include <info.h>
 #include <memtrack.h>
 #include <oskittcp.h>
+#include <interface.h>
index 4eb9ff3..cab0422 100644 (file)
@@ -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 */
index 2c546f5..cdb65c8 100644 (file)
@@ -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);
index d3f8769..d15dabc 100644 (file)
@@ -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);
 
index ced8385..7f4d539 100644 (file)
@@ -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 */
index c494171..f292453 100644 (file)
@@ -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 \
index e272d58..862ae50 100644 (file)
@@ -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);
index c6bef3d..652652c 100644 (file)
@@ -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;
index eeca634..51e41f6 100644 (file)
@@ -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--;
 
index 0d6bb62..c8dba5c 100644 (file)
@@ -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));
index 67830ad..5a5829d 100644 (file)
@@ -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;
     
 
index b77a4ae..bc4c211 100644 (file)
@@ -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;
 
index 81b44ed..2c2fd4e 100644 (file)
@@ -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;
 
index ad58905..161ac21 100644 (file)
@@ -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;
 }
 
index 9662b26..92113d4 100644 (file)
@@ -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"));
 
index 4368341..ddeda9e 100644 (file)
@@ -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);
index c621da7..ac62a72 100644 (file)
@@ -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 ) {
index b66dbcc..a5bb910 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "precomp.h"
 #include <debug.h>
+#include <route.h>
 
 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;
 
index e05bfdd..e6a9367 100644 (file)
@@ -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
index e9a5da0..54a3aae 100644 (file)
@@ -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 */
index c66a173..58393b8 100644 (file)
@@ -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;
 }
index 986d226..340782e 100644 (file)
@@ -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);
index a4261ac..84435ce 100644 (file)
@@ -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;
 }
index c6c313b..2223a39 100644 (file)
@@ -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;
index 0531ecc..9ea18d4 100644 (file)
@@ -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);
-
-    NCE = RouterGetRoute( &RemoteAddress, NULL );
-
-    if( !NCE ) return OSK_EADDRNOTAVAIL;
+            RemoteAddress.Address.IPv4Address);
+    
+    ASSERT( (LocalAddress.Address.IPv4Address & 0xc0000000) != 0xc0000000 );
+       
 
-    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;
-
-    SendRequest->Complete = TCPPacketSendComplete;
-    SendRequest->Context = Connection;
-    SendRequest->RemoteAddress = RemoteAddress;
-    SendRequest->RemotePort = RemotePort;
-    NdisQueryPacketLength( SendRequest->Packet.NdisPacket,
-                          &SendRequest->BufferSize );
-
-    AddHeaderIPv4( SendRequest, 
-                  &LocalAddress, 
-                  LocalPort,
-                  &RemoteAddress,
-                  RemotePort );
-
-    if( Connection ) 
-       DGTransmit( Connection->AddressFile, SendRequest );
-    else
-       DbgPrint("Transmit called without connection.\n");
+    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))));
+
+    Packet.HeaderSize = sizeof(IPv4_HEADER);
+    Packet.TotalSize = len;
+    Packet.SrcAddr = LocalAddress;
+    Packet.DstAddr = RemoteAddress;
+
+    IPSendFragment( Packet.NdisPacket, RCN->NCE );
 
 end:
     KeLowerIrql( OldIrql );
index 2152882..a13070d 100644 (file)
@@ -37,135 +37,75 @@ struct     ifnet *ifnet;
  * Routines with ifa_ifwith* names take sockaddr *'s as
  * parameters.
  */
-void
-ifinit()
-{
-}
 
-void
-if_attach(ifp)
-       struct ifnet *ifp;
-{
-    KeBugCheck( 0xface );
-}
+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;
 
-struct ifnet *
-ifunit(char *name)
-{
-       return 0;
+    TI_DbgPrint(MID_TRACE,("Leaving\n"));
+
+    return ifaddr;
 }
 
-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;
-
-    TI_DbgPrint(MID_TRACE,("called for type %d\n", type));
+    struct sockaddr_in *addr_in = (struct sockaddr_in *)ReqAddr;
+    
+    TI_DbgPrint(MID_TRACE,("called for type %d\n", FindType));
 
-    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
-}
index 3fcbadc..c684f63 100644 (file)
@@ -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 */
index cc79018..b84c96b 100644 (file)
@@ -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;