BSD 4_4 release
[unix-history] / usr / src / sys / netiso / clnp_frag.c
index b201f7c..546a592 100644 (file)
@@ -1,3 +1,38 @@
+/*-
+ * Copyright (c) 1991, 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.
+ *
+ *     @(#)clnp_frag.c 8.1 (Berkeley) 6/10/93
+ */
+
 /***********************************************************
                Copyright IBM Corporation 1987
 
 /***********************************************************
                Copyright IBM Corporation 1987
 
@@ -26,28 +61,24 @@ SOFTWARE.
  */
 /* $Header: /var/src/sys/netiso/RCS/clnp_frag.c,v 5.1 89/02/09 16:20:26 hagens Exp $ */
 /* $Source: /var/src/sys/netiso/RCS/clnp_frag.c,v $ */
  */
 /* $Header: /var/src/sys/netiso/RCS/clnp_frag.c,v 5.1 89/02/09 16:20:26 hagens Exp $ */
 /* $Source: /var/src/sys/netiso/RCS/clnp_frag.c,v $ */
-/*     @(#)clnp_frag.c 7.7 (Berkeley) %G% */
-
-#ifndef lint
-static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_frag.c,v 5.1 89/02/09 16:20:26 hagens Exp $";
-#endif lint
 
 
-#include "param.h"
-#include "mbuf.h"
-#include "domain.h"
-#include "protosw.h"
-#include "socket.h"
-#include "socketvar.h"
-#include "errno.h"
+#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/if.h>
+#include <net/route.h>
 
 
-#include "iso.h"
-#include "iso_var.h"
-#include "clnp.h"
-#include "clnp_stat.h"
-#include "argo_debug.h"
+#include <netiso/iso.h>
+#include <netiso/iso_var.h>
+#include <netiso/clnp.h>
+#include <netiso/clnp_stat.h>
+#include <netiso/argo_debug.h>
 
 /* all fragments are hung off this list */
 struct clnp_fragl      *clnp_frags = NULL;
 
 /* all fragments are hung off this list */
 struct clnp_fragl      *clnp_frags = NULL;
@@ -74,17 +105,18 @@ struct mbuf        *clnp_comp_pdu();
  *                                     the packet was fragmented during forwarding. In this
  *                                     case, we ought to send an ER back.
  */
  *                                     the packet was fragmented during forwarding. In this
  *                                     case, we ought to send an ER back.
  */
-clnp_fragment(ifp, m, first_hop, total_len, segoff, flags)
+clnp_fragment(ifp, m, first_hop, total_len, segoff, flags, rt)
 struct ifnet   *ifp;           /* ptr to outgoing interface */
 struct mbuf            *m;                     /* ptr to packet */
 struct sockaddr        *first_hop;     /* ptr to first hop */
 int                            total_len;      /* length of datagram */
 int                            segoff;         /* offset of segpart in hdr */
 int                            flags;          /* flags passed to clnp_output */
 struct ifnet   *ifp;           /* ptr to outgoing interface */
 struct mbuf            *m;                     /* ptr to packet */
 struct sockaddr        *first_hop;     /* ptr to first hop */
 int                            total_len;      /* length of datagram */
 int                            segoff;         /* offset of segpart in hdr */
 int                            flags;          /* flags passed to clnp_output */
