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