|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright IBM Corporation 1987 ! 3: ! 4: All Rights Reserved ! 5: ! 6: Permission to use, copy, modify, and distribute this software and its ! 7: documentation for any purpose and without fee is hereby granted, ! 8: provided that the above copyright notice appear in all copies and that ! 9: both that copyright notice and this permission notice appear in ! 10: supporting documentation, and that the name of IBM not be ! 11: used in advertising or publicity pertaining to distribution of the ! 12: software without specific, written prior permission. ! 13: ! 14: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 15: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 16: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 17: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 18: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 19: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 20: SOFTWARE. ! 21: ! 22: ******************************************************************/ ! 23: ! 24: /* ! 25: * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison ! 26: */ ! 27: /* $Header: /var/src/sys/netiso/RCS/clnp_er.c,v 5.1 89/02/09 16:20:18 hagens Exp $ */ ! 28: /* $Source: /var/src/sys/netiso/RCS/clnp_er.c,v $ */ ! 29: /* @(#)clnp_er.c 7.6 (Berkeley) 4/5/90 */ ! 30: ! 31: #ifndef lint ! 32: static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_er.c,v 5.1 89/02/09 16:20:18 hagens Exp $"; ! 33: #endif lint ! 34: ! 35: #include "param.h" ! 36: #include "mbuf.h" ! 37: #include "domain.h" ! 38: #include "protosw.h" ! 39: #include "socket.h" ! 40: #include "socketvar.h" ! 41: #include "errno.h" ! 42: ! 43: #include "../net/if.h" ! 44: #include "../net/route.h" ! 45: ! 46: #include "iso.h" ! 47: #include "iso_var.h" ! 48: #include "iso_pcb.h" ! 49: #define CLNP_ER_CODES ! 50: #include "clnp.h" ! 51: #include "clnp_stat.h" ! 52: #include "argo_debug.h" ! 53: ! 54: static struct clnp_fixed er_template = { ! 55: ISO8473_CLNP, /* network identifier */ ! 56: 0, /* length */ ! 57: ISO8473_V1, /* version */ ! 58: CLNP_TTL, /* ttl */ ! 59: CLNP_ER, /* type */ ! 60: 0, /* segment length */ ! 61: 0 /* checksum */ ! 62: }; ! 63: ! 64: /* ! 65: * FUNCTION: clnp_er_input ! 66: * ! 67: * PURPOSE: Process an ER pdu. ! 68: * ! 69: * RETURNS: ! 70: * ! 71: * SIDE EFFECTS: ! 72: * ! 73: * NOTES: ! 74: */ ! 75: clnp_er_input(m, src, reason) ! 76: struct mbuf *m; /* ptr to packet itself */ ! 77: struct iso_addr *src; /* ptr to src of er */ ! 78: u_char reason; /* reason code of er */ ! 79: { ! 80: int cmd = -1; ! 81: extern u_char clnp_protox[]; ! 82: ! 83: IFDEBUG(D_CTLINPUT) ! 84: printf("clnp_er_input: m x%x, src %s, reason x%x\n", m, ! 85: clnp_iso_addrp(src), reason); ! 86: ENDDEBUG ! 87: ! 88: INCSTAT(cns_er_inhist[clnp_er_index(reason)]); ! 89: switch (reason) { ! 90: case GEN_NOREAS: ! 91: case GEN_PROTOERR: ! 92: break; ! 93: case GEN_BADCSUM: ! 94: cmd = PRC_PARAMPROB; ! 95: break; ! 96: case GEN_CONGEST: ! 97: cmd = PRC_QUENCH; ! 98: break; ! 99: case GEN_HDRSYNTAX: ! 100: cmd = PRC_PARAMPROB; ! 101: break; ! 102: case GEN_SEGNEEDED: ! 103: cmd = PRC_MSGSIZE; ! 104: break; ! 105: case GEN_INCOMPLETE: ! 106: cmd = PRC_PARAMPROB; ! 107: break; ! 108: case GEN_DUPOPT: ! 109: cmd = PRC_PARAMPROB; ! 110: break; ! 111: case ADDR_DESTUNREACH: ! 112: cmd = PRC_UNREACH_HOST; ! 113: break; ! 114: case ADDR_DESTUNKNOWN: ! 115: cmd = PRC_UNREACH_PROTOCOL; ! 116: break; ! 117: case SRCRT_UNSPECERR: ! 118: case SRCRT_SYNTAX: ! 119: case SRCRT_UNKNOWNADDR: ! 120: case SRCRT_BADPATH: ! 121: cmd = PRC_UNREACH_SRCFAIL; ! 122: break; ! 123: case TTL_EXPTRANSIT: ! 124: cmd = PRC_TIMXCEED_INTRANS; ! 125: break; ! 126: case TTL_EXPREASS: ! 127: cmd = PRC_TIMXCEED_REASS; ! 128: break; ! 129: case DISC_UNSUPPOPT: ! 130: case DISC_UNSUPPVERS: ! 131: case DISC_UNSUPPSECURE: ! 132: case DISC_UNSUPPSRCRT: ! 133: case DISC_UNSUPPRECRT: ! 134: cmd = PRC_PARAMPROB; ! 135: break; ! 136: case REASS_INTERFERE: ! 137: cmd = PRC_TIMXCEED_REASS; ! 138: break; ! 139: } ! 140: ! 141: /* ! 142: * tpclnp_ctlinput1 is called directly so that we don't ! 143: * have to build an iso_sockaddr out of src. ! 144: */ ! 145: if (cmd >= 0) ! 146: tpclnp_ctlinput1(cmd, src); ! 147: ! 148: m_freem(m); ! 149: } ! 150: ! 151: /* ! 152: * FUNCTION: clnp_discard ! 153: * ! 154: * PURPOSE: Discard a clnp datagram ! 155: * ! 156: * RETURNS: nothing ! 157: * ! 158: * SIDE EFFECTS: Will emit an ER pdu if possible ! 159: * ! 160: * NOTES: This code assumes that we have previously tried to pull ! 161: * up the header of the datagram into one mbuf. ! 162: */ ! 163: clnp_discard(m, reason) ! 164: struct mbuf *m; /* header of packet to discard */ ! 165: char reason; /* reason for discard */ ! 166: { ! 167: IFDEBUG(D_DISCARD) ! 168: printf("clnp_discard: m x%x, reason x%x\n", m, reason); ! 169: ENDDEBUG ! 170: ! 171: if (m != NULL) { ! 172: if (m->m_len >= sizeof(struct clnp_fixed)) { ! 173: register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *); ! 174: ! 175: if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) && ! 176: (clnp->cnf_type & CNF_ERR_OK)) { ! 177: clnp_emit_er(m, reason); ! 178: return; ! 179: } ! 180: } ! 181: m_freem(m); ! 182: } ! 183: } ! 184: ! 185: /* ! 186: * FUNCTION: clnp_emit_er ! 187: * ! 188: * PURPOSE: Send an ER pdu. ! 189: * The src of the of the ER pdu is the host that is sending ! 190: * the ER (ie. us), *not* the original destination of the ! 191: * packet. ! 192: * ! 193: * RETURNS: nothing ! 194: * ! 195: * SIDE EFFECTS: ! 196: * ! 197: * NOTES: Takes responsibility for freeing mbuf passed ! 198: * This function may be called with a packet that ! 199: * was created by us; in this case, do not send ! 200: * an ER. ! 201: */ ! 202: clnp_emit_er(m, reason) ! 203: struct mbuf *m; /* header of packet to discard */ ! 204: char reason; /* reason for discard */ ! 205: { ! 206: register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *); ! 207: register struct clnp_fixed *er; ! 208: struct route_iso route; ! 209: struct ifnet *ifp; ! 210: struct sockaddr *first_hop; ! 211: struct iso_addr src, dst, *our_addr; ! 212: caddr_t hoff, hend; ! 213: int total_len; /* total len of dg */ ! 214: struct mbuf *m0; /* contains er pdu hdr */ ! 215: struct iso_ifaddr *ia = 0; ! 216: ! 217: IFDEBUG(D_DISCARD) ! 218: printf("clnp_emit_er: m x%x, hdr len %d\n", m, clnp->cnf_hdr_len); ! 219: ENDDEBUG ! 220: ! 221: bzero((caddr_t)&route, sizeof(route)); ! 222: ! 223: /* ! 224: * If header length is incorrect, or entire header is not contained ! 225: * in this mbuf, we punt ! 226: */ ! 227: if ((clnp->cnf_hdr_len < CLNP_HDR_MIN) || ! 228: (clnp->cnf_hdr_len > CLNP_HDR_MAX) || ! 229: (clnp->cnf_hdr_len > m->m_len)) ! 230: goto bad; ! 231: ! 232: /* extract src, dest address */ ! 233: hend = (caddr_t)clnp + clnp->cnf_hdr_len; ! 234: hoff = (caddr_t)clnp + sizeof(struct clnp_fixed); ! 235: CLNP_EXTRACT_ADDR(dst, hoff, hend); ! 236: if (hoff == (caddr_t)0) { ! 237: goto bad; ! 238: } ! 239: CLNP_EXTRACT_ADDR(src, hoff, hend); ! 240: if (hoff == (caddr_t)0) { ! 241: goto bad; ! 242: } ! 243: ! 244: /* ! 245: * Do not send ER if we generated the packet. ! 246: */ ! 247: if (clnp_ours(&src)) ! 248: goto bad; ! 249: ! 250: /* ! 251: * Trim mbuf to hold only the header. ! 252: * This mbuf will be the 'data' of the er pdu ! 253: */ ! 254: if (m->m_next != NULL) { ! 255: m_freem(m->m_next); ! 256: m->m_next = NULL; ! 257: } ! 258: ! 259: if (m->m_len > clnp->cnf_hdr_len) ! 260: m_adj(m, (int)-(m->m_len - (int)clnp->cnf_hdr_len)); ! 261: ! 262: /* route er pdu: note we send pkt to src of original packet */ ! 263: if (clnp_route(&src, &route, /* flags */0, &first_hop, &ia) != 0) ! 264: goto bad; ! 265: ! 266: /* compute our address based upon firsthop/ifp */ ! 267: if (ia) ! 268: our_addr = &ia->ia_addr.siso_addr; ! 269: else ! 270: goto bad; ! 271: ifp = ia->ia_ifp; ! 272: ! 273: IFDEBUG(D_DISCARD) ! 274: printf("clnp_emit_er: to %s", clnp_iso_addrp(&src)); ! 275: printf(" from %s\n", clnp_iso_addrp(our_addr)); ! 276: ENDDEBUG ! 277: ! 278: IFDEBUG(D_DISCARD) ! 279: printf("clnp_emit_er: packet routed to %s\n", ! 280: clnp_iso_addrp(&((struct sockaddr_iso *)first_hop)->siso_addr)); ! 281: ENDDEBUG ! 282: ! 283: /* allocate mbuf for er pdu header: punt on no space */ ! 284: MGET(m0, M_DONTWAIT, MT_HEADER); ! 285: if (m0 == 0) ! 286: goto bad; ! 287: ! 288: m0->m_next = m; ! 289: er = mtod(m0, struct clnp_fixed *); ! 290: *er = er_template; ! 291: ! 292: /* setup src/dst on er pdu */ ! 293: /* NOTE REVERSAL OF SRC/DST */ ! 294: hoff = (caddr_t)er + sizeof(struct clnp_fixed); ! 295: CLNP_INSERT_ADDR(hoff, src); ! 296: CLNP_INSERT_ADDR(hoff, *our_addr); ! 297: ! 298: /* ! 299: * TODO: if complete src rt was specified, then reverse path, and ! 300: * copy into er as option. ! 301: */ ! 302: ! 303: /* add er option */ ! 304: *hoff++ = CLNPOVAL_ERREAS; /* code */ ! 305: *hoff++ = 2; /* length */ ! 306: *hoff++ = reason; /* discard reason */ ! 307: *hoff++ = 0; /* error localization = not specified */ ! 308: ! 309: /* set length */ ! 310: er->cnf_hdr_len = m0->m_len = (u_char)(hoff - (caddr_t)er); ! 311: total_len = m0->m_len + m->m_len; ! 312: HTOC(er->cnf_seglen_msb, er->cnf_seglen_lsb, total_len); ! 313: ! 314: /* compute checksum (on header only) */ ! 315: iso_gen_csum(m0, CLNP_CKSUM_OFF, (int)er->cnf_hdr_len); ! 316: ! 317: /* trim packet if too large for interface */ ! 318: if (total_len > ifp->if_mtu) ! 319: m_adj(m0, -(total_len - ifp->if_mtu)); ! 320: ! 321: /* send packet */ ! 322: INCSTAT(cns_er_outhist[clnp_er_index(reason)]); ! 323: (void) (*ifp->if_output)(ifp, m0, first_hop, route.ro_rt); ! 324: goto done; ! 325: ! 326: bad: ! 327: m_freem(m); ! 328: ! 329: done: ! 330: /* free route if it is a temp */ ! 331: if (route.ro_rt != NULL) ! 332: RTFREE(route.ro_rt); ! 333: } ! 334: ! 335: clnp_er_index(p) ! 336: u_char p; ! 337: { ! 338: register u_char *cp = clnp_er_codes + CLNP_ERRORS; ! 339: while (cp > clnp_er_codes) { ! 340: cp--; ! 341: if (*cp == p) ! 342: return (cp - clnp_er_codes); ! 343: } ! 344: return (CLNP_ERRORS + 1); ! 345: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.