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