+struct rtentry *rt;                    /* route if direct ether */
 {
        struct clnp_fixed               *clnp = mtod(m, struct clnp_fixed *);
        int                                             hdr_len = (int)clnp->cnf_hdr_len;
 {
        struct clnp_fixed               *clnp = mtod(m, struct clnp_fixed *);
        int                                             hdr_len = (int)clnp->cnf_hdr_len;
-       int                                             frag_size = (ifp->if_mtu - hdr_len) & ~7;
+       int                                             frag_size = (SN_MTU(ifp, rt) - hdr_len) & ~7;
 
        total_len -= hdr_len;
        if ((clnp->cnf_type & CNF_SEG_OK) &&
 
        total_len -= hdr_len;
        if ((clnp->cnf_type & CNF_SEG_OK) &&
@@ -94,16 +126,15 @@ int                                flags;          /* flags passed to clnp_output */
                struct mbuf                     *hdr = NULL;            /* save copy of clnp hdr */
                struct mbuf                     *frag_hdr = NULL;
                struct mbuf                     *frag_data = NULL;
                struct mbuf                     *hdr = NULL;            /* save copy of clnp hdr */
                struct mbuf                     *frag_hdr = NULL;
                struct mbuf                     *frag_data = NULL;
-               struct clnp_segment     seg_part, tmp_seg;      /* segmentation header */
-               extern int                      clnp_id;                        /* id of datagram */
-               int                                     frag_size;
+               struct clnp_segment     seg_part;                       /* segmentation header */
+               int                                     frag_base;
                int                                     error = 0;
 
 
                INCSTAT(cns_fragmented);
                int                                     error = 0;
 
 
                INCSTAT(cns_fragmented);
-               seg_part.cng_id = clnp_id++;
-               seg_part.cng_off = 0;
-               seg_part.cng_tot_len = total_len + hdr_len;
+        (void) bcopy(segoff + mtod(m, caddr_t), (caddr_t)&seg_part,
+            sizeof(seg_part));
+               frag_base = ntohs(seg_part.cng_off);
                /*
                 *      Duplicate header, and remove from packet
                 */
                /*
                 *      Duplicate header, and remove from packet
                 */
@@ -147,7 +178,7 @@ int                         flags;          /* flags passed to clnp_output */
 
                        IFDEBUG(D_FRAG)
                                printf("clnp_fragment: seg off %d, size %d, remaining %d\n", 
 
                        IFDEBUG(D_FRAG)
                                printf("clnp_fragment: seg off %d, size %d, remaining %d\n", 
-                                       seg_part.cng_off, frag_size, total_len-frag_size);
+                                       ntohs(seg_part.cng_off), frag_size, total_len-frag_size);
                                if (last_frag)
                                        printf("clnp_fragment: last fragment\n");
                        ENDDEBUG
                                if (last_frag)
                                        printf("clnp_fragment: last fragment\n");
                        ENDDEBUG
@@ -182,13 +213,8 @@ int                                flags;          /* flags passed to clnp_output */
                        /* link together */
                        m_cat(frag_hdr, frag_data);
 
                        /* link together */
                        m_cat(frag_hdr, frag_data);
 
-                       /* make sure segmentation fields are in network order */
-                       tmp_seg.cng_id = htons(seg_part.cng_id);
-                       tmp_seg.cng_off = htons(seg_part.cng_off);
-                       tmp_seg.cng_tot_len = htons(seg_part.cng_tot_len);
-
-                       /* insert segmentation part */
-                       bcopy((caddr_t)&tmp_seg, mtod(frag_hdr, caddr_t) + segoff,
+                       /* insert segmentation part; updated below */
+                       bcopy((caddr_t)&seg_part, mtod(frag_hdr, caddr_t) + segoff,
                                sizeof(struct clnp_segment));
 
                        {
                                sizeof(struct clnp_segment));
 
                        {
@@ -215,10 +241,10 @@ int                               flags;          /* flags passed to clnp_output */
                        ENDDEBUG
 
 #ifdef TROLL
                        ENDDEBUG
 
 #ifdef TROLL
-                       error = troll_output(ifp, frag_hdr, first_hop);
+                       error = troll_output(ifp, frag_hdr, first_hop, rt);
 #else
 #else
-                       error = (*ifp->if_output)(ifp, frag_hdr, first_hop);
-#endif TROLL
+                       error = (*ifp->if_output)(ifp, frag_hdr, first_hop, rt);
+#endif /* TROLL */
 
                        /*
                         *      Tough situation: if the error occured on the last 
 
                        /*
                         *      Tough situation: if the error occured on the last 
@@ -257,10 +283,11 @@ int                               flags;          /* flags passed to clnp_output */
                                        num_bytes *= troll_random();
                                frag_size -= num_bytes;
                        }
                                        num_bytes *= troll_random();
                                frag_size -= num_bytes;
                        }
-#endif TROLL
+#endif /* TROLL */
                        total_len -= frag_size;
                        if (!last_frag) {
                        total_len -= frag_size;
                        if (!last_frag) {
-                               seg_part.cng_off += frag_size;
+                               frag_base += frag_size;
+                               seg_part.cng_off = htons(frag_base);
                                m_adj(m, frag_size);
                        }
                }
                                m_adj(m, frag_size);
                        }
                }
@@ -305,8 +332,9 @@ struct clnp_segment *seg;   /* segment part of fragment header */
 
        /* look for other fragments of this datagram */
        for (cfh = clnp_frags; cfh != NULL; cfh = cfh->cfl_next) {
 
        /* look for other fragments of this datagram */
        for (cfh = clnp_frags; cfh != NULL; cfh = cfh->cfl_next) {
-               if (iso_addrmatch1(src, &cfh->cfl_src) && 
-                       iso_addrmatch1(dst, &cfh->cfl_dst) && seg->cng_id == cfh->cfl_id) {
+               if (seg->cng_id == cfh->cfl_id &&
+                   iso_addrmatch1(src, &cfh->cfl_src) && 
+                       iso_addrmatch1(dst, &cfh->cfl_dst)) {
                        IFDEBUG(D_REASS)
                                printf("clnp_reass: found packet\n");
                        ENDDEBUG
                        IFDEBUG(D_REASS)
                                printf("clnp_reass: found packet\n");
                        ENDDEBUG
@@ -315,7 +343,12 @@ struct clnp_segment        *seg;   /* segment part of fragment header */
                         *      this fragment is of any help
                         */
                        clnp_insert_frag(cfh, m, seg);
                         *      this fragment is of any help
                         */
                        clnp_insert_frag(cfh, m, seg);
-                       return (clnp_comp_pdu(cfh));
+                       if (m = clnp_comp_pdu(cfh)) {
+                               register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
+                               HTOC(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb,
+                                        seg->cng_tot_len);
+                       }
+                       return (m);
                }
        }
 
                }
        }
 
@@ -750,7 +783,7 @@ struct clnp_fragl   *cfh;           /* fragment header */
 }
 #ifdef TROLL
 static int troll_cnt;
 }
 #ifdef TROLL
 static int troll_cnt;
