1 /* ns_error.c 6.1 85/05/30 */ 2 3 #include "param.h" 4 #include "systm.h" 5 #include "mbuf.h" 6 #include "protosw.h" 7 #include "socket.h" 8 #include "time.h" 9 #include "kernel.h" 10 11 #include "../net/route.h" 12 13 #include "ns.h" 14 #include "ns_pcb.h" 15 #include "idp.h" 16 #include "ns_error.h" 17 18 #define NS_ERRPRINTFS 19 #ifdef NS_ERRPRINTFS 20 /* 21 * NS_ERR routines: error generation, receive packet processing, and 22 * routines to turnaround packets back to the originator, and 23 * host table maintenance routines. 24 */ 25 int ns_errprintfs = 0; 26 #endif 27 28 /* 29 * Generate an error packet of type error 30 * in response to bad packet. 31 */ 32 33 ns_error(om, type, param) 34 struct mbuf *om; 35 int type; 36 { 37 register struct ns_epidp *ep; 38 struct mbuf *m; 39 struct idp *nip; 40 register struct idp *oip = mtod(om, struct idp *); 41 extern int idpcksum; 42 43 #ifdef NS_ERRPRINTFS 44 if (ns_errprintfs) 45 printf("ns_err_error(%x, %d, %d)\n", oip, type, param); 46 #endif 47 ns_errstat.ns_es_error++; 48 /* 49 * Make sure that the old IDP packet had 30 bytes of data to return; 50 * if not, don't bother. Also don't EVER error if the old 51 * packet protocol was NS_ERR. 52 */ 53 if (oip->idp_len < sizeof(struct idp)) { 54 ns_errstat.ns_es_oldshort++; 55 goto free; 56 } 57 if (oip->idp_pt == NSPROTO_ERROR) { 58 ns_errstat.ns_es_oldns_err++; 59 goto free; 60 } 61 62 /* 63 * First, formulate ns_err message 64 */ 65 m = m_get(M_DONTWAIT, MT_HEADER); 66 if (m == NULL) 67 goto free; 68 m->m_len = sizeof(*ep); 69 m->m_off = MMAXOFF - m->m_len; 70 ep = mtod(m, struct ns_epidp *); 71 if ((u_int)type > NS_ERR_TOO_BIG) 72 panic("ns_err_error"); 73 ns_errstat.ns_es_outhist[ns_err_x(type)]++; 74 ep->ns_ep_errp.ns_err_num = htons(type); 75 ep->ns_ep_errp.ns_err_param = htons(param); 76 bcopy((caddr_t)oip, (caddr_t)&ep->ns_ep_errp.ns_err_idp, 42); 77 nip = &ep->ns_ep_idp; 78 nip->idp_len = sizeof(*ep); 79 nip->idp_len = htons((u_short)nip->idp_len); 80 nip->idp_pt = NSPROTO_ERROR; 81 nip->idp_tc = 0; 82 nip->idp_dna = oip->idp_sna; 83 nip->idp_sna = oip->idp_dna; 84 if (idpcksum) { 85 nip->idp_sum = 0; 86 nip->idp_sum = ns_cksum(dtom(nip), sizeof(*ep)); 87 } else 88 nip->idp_sum = 0xffff; 89 ns_output(dtom(nip), (struct route *)0, 0); 90 91 free: 92 m_freem(dtom(oip)); 93 } 94 95 static struct sockproto ns_errroto = { AF_NS, NSPROTO_ERROR }; 96 static struct sockaddr_ns ns_errsrc = { AF_NS }; 97 static struct sockaddr_ns ns_errdst = { AF_NS }; 98 99 ns_printhost(p) 100 register struct ns_addr *p; 101 { 102 103 printf("<net:%x%x,host:%x%x%x,port:%x>", 104 p->x_net.s_net[0], 105 p->x_net.s_net[1], 106 p->x_host.s_host[0], 107 p->x_host.s_host[1], 108 p->x_host.s_host[2], 109 p->x_port); 110 111 } 112 113 /* 114 * Process a received NS_ERR message. 115 */ 116 ns_err_input(m) 117 struct mbuf *m; 118 { 119 register struct ns_errp *ep; 120 register struct ns_epidp *epidp = mtod(m, struct ns_epidp *); 121 register int i; 122 int type, code, param; 123 extern struct ns_addr if_makeaddr(); 124 125 /* 126 * Locate ns_err structure in mbuf, and check 127 * that not corrupted and of at least minimum length. 128 */ 129 #ifdef NS_ERRPRINTFS 130 if (ns_errprintfs) { 131 printf("ns_err_input from "); 132 ns_printhost(&epidp->ns_ep_idp.idp_sna); 133 printf("len %d\n", ntohs(epidp->ns_ep_idp.idp_len)); 134 } 135 #endif 136 i = sizeof (struct ns_epidp); 137 if ((m->m_off > MMAXOFF || m->m_len < i) && 138 (m = m_pullup(m, i)) == 0) { 139 ns_errstat.ns_es_tooshort++; 140 return; 141 } 142 ep = &(mtod(m, struct ns_epidp *)->ns_ep_errp); 143 type = ntohs(ep->ns_err_num); 144 param = ntohs(ep->ns_err_param); 145 146 #ifdef NS_ERRPRINTFS 147 /* 148 * Message type specific processing. 149 */ 150 if (ns_errprintfs) 151 printf("ns_err_input, type %d param %d\n", type, param); 152 #endif 153 if (type >= NS_ERR_TOO_BIG) { 154 goto badcode; 155 } 156 ns_errstat.ns_es_outhist[ns_err_x(type)]++; 157 switch (type) { 158 159 case NS_ERR_UNREACH_HOST: 160 code = PRC_UNREACH_NET; 161 goto deliver; 162 163 case NS_ERR_TOO_OLD: 164 code = PRC_TIMXCEED_INTRANS; 165 goto deliver; 166 167 case NS_ERR_TOO_BIG: 168 code = PRC_MSGSIZE; 169 goto deliver; 170 171 case NS_ERR_FULLUP: 172 code = PRC_QUENCH; 173 goto deliver; 174 175 case NS_ERR_NOSOCK: 176 code = PRC_UNREACH_PORT; 177 goto deliver; 178 179 case NS_ERR_UNSPEC_T: 180 case NS_ERR_BADSUM_T: 181 case NS_ERR_BADSUM: 182 case NS_ERR_UNSPEC: 183 code = PRC_PARAMPROB; 184 goto deliver; 185 186 deliver: 187 /* 188 * Problem with datagram; advise higher level routines. 189 */ 190 #ifdef NS_ERRPRINTFS 191 if (ns_errprintfs) 192 printf("deliver to protocol %d\n", 193 ep->ns_err_idp.idp_pt); 194 #endif 195 switch(ep->ns_err_idp.idp_pt) { 196 case NSPROTO_SPP: 197 spp_ctlinput(code, (caddr_t)ep); 198 break; 199 200 default: 201 idp_ctlinput(code, (caddr_t)ep); 202 } 203 204 goto free; 205 206 default: 207 badcode: 208 ns_errstat.ns_es_badcode++; 209 goto free; 210 211 } 212 free: 213 m_freem(m); 214 } 215 u_long 216 nstime() 217 { 218 int s = spl6(); 219 u_long t; 220 221 t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000; 222 splx(s); 223 return (htonl(t)); 224 } 225