don't generate icmp message without a copy of the original ip
[unix-history] / usr / src / sys / netinet / raw_ip.c
index 8ec42b3..24ed7a4 100644 (file)
@@ -1,58 +1,93 @@
-/*     raw_ip.c        4.1     81/11/29        */
+/*     raw_ip.c        4.17    83/02/10        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 #include "../h/socket.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 #include "../h/socket.h"
+#include "../h/protosw.h"
 #include "../h/socketvar.h"
 #include "../h/socketvar.h"
-#include "../net/in.h"
-#include "../net/in_systm.h"
+#include "../h/errno.h"
 
 
-/*
- * Raw protocol interface.
- */
-/*ARGSUSED*/
-rip_input(m)
-       struct mbuf *m;
-{
-
-COUNT(RIP_INPUT);
-
-       /* call raw_input with prepared parameters */
-}
-
-/*ARGSUSED*/
-rip_ctlinput(m)
-       struct mbuf *m;
-{
+#include "../net/if.h"
+#include "../net/raw_cb.h"
+#include "../net/route.h"
 
 
-COUNT(RIP_CTLINPUT);
+#include "../netinet/in.h"
+#include "../netinet/in_systm.h"
+#include "../netinet/ip.h"
+#include "../netinet/ip_var.h"
 
 
-}
+/*
+ * Raw interface to IP protocol.
+ */
 
 
-/*ARGSUSED*/
-rip_output(m)
+static struct sockaddr_in ripdst = { AF_INET };
+static struct sockaddr_in ripsrc = { AF_INET };
+static struct sockproto ripproto = { PF_INET };
+/*
+ * Setup generic address and protocol structures
+ * for raw_input routine, then pass them along with
+ * mbuf chain.
+ */
+rip_input(m)
        struct mbuf *m;
 {
        struct mbuf *m;
 {
+       register struct ip *ip = mtod(m, struct ip *);
 
 
-COUNT(RIP_OUTPUT);
-
+       ripproto.sp_protocol = ip->ip_p;
+       ripdst.sin_addr = ip->ip_dst;
+       ripsrc.sin_addr = ip->ip_src;
+       raw_input(m, &ripproto, (struct sockaddr *)&ripsrc,
+         (struct sockaddr *)&ripdst);
 }
 
 }
 
-/*ARGSUSED*/
-rip_usrreq(so, req, m, addr)
+/*
+ * Generate IP header and pass packet to ip_output.
+ * Tack on options user may have setup with control call.
+ */
+rip_output(m0, so)
+       struct mbuf *m0;
        struct socket *so;
        struct socket *so;
-       int req;
-       struct mbuf *m;
-       caddr_t addr;
 {
 {
-
-COUNT(RAW_USRREQ);
-
-}
-
-rip_slowtimo()
-{
-
-COUNT(RIP_SLOWTIMO);
-
+       register struct mbuf *m;
+       register struct ip *ip;
+       int len = 0, error;
+       struct rawcb *rp = sotorawcb(so);
+       struct sockaddr_in *sin;
+
+       /*
+        * Calculate data length and get an mbuf
+        * for IP header.
+        */
+       for (m = m0; m; m = m->m_next)
+               len += m->m_len;
+       m = m_get(M_DONTWAIT, MT_HEADER);
+       if (m == 0) {
+               error = ENOBUFS;
+               goto bad;
+       }
+       
+       /*
+        * Fill in IP header as needed.
+        */
+       m->m_off = MMAXOFF - sizeof(struct ip);
+       m->m_len = sizeof(struct ip);
+       m->m_next = m0;
+       ip = mtod(m, struct ip *);
+       ip->ip_p = so->so_proto->pr_protocol;
+       ip->ip_len = sizeof(struct ip) + len;
+       if (rp->rcb_flags & RAW_LADDR) {
+               sin = (struct sockaddr_in *)&rp->rcb_laddr;
+               if (sin->sin_family != AF_INET) {
+                       error = EAFNOSUPPORT;
+                       goto bad;
+               }
+               ip->ip_src.s_addr = sin->sin_addr.s_addr;
+       } else
+               ip->ip_src.s_addr = 0;
+       ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
+       ip->ip_ttl = MAXTTL;
+       return (ip_output(m, (struct mbuf *)0, &routetoif, 1));
+bad:
+       m_freem(m);
+       return (error);
 }
 }