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