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