-#include "time.h"
+#include <sys/time.h>
 /*
  * FUNCTION:           troll_random
  *
 /*
  * FUNCTION:           troll_random
  *
@@ -787,10 +820,11 @@ float troll_random()
  * NOTES:                      The operation of this procedure is regulated by the
  *                                     troll control structure (Troll).
  */
  * NOTES:                      The operation of this procedure is regulated by the
  *                                     troll control structure (Troll).
  */
-troll_output(ifp, m, dst)
+troll_output(ifp, m, dst, rt)
 struct ifnet   *ifp;
 struct mbuf            *m;
 struct sockaddr        *dst;
 struct ifnet   *ifp;
 struct mbuf            *m;
 struct sockaddr        *dst;
+struct rtentry *rt;
 {
        int     err = 0;
        troll_cnt++;
 {
        int     err = 0;
        troll_cnt++;
@@ -805,21 +839,21 @@ struct sockaddr   *dst;
                if (i_freq == f_freq) {
                        struct mbuf *dup = m_copy(m, 0, (int)M_COPYALL);
                        if (dup != NULL)
                if (i_freq == f_freq) {
                        struct mbuf *dup = m_copy(m, 0, (int)M_COPYALL);
                        if (dup != NULL)
-                               err = (*ifp->if_output)(ifp, dup, dst);
+                               err = (*ifp->if_output)(ifp, dup, dst, rt);
                }
                if (!err)
                }
                if (!err)
-                       err = (*ifp->if_output)(ifp, m, dst);
+                       err = (*ifp->if_output)(ifp, m, dst, rt);
                return(err);
        } else if (trollctl.tr_ops & TR_DROPPKT) {
        } else if (trollctl.tr_ops & TR_CHANGE) {
                struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
                clnp->cnf_cksum_msb = 0;
                return(err);
        } else if (trollctl.tr_ops & TR_DROPPKT) {
        } else if (trollctl.tr_ops & TR_CHANGE) {
                struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
                clnp->cnf_cksum_msb = 0;
-               err = (*ifp->if_output)(ifp, m, dst);
+               err = (*ifp->if_output)(ifp, m, dst, rt);
                return(err);
        } else {
                return(err);
        } else {
-               err = (*ifp->if_output)(ifp, m, dst);
+               err = (*ifp->if_output)(ifp, m, dst, rt);
                return(err);
        }
 }
 
                return(err);
        }
 }
 
-#endif TROLL
+#endif /* TROLL */