The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netns/ns_error.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1984, 1988, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by the University of
   16  *      California, Berkeley and its contributors.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      @(#)ns_error.c  8.1 (Berkeley) 6/10/93
   34  * $FreeBSD$
   35  */
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/malloc.h>
   40 #include <sys/mbuf.h>
   41 #include <sys/protosw.h>
   42 #include <sys/socket.h>
   43 #include <sys/time.h>
   44 #include <sys/kernel.h>
   45 
   46 #include <net/route.h>
   47 
   48 #include <netns/ns.h>
   49 #include <netns/ns_pcb.h>
   50 #include <netns/idp.h>
   51 #include <netns/ns_error.h>
   52 
   53 #ifdef lint
   54 #define NS_ERRPRINTFS 1
   55 #endif
   56 
   57 #ifdef NS_ERRPRINTFS
   58 /*
   59  * NS_ERR routines: error generation, receive packet processing, and
   60  * routines to turnaround packets back to the originator.
   61  */
   62 int     ns_errprintfs = 0;
   63 #endif
   64 
   65 ns_err_x(c)
   66 {
   67         register u_short *w, *lim, *base = ns_errstat.ns_es_codes;
   68         u_short x = c;
   69 
   70         /*
   71          * zero is a legit error code, handle specially
   72          */
   73         if (x == 0)
   74                 return (0);
   75         lim = base + NS_ERR_MAX - 1;
   76         for (w = base + 1; w < lim; w++) {
   77                 if (*w == 0)
   78                         *w = x;
   79                 if (*w == x)
   80                         break;
   81         }
   82         return (w - base);
   83 }
   84 
   85 /*
   86  * Generate an error packet of type error
   87  * in response to bad packet.
   88  */
   89 
   90 ns_error(om, type, param)
   91         struct mbuf *om;
   92         int type;
   93 {
   94         register struct ns_epidp *ep;
   95         struct mbuf *m;
   96         struct idp *nip;
   97         register struct idp *oip = mtod(om, struct idp *);
   98         extern int idpcksum;
   99 
  100         /*
  101          * If this packet was sent to the echo port,
  102          * and nobody was there, just echo it.
  103          * (Yes, this is a wart!)
  104          */
  105         if (type == NS_ERR_NOSOCK &&
  106             oip->idp_dna.x_port == htons(2) &&
  107             (type = ns_echo(om))==0)
  108                 return;
  109 
  110 #ifdef NS_ERRPRINTFS
  111         if (ns_errprintfs)
  112                 printf("ns_err_error(%x, %d, %d)\n", oip, type, param);
  113 #endif
  114         /*
  115          * Don't Generate error packets in response to multicasts.
  116          */
  117         if (oip->idp_dna.x_host.c_host[0] & 1)
  118                 goto freeit;
  119 
  120         ns_errstat.ns_es_error++;
  121         /*
  122          * Make sure that the old IDP packet had 30 bytes of data to return;
  123          * if not, don't bother.  Also don't EVER error if the old
  124          * packet protocol was NS_ERR.
  125          */
  126         if (oip->idp_len < sizeof(struct idp)) {
  127                 ns_errstat.ns_es_oldshort++;
  128                 goto freeit;
  129         }
  130         if (oip->idp_pt == NSPROTO_ERROR) {
  131                 ns_errstat.ns_es_oldns_err++;
  132                 goto freeit;
  133         }
  134 
  135         /*
  136          * First, formulate ns_err message
  137          */
  138         m = m_gethdr(M_DONTWAIT, MT_HEADER);
  139         if (m == NULL)
  140                 goto freeit;
  141         m->m_len = sizeof(*ep);
  142         MH_ALIGN(m, m->m_len);
  143         ep = mtod(m, struct ns_epidp *);
  144         if ((u_int)type > NS_ERR_TOO_BIG)
  145                 panic("ns_err_error");
  146         ns_errstat.ns_es_outhist[ns_err_x(type)]++;
  147         ep->ns_ep_errp.ns_err_num = htons((u_short)type);
  148         ep->ns_ep_errp.ns_err_param = htons((u_short)param);
  149         bcopy((caddr_t)oip, (caddr_t)&ep->ns_ep_errp.ns_err_idp, 42);
  150         nip = &ep->ns_ep_idp;
  151         nip->idp_len = sizeof(*ep);
  152         nip->idp_len = htons((u_short)nip->idp_len);
  153         nip->idp_pt = NSPROTO_ERROR;
  154         nip->idp_tc = 0;
  155         nip->idp_dna = oip->idp_sna;
  156         nip->idp_sna = oip->idp_dna;
  157         if (idpcksum) {
  158                 nip->idp_sum = 0;
  159                 nip->idp_sum = ns_cksum(m, sizeof(*ep));
  160         } else
  161                 nip->idp_sum = 0xffff;
  162         (void) ns_output(m, (struct route *)0, 0);
  163 
  164 freeit:
  165         m_freem(om);
  166 }
  167 
  168 ns_printhost(p)
  169 register struct ns_addr *p;
  170 {
  171 
  172         printf("<net:%x%x,host:%x%x%x,port:%x>",
  173                         p->x_net.s_net[0],
  174                         p->x_net.s_net[1],
  175                         p->x_host.s_host[0],
  176                         p->x_host.s_host[1],
  177                         p->x_host.s_host[2],
  178                         p->x_port);
  179 
  180 }
  181 
  182 /*
  183  * Process a received NS_ERR message.
  184  */
  185 ns_err_input(m)
  186         struct mbuf *m;
  187 {
  188         register struct ns_errp *ep;
  189         register struct ns_epidp *epidp = mtod(m, struct ns_epidp *);
  190         register int i;
  191         int type, code, param;
  192 
  193         /*
  194          * Locate ns_err structure in mbuf, and check
  195          * that not corrupted and of at least minimum length.
  196          */
  197 #ifdef NS_ERRPRINTFS
  198         if (ns_errprintfs) {
  199                 printf("ns_err_input from ");
  200                 ns_printhost(&epidp->ns_ep_idp.idp_sna);
  201                 printf("len %d\n", ntohs(epidp->ns_ep_idp.idp_len));
  202         }
  203 #endif
  204         i = sizeof (struct ns_epidp);
  205         if (((m->m_flags & M_EXT) || m->m_len < i) &&
  206                 (m = m_pullup(m, i)) == 0)  {
  207                 ns_errstat.ns_es_tooshort++;
  208                 return;
  209         }
  210         ep = &(mtod(m, struct ns_epidp *)->ns_ep_errp);
  211         type = ntohs(ep->ns_err_num);
  212         param = ntohs(ep->ns_err_param);
  213         ns_errstat.ns_es_inhist[ns_err_x(type)]++;
  214 
  215 #ifdef NS_ERRPRINTFS
  216         /*
  217          * Message type specific processing.
  218          */
  219         if (ns_errprintfs)
  220                 printf("ns_err_input, type %d param %d\n", type, param);
  221 #endif
  222         if (type >= NS_ERR_TOO_BIG) {
  223                 goto badcode;
  224         }
  225         ns_errstat.ns_es_outhist[ns_err_x(type)]++;
  226         switch (type) {
  227 
  228         case NS_ERR_UNREACH_HOST:
  229                 code = PRC_UNREACH_NET;
  230                 goto deliver;
  231 
  232         case NS_ERR_TOO_OLD:
  233                 code = PRC_TIMXCEED_INTRANS;
  234                 goto deliver;
  235 
  236         case NS_ERR_TOO_BIG:
  237                 code = PRC_MSGSIZE;
  238                 goto deliver;
  239 
  240         case NS_ERR_FULLUP:
  241                 code = PRC_QUENCH;
  242                 goto deliver;
  243 
  244         case NS_ERR_NOSOCK:
  245                 code = PRC_UNREACH_PORT;
  246                 goto deliver;
  247 
  248         case NS_ERR_UNSPEC_T:
  249         case NS_ERR_BADSUM_T:
  250         case NS_ERR_BADSUM:
  251         case NS_ERR_UNSPEC:
  252                 code = PRC_PARAMPROB;
  253                 goto deliver;
  254 
  255         deliver:
  256                 /*
  257                  * Problem with datagram; advise higher level routines.
  258                  */
  259 #ifdef NS_ERRPRINTFS
  260                 if (ns_errprintfs)
  261                         printf("deliver to protocol %d\n",
  262                                        ep->ns_err_idp.idp_pt);
  263 #endif
  264                 switch(ep->ns_err_idp.idp_pt) {
  265                 case NSPROTO_SPP:
  266                         spp_ctlinput(code, (caddr_t)ep);
  267                         break;
  268 
  269                 default:
  270                         idp_ctlinput(code, (caddr_t)ep);
  271                 }
  272 
  273                 goto freeit;
  274 
  275         default:
  276         badcode:
  277                 ns_errstat.ns_es_badcode++;
  278                 goto freeit;
  279 
  280         }
  281 freeit:
  282         m_freem(m);
  283 }
  284 
  285 #ifdef notdef
  286 u_long
  287 nstime()
  288 {
  289         int s = splclock();
  290         u_long t;
  291 
  292         t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000;
  293         splx(s);
  294         return (htonl(t));
  295 }
  296 #endif
  297 
  298 ns_echo(m)
  299 struct mbuf *m;
  300 {
  301         register struct idp *idp = mtod(m, struct idp *);
  302         register struct echo {
  303             struct idp  ec_idp;
  304             u_short             ec_op; /* Operation, 1 = request, 2 = reply */
  305         } *ec = (struct echo *)idp;
  306         struct ns_addr temp;
  307 
  308         if (idp->idp_pt!=NSPROTO_ECHO) return(NS_ERR_NOSOCK);
  309         if (ec->ec_op!=htons(1)) return(NS_ERR_UNSPEC);
  310 
  311         ec->ec_op = htons(2);
  312 
  313         temp = idp->idp_dna;
  314         idp->idp_dna = idp->idp_sna;
  315         idp->idp_sna = temp;
  316 
  317         if (idp->idp_sum != 0xffff) {
  318                 idp->idp_sum = 0;
  319                 idp->idp_sum = ns_cksum(m,
  320                     (int)(((ntohs(idp->idp_len) - 1)|1)+1));
  321         }
  322         (void) ns_output(m, (struct route *)0, NS_FORWARDING);
  323         return(0);
  324 }

Cache object: b5f3bdddebb1469e2055ce2a6804d97e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.