Commit | Line | Data |
---|---|---|
986fd057 KS |
1 | /*********************************************************** |
2 | Copyright IBM Corporation 1987 | |
3 | ||
4 | All Rights Reserved | |
5 | ||
6 | Permission to use, copy, modify, and distribute this software and its | |
7 | documentation for any purpose and without fee is hereby granted, | |
8 | provided that the above copyright notice appear in all copies and that | |
9 | both that copyright notice and this permission notice appear in | |
10 | supporting documentation, and that the name of IBM not be | |
11 | used in advertising or publicity pertaining to distribution of the | |
12 | software without specific, written prior permission. | |
13 | ||
14 | IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
15 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
16 | IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
17 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
18 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
19 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
20 | SOFTWARE. | |
21 | ||
22 | ******************************************************************/ | |
23 | ||
24 | /* | |
25 | * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison | |
26 | */ | |
27 | /* $Header: clnp_raw.c,v 4.2 88/06/29 14:58:56 hagens Exp $ */ | |
28 | /* $Source: /usr/argo/sys/netiso/RCS/clnp_raw.c,v $ */ | |
29 | #ifndef lint | |
30 | static char *rcsid = "$Header: clnp_raw.c,v 4.2 88/06/29 14:58:56 hagens Exp $"; | |
31 | #endif lint | |
32 | ||
33 | #ifdef ISO | |
34 | ||
35 | #include "../h/types.h" | |
36 | #include "../h/param.h" | |
37 | #include "../h/mbuf.h" | |
38 | #include "../h/domain.h" | |
39 | #include "../h/protosw.h" | |
40 | #include "../h/socket.h" | |
41 | #include "../h/socketvar.h" | |
42 | #include "../h/errno.h" | |
43 | #include "../h/time.h" | |
44 | ||
45 | #include "../net/if.h" | |
46 | #include "../net/route.h" | |
47 | #include "../net/raw_cb.h" | |
48 | ||
49 | #include "../netiso/iso.h" | |
50 | #include "../netiso/iso_pcb.h" | |
51 | #include "../netiso/clnp.h" | |
52 | #include "../netiso/clnp_stat.h" | |
53 | #include "../netiso/argo_debug.h" | |
54 | ||
55 | struct sockaddr_iso rclnp_src = { AF_ISO }; | |
56 | struct sockaddr_iso rclnp_dst = { AF_ISO }; | |
57 | struct sockproto rclnp_proto = { PF_ISO, 0 }; | |
58 | /* | |
59 | * FUNCTION: rclnp_input | |
60 | * | |
61 | * PURPOSE: Setup generic address an protocol structures for | |
62 | * raw input routine, then pass them along with the | |
63 | * mbuf chain. | |
64 | * | |
65 | * RETURNS: none | |
66 | * | |
67 | * SIDE EFFECTS: | |
68 | * | |
69 | * NOTES: The protocol field of rclnp_proto is set to zero indicating | |
70 | * no protocol. | |
71 | */ | |
72 | rclnp_input(m, src, dst, hdrlen) | |
73 | struct mbuf *m; /* ptr to packet */ | |
74 | struct iso_addr *src; /* ptr to src address */ | |
75 | struct iso_addr *dst; /* ptr to dest address */ | |
76 | int hdrlen; /* length (in bytes) of clnp header */ | |
77 | { | |
78 | #ifdef TROLL | |
79 | if (trollctl.tr_ops & TR_CHUCK) { | |
80 | m_freem(m); | |
81 | return; | |
82 | } | |
83 | #endif TROLL | |
84 | ||
85 | rclnp_src.siso_addr = *src; | |
86 | rclnp_dst.siso_addr = *dst; | |
87 | raw_input(m, &rclnp_proto, (struct sockaddr *)&rclnp_src, | |
88 | (struct sockaddr *)&rclnp_dst); | |
89 | } | |
90 | ||
91 | /* | |
92 | * FUNCTION: rclnp_output | |
93 | * | |
94 | * PURPOSE: Prepare to send a raw clnp packet. Setup src and dest | |
95 | * addresses, count the number of bytes to send, and | |
96 | * call clnp_output. | |
97 | * | |
98 | * RETURNS: success - 0 | |
99 | * failure - an appropriate error code | |
100 | * | |
101 | * SIDE EFFECTS: | |
102 | * | |
103 | * NOTES: | |
104 | */ | |
105 | rclnp_output(m0, so) | |
106 | struct mbuf *m0; /* packet to send */ | |
107 | struct socket *so; /* socket to send from */ | |
108 | { | |
109 | register struct mbuf *m; /* used to scan a chain */ | |
110 | int len = 0; /* store length of chain here */ | |
111 | struct rawcb *rp = sotorawcb(so); /* ptr to raw cb */ | |
112 | int error; /* return value of function */ | |
113 | u_int flags; /* flags for clnp_output */ | |
114 | struct isopcb isopcb; /* isopcb used to interface w/clnp */ | |
115 | ||
116 | /* Calculate length of data */ | |
117 | for (m = m0; m; m = m->m_next) | |
118 | len += m->m_len; | |
119 | ||
120 | bzero((caddr_t)&isopcb, sizeof(isopcb)); | |
121 | ||
122 | /* | |
123 | * Set up src address. If user has bound socket to an address, use it. | |
124 | * Otherwise, do not specify src (clnp_output will fill it in). | |
125 | */ | |
126 | if (rp->rcb_flags & RAW_LADDR) { | |
127 | if (rp->rcb_laddr.sa_family != AF_ISO) { | |
128 | m_freem(m0); | |
129 | return(EAFNOSUPPORT); | |
130 | } | |
131 | bcopy((caddr_t)&rp->rcb_laddr, &isopcb.isop_laddr, | |
132 | sizeof(struct sockaddr_iso)); | |
133 | } | |
134 | ||
135 | /* set up route structure, if route is present */ | |
136 | if (rp->rcb_route.ro_rt != NULL) | |
137 | bcopy((caddr_t)&rp->rcb_route, (caddr_t)&isopcb.isop_route, | |
138 | sizeof(struct route)); | |
139 | ||
140 | /* set up dest address */ | |
141 | bcopy((caddr_t)&rp->rcb_faddr, &isopcb.isop_faddr, | |
142 | sizeof(struct sockaddr_iso)); | |
143 | ||
144 | /* | |
145 | * setup option index - this was done when option was set, but raw | |
146 | * cb has no place to put it. | |
147 | */ | |
148 | if (rp->rcb_options != NULL) { | |
149 | isopcb.isop_options = rp->rcb_options; | |
150 | isopcb.isop_optindex = m_get(M_WAIT, MT_SOOPTS); | |
151 | (void) clnp_opt_sanity(isopcb.isop_options, | |
152 | mtod(isopcb.isop_options, caddr_t), isopcb.isop_options->m_len, | |
153 | mtod(isopcb.isop_optindex, struct clnp_optidx *)); | |
154 | } | |
155 | ||
156 | /* get flags and ship it off */ | |
157 | flags = rp->rcb_flags & CLNP_VFLAGS; | |
158 | ||
159 | #ifdef TROLL | |
160 | if (trollctl.tr_ops & TR_BLAST) { | |
161 | register int i; | |
162 | struct timeval start, stop; | |
163 | extern struct timeval time; | |
164 | struct mbuf *mbuf_orig; | |
165 | ||
166 | mbuf_orig = m0; | |
167 | start = time; | |
168 | for (i=0; i<trollctl.tr_blast_cnt; i++) { | |
169 | m0 = m_copy(mbuf_orig, 0, M_COPYALL); | |
170 | if (m0 == NULL) { | |
171 | error = ENOBUFS; | |
172 | } else { | |
173 | error = clnp_output(m0, &isopcb, len, flags); | |
174 | } | |
175 | if (error) | |
176 | break; | |
177 | } | |
178 | stop = time; | |
179 | printf("rclnp_output: %d pkts in %d sec\n", i, | |
180 | stop.tv_sec - start.tv_sec); | |
181 | m_freem(mbuf_orig); | |
182 | } else { | |
183 | /* | |
184 | * Don't bother creating the cache since this is raw; probably | |
185 | * a one shot send | |
186 | */ | |
187 | error = clnp_output(m0, &isopcb, len, flags|CLNP_NOCACHE); | |
188 | } | |
189 | #else | |
190 | error = clnp_output(m0, &isopcb, len, flags|CLNP_NOCACHE); | |
191 | #endif TROLL | |
192 | ||
193 | if (isopcb.isop_route.ro_rt) | |
194 | RTFREE(isopcb.isop_route.ro_rt); | |
195 | ||
196 | /* free clnp cached hdr if necessary */ | |
197 | if (isopcb.isop_clnpcache != NULL) { | |
198 | struct clnp_cache *clcp = | |
199 | mtod(isopcb.isop_clnpcache, struct clnp_cache *); | |
200 | if (clcp->clc_hdr != NULL) { | |
201 | m_free(clcp->clc_hdr); | |
202 | } | |
203 | m_free(isopcb.isop_clnpcache); | |
204 | } | |
205 | ||
206 | if (isopcb.isop_optindex != NULL) | |
207 | m_free(isopcb.isop_optindex); | |
208 | ||
209 | return (error); | |
210 | } | |
211 | ||
212 | /* | |
213 | * FUNCTION: rclnp_ctloutput | |
214 | * | |
215 | * PURPOSE: Raw clnp socket option processing | |
216 | * All options are stored inside an mbuf. | |
217 | * | |
218 | * RETURNS: success - 0 | |
219 | * failure - unix error code | |
220 | * | |
221 | * SIDE EFFECTS: If the options mbuf does not exist, it the mbuf passed | |
222 | * is used. | |
223 | * | |
224 | * NOTES: | |
225 | */ | |
226 | rclnp_ctloutput(op, so, level, optname, m) | |
227 | int op; /* type of operation */ | |
228 | struct socket *so; /* ptr to socket */ | |
229 | int level; /* level of option */ | |
230 | int optname; /* name of option */ | |
231 | struct mbuf **m; /* ptr to ptr to option data */ | |
232 | { | |
233 | int error = 0; | |
234 | register struct rawcb *rp = sotorawcb(so);/* raw cb ptr */ | |
235 | ||
236 | IFDEBUG(D_CTLOUTPUT) | |
237 | printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n", | |
238 | op, level, optname); | |
239 | if (*m != NULL) { | |
240 | printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len); | |
241 | dump_buf(mtod((*m), caddr_t), (*m)->m_len); | |
242 | } | |
243 | ENDDEBUG | |
244 | ||
245 | #ifdef SOL_NETWORK | |
246 | if (level != SOL_NETWORK) | |
247 | error = EINVAL; | |
248 | else switch (op) { | |
249 | #else | |
250 | switch (op) { | |
251 | #endif SOL_NETWORK | |
252 | case PRCO_SETOPT: | |
253 | switch (optname) { | |
254 | case CLNPOPT_FLAGS: { | |
255 | u_short usr_flags; | |
256 | /* | |
257 | * Insure that the data passed has exactly one short in it | |
258 | */ | |
259 | if ((*m == NULL) || ((*m)->m_len != sizeof(short))) { | |
260 | error = EINVAL; | |
261 | break; | |
262 | } | |
263 | ||
264 | /* | |
265 | * Don't allow invalid flags to be set | |
266 | */ | |
267 | usr_flags = (*mtod((*m), short *)); | |
268 | ||
269 | if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) { | |
270 | error = EINVAL; | |
271 | } else | |
272 | rp->rcb_flags |= usr_flags; | |
273 | ||
274 | } break; | |
275 | ||
276 | case CLNPOPT_OPTS: | |
277 | error = clnp_set_opts(&rp->rcb_options, m); | |
278 | break; | |
279 | } | |
280 | break; | |
281 | ||
282 | case PRCO_GETOPT: | |
283 | #ifdef notdef | |
284 | /* commented out to keep hi C quiet */ | |
285 | switch (optname) { | |
286 | default: | |
287 | error = EINVAL; | |
288 | break; | |
289 | } | |
290 | #endif notdef | |
291 | break; | |
292 | default: | |
293 | error = EINVAL; | |
294 | break; | |
295 | } | |
296 | if (op == PRCO_SETOPT) { | |
297 | /* note: m_freem does not barf is *m is NULL */ | |
298 | m_freem(*m); | |
299 | *m = NULL; | |
300 | } | |
301 | ||
302 | return error; | |
303 | } | |
304 | ||
305 | /*ARGSUSED*/ | |
306 | clnp_usrreq(so, req, m, nam, rights) | |
307 | struct socket *so; | |
308 | int req; | |
309 | struct mbuf *m, *nam, *rights; | |
310 | { | |
311 | return EPROTOTYPE; | |
312 | } | |
313 | #endif ISO |