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