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

Defined functions

ns_echo defined in line 276; used 1 times
  • in line 85
ns_err_input defined in line 163; never used
ns_err_x defined in line 43; used 3 times
ns_error defined in line 68; never used
ns_printhost defined in line 146; used 1 times
nstime defined in line 264; never used

Defined variables

ns_errprintfs defined in line 40; used 4 times

Defined struct's

echo defined in line 280; used 2 times
  • in line 283(2)

Defined macros

NS_ERRPRINTFS defined in line 32; used 5 times
Last modified: 1988-04-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3671
Valid CSS Valid XHTML 1.0 Strict