|
|
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.