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