home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / netns / ns_error.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  7.5 KB  |  324 lines

  1. /*
  2.  * Copyright (c) 1984, 1988 Regents of the University of California.
  3.  * 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    7.8 (Berkeley) 6/28/90
  34.  */
  35.  
  36. #include "param.h"
  37. #include "systm.h"
  38. #include "malloc.h"
  39. #include "mbuf.h"
  40. #include "protosw.h"
  41. #include "socket.h"
  42. #include "time.h"
  43. #include "kernel.h"
  44.  
  45. #include "../net/route.h"
  46.  
  47. #include "ns.h"
  48. #include "ns_pcb.h"
  49. #include "idp.h"
  50. #include "ns_error.h"
  51.  
  52. #ifdef lint
  53. #define NS_ERRPRINTFS 1
  54. #endif
  55.  
  56. #ifdef NS_ERRPRINTFS
  57. /*
  58.  * NS_ERR routines: error generation, receive packet processing, and
  59.  * routines to turnaround packets back to the originator.
  60.  */
  61. int    ns_errprintfs = 0;
  62. #endif
  63.  
  64. ns_err_x(c)
  65. {
  66.     register u_short *w, *lim, *base = ns_errstat.ns_es_codes;
  67.     u_short x = c;
  68.  
  69.     /*
  70.      * zero is a legit error code, handle specially
  71.      */
  72.     if (x == 0)
  73.         return (0);
  74.     lim = base + NS_ERR_MAX - 1;
  75.     for (w = base + 1; w < lim; w++) {
  76.         if (*w == 0)
  77.             *w = x;
  78.         if (*w == x)
  79.             break;
  80.     }
  81.     return (w - base);
  82. }
  83.  
  84. /*
  85.  * Generate an error packet of type error
  86.  * in response to bad packet.
  87.  */
  88.  
  89. ns_error(om, type, param)
  90.     struct mbuf *om;
  91.     int type;
  92. {
  93.     register struct ns_epidp *ep;
  94.     struct mbuf *m;
  95.     struct idp *nip;
  96.     register struct idp *oip = mtod(om, struct idp *);
  97.     extern int idpcksum;
  98.  
  99.     /*
  100.      * If this packet was sent to the echo port,
  101.      * and nobody was there, just echo it.
  102.      * (Yes, this is a wart!)
  103.      */
  104.     if (type == NS_ERR_NOSOCK &&
  105.         oip->idp_dna.x_port == htons(2) &&
  106.         (type = ns_echo(om))==0)
  107.         return;
  108.  
  109. #ifdef NS_ERRPRINTFS
  110.     if (ns_errprintfs)
  111.         printf("ns_err_error(%x, %d, %d)\n", oip, type, param);
  112. #endif
  113.     /*
  114.      * Don't Generate error packets in response to multicasts.
  115.      */
  116.     if (oip->idp_dna.x_host.c_host[0] & 1)
  117.         goto freeit;
  118.  
  119.     ns_errstat.ns_es_error++;
  120.     /*
  121.      * Make sure that the old IDP packet had 30 bytes of data to return;
  122.      * if not, don't bother.  Also don't EVER error if the old
  123.      * packet protocol was NS_ERR.
  124.      */
  125.     if (oip->idp_len < sizeof(struct idp)) {
  126.         ns_errstat.ns_es_oldshort++;
  127.         goto freeit;
  128.     }
  129.     if (oip->idp_pt == NSPROTO_ERROR) {
  130.         ns_errstat.ns_es_oldns_err++;
  131.         goto freeit;
  132.     }
  133.  
  134.     /*
  135.      * First, formulate ns_err message
  136.      */
  137.     m = m_gethdr(M_DONTWAIT, MT_HEADER);
  138.     if (m == NULL)
  139.         goto freeit;
  140.     m->m_len = sizeof(*ep);
  141.     MH_ALIGN(m, m->m_len);
  142.     ep = mtod(m, struct ns_epidp *);
  143.     if ((u_int)type > NS_ERR_TOO_BIG)
  144.         panic("ns_err_error");
  145.     ns_errstat.ns_es_outhist[ns_err_x(type)]++;
  146.     ep->ns_ep_errp.ns_err_num = htons((u_short)type);
  147.     ep->ns_ep_errp.ns_err_param = htons((u_short)param);
  148.     bcopy((caddr_t)oip, (caddr_t)&ep->ns_ep_errp.ns_err_idp, 42);
  149.     nip = &ep->ns_ep_idp;
  150.     nip->idp_len = sizeof(*ep);
  151.     nip->idp_len = htons((u_short)nip->idp_len);
  152.     nip->idp_pt = NSPROTO_ERROR;
  153.     nip->idp_tc = 0;
  154.     nip->idp_dna = oip->idp_sna;
  155.     nip->idp_sna = oip->idp_dna;
  156.     if (idpcksum) {
  157.         nip->idp_sum = 0;
  158.         nip->idp_sum = ns_cksum(m, sizeof(*ep));
  159.     } else 
  160.         nip->idp_sum = 0xffff;
  161.     (void) ns_output(m, (struct route *)0, 0);
  162.  
  163. freeit:
  164.     m_freem(om);
  165. }
  166.  
  167. ns_printhost(p)
  168. register struct ns_addr *p;
  169. {
  170.  
  171.     printf("<net:%x%x,host:%x%x%x,port:%x>",
  172.             p->x_net.s_net[0],
  173.             p->x_net.s_net[1],
  174.             p->x_host.s_host[0],
  175.             p->x_host.s_host[1],
  176.             p->x_host.s_host[2],
  177.             p->x_port);
  178.  
  179. }
  180.  
  181. /*
  182.  * Process a received NS_ERR message.
  183.  */
  184. ns_err_input(m)
  185.     struct mbuf *m;
  186. {
  187.     register struct ns_errp *ep;
  188.     register struct ns_epidp *epidp = mtod(m, struct ns_epidp *);
  189.     register int i;
  190.     int type, code, param;
  191.  
  192.     /*
  193.      * Locate ns_err structure in mbuf, and check
  194.      * that not corrupted and of at least minimum length.
  195.      */
  196. #ifdef NS_ERRPRINTFS
  197.     if (ns_errprintfs) {
  198.         printf("ns_err_input from ");
  199.         ns_printhost(&epidp->ns_ep_idp.idp_sna);
  200.         printf("len %d\n", ntohs(epidp->ns_ep_idp.idp_len));
  201.     }
  202. #endif
  203.     i = sizeof (struct ns_epidp);
  204.      if (((m->m_flags & M_EXT) || m->m_len < i) &&
  205.          (m = m_pullup(m, i)) == 0)  {
  206.         ns_errstat.ns_es_tooshort++;
  207.         return;
  208.     }
  209.     ep = &(mtod(m, struct ns_epidp *)->ns_ep_errp);
  210.     type = ntohs(ep->ns_err_num);
  211.     param = ntohs(ep->ns_err_param);
  212.     ns_errstat.ns_es_inhist[ns_err_x(type)]++;
  213.  
  214. #ifdef NS_ERRPRINTFS
  215.     /*
  216.      * Message type specific processing.
  217.      */
  218.     if (ns_errprintfs)
  219.         printf("ns_err_input, type %d param %d\n", type, param);
  220. #endif
  221.     if (type >= NS_ERR_TOO_BIG) {
  222.         goto badcode;
  223.     }
  224.     ns_errstat.ns_es_outhist[ns_err_x(type)]++;
  225.     switch (type) {
  226.  
  227.     case NS_ERR_UNREACH_HOST:
  228.         code = PRC_UNREACH_NET;
  229.         goto deliver;
  230.  
  231.     case NS_ERR_TOO_OLD:
  232.         code = PRC_TIMXCEED_INTRANS;
  233.         goto deliver;
  234.  
  235.     case NS_ERR_TOO_BIG:
  236.         code = PRC_MSGSIZE;
  237.         goto deliver;
  238.  
  239.     case NS_ERR_FULLUP:
  240.         code = PRC_QUENCH;
  241.         goto deliver;
  242.  
  243.     case NS_ERR_NOSOCK:
  244.         code = PRC_UNREACH_PORT;
  245.         goto deliver;
  246.  
  247.     case NS_ERR_UNSPEC_T:
  248.     case NS_ERR_BADSUM_T:
  249.     case NS_ERR_BADSUM:
  250.     case NS_ERR_UNSPEC:
  251.         code = PRC_PARAMPROB;
  252.         goto deliver;
  253.  
  254.     deliver:
  255.         /*
  256.          * Problem with datagram; advise higher level routines.
  257.          */
  258. #ifdef NS_ERRPRINTFS
  259.         if (ns_errprintfs)
  260.             printf("deliver to protocol %d\n",
  261.                        ep->ns_err_idp.idp_pt);
  262. #endif
  263.         switch(ep->ns_err_idp.idp_pt) {
  264.         case NSPROTO_SPP:
  265.             spp_ctlinput(code, (caddr_t)ep);
  266.             break;
  267.  
  268.         default:
  269.             idp_ctlinput(code, (caddr_t)ep);
  270.         }
  271.         
  272.         goto freeit;
  273.  
  274.     default:
  275.     badcode:
  276.         ns_errstat.ns_es_badcode++;
  277.         goto freeit;
  278.  
  279.     }
  280. freeit:
  281.     m_freem(m);
  282. }
  283.  
  284. #ifdef notdef
  285. u_long
  286. nstime()
  287. {
  288.     int s = splclock();
  289.     u_long t;
  290.  
  291.     t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000;
  292.     splx(s);
  293.     return (htonl(t));
  294. }
  295. #endif
  296.  
  297. ns_echo(m)
  298. struct mbuf *m;
  299. {
  300.     register struct idp *idp = mtod(m, struct idp *);
  301.     register struct echo {
  302.         struct idp    ec_idp;
  303.         u_short        ec_op; /* Operation, 1 = request, 2 = reply */
  304.     } *ec = (struct echo *)idp;
  305.     struct ns_addr temp;
  306.  
  307.     if (idp->idp_pt!=NSPROTO_ECHO) return(NS_ERR_NOSOCK);
  308.     if (ec->ec_op!=htons(1)) return(NS_ERR_UNSPEC);
  309.  
  310.     ec->ec_op = htons(2);
  311.  
  312.     temp = idp->idp_dna;
  313.     idp->idp_dna = idp->idp_sna;
  314.     idp->idp_sna = temp;
  315.  
  316.     if (idp->idp_sum != 0xffff) {
  317.         idp->idp_sum = 0;
  318.         idp->idp_sum = ns_cksum(m,
  319.             (int)(((ntohs(idp->idp_len) - 1)|1)+1));
  320.     }
  321.     (void) ns_output(m, (struct route *)0, NS_FORWARDING);
  322.     return(0);
  323. }
  324.