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