fix argument handling
[unix-history] / usr / src / sys / netns / ns_error.c
CommitLineData
8ae0e4b4 1/*
79b7ed8c 2 * Copyright (c) 1984, 1985 Regents of the University of California.
8ae0e4b4
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
8011f5df 6 * @(#)ns_error.c 6.7 (Berkeley) %G%
8ae0e4b4 7 */
bedb3747
KS
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
f97be0c9
KS
24#ifdef lint
25#define NS_ERRPRINTFS 1
26#endif
27
bedb3747
KS
28#ifdef NS_ERRPRINTFS
29/*
30 * NS_ERR routines: error generation, receive packet processing, and
233a75ef 31 * routines to turnaround packets back to the originator.
bedb3747
KS
32 */
33int ns_errprintfs = 0;
34#endif
35
36/*
37 * Generate an error packet of type error
38 * in response to bad packet.
39 */
40
41ns_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
233a75ef
KS
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
bedb3747
KS
61#ifdef NS_ERRPRINTFS
62 if (ns_errprintfs)
63 printf("ns_err_error(%x, %d, %d)\n", oip, type, param);
64#endif
9fa7f9e6
KS
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
bedb3747
KS
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)]++;
f97be0c9
KS
98 ep->ns_ep_errp.ns_err_num = htons((u_short)type);
99 ep->ns_ep_errp.ns_err_param = htons((u_short)param);
bedb3747
KS
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;
f97be0c9 113 (void) ns_output(dtom(nip), (struct route *)0, 0);
bedb3747
KS
114
115free:
116 m_freem(dtom(oip));
117}
118
bedb3747
KS
119ns_printhost(p)
120register 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 */
136ns_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;
bedb3747
KS
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);
9fa7f9e6 164 ns_errstat.ns_es_inhist[ns_err_x(type)]++;
bedb3747
KS
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 }
232free:
233 m_freem(m);
234}
233a75ef 235
bedb3747
KS
236u_long
237nstime()
238{
239 int s = spl6();
240 u_long t;
241
242 t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000;
243 splx(s);
244 return (htonl(t));
245}
233a75ef
KS
246
247ns_echo(idp)
248register struct idp *idp;
249{
250 struct mbuf *m = dtom(idp);
251 register struct echo {
252 struct idp ec_idp;
253 u_short ec_op; /* Operation, 1 = request, 2 = reply */
254 } *ec = (struct echo *)idp;
255 struct ns_addr temp;
256
257 if (idp->idp_pt!=NSPROTO_ECHO) return(NS_ERR_NOSOCK);
258 if (ec->ec_op!=htons(1)) return(NS_ERR_UNSPEC);
259
260 ec->ec_op = htons(2);
261
262 temp = idp->idp_dna;
263 idp->idp_dna = idp->idp_sna;
264 idp->idp_sna = temp;
265
266 if (idp->idp_sum != 0xffff) {
267 idp->idp_sum = 0;
268 idp->idp_sum = ns_cksum(m, (((ntohs(idp->idp_len) - 1)|1)+1));
269 }
8011f5df 270 (void) ns_output(m, (struct route *)0, NS_FORWARDING);
233a75ef
KS
271 return(0);
272}