source: trunk/minix/servers/inet/generic/ip_ioctl.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 16.3 KB
Line 
1/*
2ip_ioctl.c
3
4Copyright 1995 Philip Homburg
5*/
6
7#include "inet.h"
8#include "buf.h"
9#include "event.h"
10#include "type.h"
11
12#include "arp.h"
13#include "assert.h"
14#include "clock.h"
15#include "icmp_lib.h"
16#include "ip.h"
17#include "ip_int.h"
18#include "ipr.h"
19
20THIS_FILE
21
22FORWARD int ip_checkopt ARGS(( ip_fd_t *ip_fd ));
23FORWARD void reply_thr_get ARGS(( ip_fd_t *ip_fd, size_t
24 reply, int for_ioctl ));
25FORWARD void report_addr ARGS(( ip_port_t *ip_port ));
26
27PUBLIC int ip_ioctl (fd, req)
28int fd;
29ioreq_t req;
30{
31 ip_fd_t *ip_fd;
32 ip_port_t *ip_port;
33 nwio_ipopt_t *ipopt;
34 nwio_ipopt_t oldopt, newopt;
35 nwio_ipconf2_t *ipconf2;
36 nwio_ipconf_t *ipconf;
37 nwio_route_t *route_ent;
38 acc_t *data;
39 int result;
40 unsigned int new_en_flags, new_di_flags,
41 old_en_flags, old_di_flags;
42 unsigned long new_flags;
43 int ent_no, r;
44 nwio_ipconf_t ipconf_var;
45
46 assert (fd>=0 && fd<=IP_FD_NR);
47 ip_fd= &ip_fd_table[fd];
48
49 assert (ip_fd->if_flags & IFF_INUSE);
50
51 switch (req)
52 {
53 case NWIOSIPOPT:
54 ip_port= ip_fd->if_port;
55
56 if (!(ip_port->ip_flags & IPF_IPADDRSET))
57 {
58 ip_fd->if_ioctl= NWIOSIPOPT;
59 ip_fd->if_flags |= IFF_IOCTL_IP;
60 return NW_SUSPEND;
61 }
62 ip_fd->if_flags &= ~IFF_IOCTL_IP;
63
64 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0,
65 sizeof(nwio_ipopt_t), TRUE);
66
67 data= bf_packIffLess (data, sizeof(nwio_ipopt_t));
68 assert (data->acc_length == sizeof(nwio_ipopt_t));
69
70 ipopt= (nwio_ipopt_t *)ptr2acc_data(data);
71 oldopt= ip_fd->if_ipopt;
72 newopt= *ipopt;
73
74 old_en_flags= oldopt.nwio_flags & 0xffff;
75 old_di_flags= (oldopt.nwio_flags >> 16) & 0xffff;
76 new_en_flags= newopt.nwio_flags & 0xffff;
77 new_di_flags= (newopt.nwio_flags >> 16) & 0xffff;
78 if (new_en_flags & new_di_flags)
79 {
80 bf_afree(data);
81 reply_thr_get (ip_fd, EBADMODE, TRUE);
82 return NW_OK;
83 }
84
85 /* NWIO_ACC_MASK */
86 if (new_di_flags & NWIO_ACC_MASK)
87 {
88 bf_afree(data);
89 reply_thr_get (ip_fd, EBADMODE, TRUE);
90 return NW_OK;
91 /* access modes can't be disable */
92 }
93
94 if (!(new_en_flags & NWIO_ACC_MASK))
95 new_en_flags |= (old_en_flags & NWIO_ACC_MASK);
96
97 /* NWIO_LOC_MASK */
98 if (!((new_en_flags|new_di_flags) & NWIO_LOC_MASK))
99 {
100 new_en_flags |= (old_en_flags & NWIO_LOC_MASK);
101 new_di_flags |= (old_di_flags & NWIO_LOC_MASK);
102 }
103
104 /* NWIO_BROAD_MASK */
105 if (!((new_en_flags|new_di_flags) & NWIO_BROAD_MASK))
106 {
107 new_en_flags |= (old_en_flags & NWIO_BROAD_MASK);
108 new_di_flags |= (old_di_flags & NWIO_BROAD_MASK);
109 }
110
111 /* NWIO_REM_MASK */
112 if (!((new_en_flags|new_di_flags) & NWIO_REM_MASK))
113 {
114 new_en_flags |= (old_en_flags & NWIO_REM_MASK);
115 new_di_flags |= (old_di_flags & NWIO_REM_MASK);
116 newopt.nwio_rem= oldopt.nwio_rem;
117 }
118
119 /* NWIO_PROTO_MASK */
120 if (!((new_en_flags|new_di_flags) & NWIO_PROTO_MASK))
121 {
122 new_en_flags |= (old_en_flags & NWIO_PROTO_MASK);
123 new_di_flags |= (old_di_flags & NWIO_PROTO_MASK);
124 newopt.nwio_proto= oldopt.nwio_proto;
125 }
126
127 /* NWIO_HDR_O_MASK */
128 if (!((new_en_flags|new_di_flags) & NWIO_HDR_O_MASK))
129 {
130 new_en_flags |= (old_en_flags & NWIO_HDR_O_MASK);
131 new_di_flags |= (old_di_flags & NWIO_HDR_O_MASK);
132 newopt.nwio_tos= oldopt.nwio_tos;
133 newopt.nwio_ttl= oldopt.nwio_ttl;
134 newopt.nwio_df= oldopt.nwio_df;
135 newopt.nwio_hdropt= oldopt.nwio_hdropt;
136 }
137
138 /* NWIO_RW_MASK */
139 if (!((new_en_flags|new_di_flags) & NWIO_RW_MASK))
140 {
141 new_en_flags |= (old_en_flags & NWIO_RW_MASK);
142 new_di_flags |= (old_di_flags & NWIO_RW_MASK);
143 }
144
145 new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags;
146
147 if ((new_flags & NWIO_RWDATONLY) && (new_flags &
148 (NWIO_REMANY|NWIO_PROTOANY|NWIO_HDR_O_ANY)))
149 {
150 bf_afree(data);
151 reply_thr_get(ip_fd, EBADMODE, TRUE);
152 return NW_OK;
153 }
154
155 if (ip_fd->if_flags & IFF_OPTSET)
156 ip_unhash_proto(ip_fd);
157
158 newopt.nwio_flags= new_flags;
159 ip_fd->if_ipopt= newopt;
160
161 result= ip_checkopt(ip_fd);
162
163 if (result<0)
164 ip_fd->if_ipopt= oldopt;
165
166 bf_afree(data);
167 reply_thr_get (ip_fd, result, TRUE);
168 return NW_OK;
169
170 case NWIOGIPOPT:
171 data= bf_memreq(sizeof(nwio_ipopt_t));
172
173 ipopt= (nwio_ipopt_t *)ptr2acc_data(data);
174
175 *ipopt= ip_fd->if_ipopt;
176
177 result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data,
178 TRUE);
179 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result,
180 (acc_t *)0, TRUE);
181
182 case NWIOSIPCONF2:
183 case NWIOSIPCONF:
184 ip_port= ip_fd->if_port;
185
186 if (req == NWIOSIPCONF2)
187 {
188 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0,
189 sizeof(*ipconf2), TRUE);
190 data= bf_packIffLess (data, sizeof(*ipconf2));
191 assert (data->acc_length == sizeof(*ipconf2));
192
193 ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data);
194
195 ipconf= &ipconf_var;
196 ipconf->nwic_flags= ipconf2->nwic_flags;
197 ipconf->nwic_ipaddr= ipconf2->nwic_ipaddr;
198 ipconf->nwic_netmask= ipconf2->nwic_netmask;
199 ipconf->nwic_flags &= ~NWIC_MTU_SET;
200 }
201 else
202 {
203 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0,
204 sizeof(*ipconf), TRUE);
205 data= bf_packIffLess (data, sizeof(*ipconf));
206 assert (data->acc_length == sizeof(*ipconf));
207
208 ipconf= (nwio_ipconf_t *)ptr2acc_data(data);
209 }
210 r= ip_setconf(ip_port-ip_port_table, ipconf);
211 bf_afree(data);
212 return (*ip_fd->if_put_userdata)(ip_fd-> if_srfd, r,
213 (acc_t *)0, TRUE);
214
215 case NWIOGIPCONF2:
216 ip_port= ip_fd->if_port;
217
218 if (!(ip_port->ip_flags & IPF_IPADDRSET))
219 {
220 ip_fd->if_ioctl= NWIOGIPCONF2;
221 ip_fd->if_flags |= IFF_IOCTL_IP;
222 return NW_SUSPEND;
223 }
224 ip_fd->if_flags &= ~IFF_IOCTL_IP;
225 data= bf_memreq(sizeof(nwio_ipconf_t));
226 ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data);
227 ipconf2->nwic_flags= NWIC_IPADDR_SET;
228 ipconf2->nwic_ipaddr= ip_port->ip_ipaddr;
229 ipconf2->nwic_netmask= ip_port->ip_subnetmask;
230 if (ip_port->ip_flags & IPF_NETMASKSET)
231 ipconf2->nwic_flags |= NWIC_NETMASK_SET;
232
233 result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data,
234 TRUE);
235 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result,
236 (acc_t *)0, TRUE);
237
238 case NWIOGIPCONF:
239 ip_port= ip_fd->if_port;
240
241 if (!(ip_port->ip_flags & IPF_IPADDRSET))
242 {
243 ip_fd->if_ioctl= NWIOGIPCONF;
244 ip_fd->if_flags |= IFF_IOCTL_IP;
245 return NW_SUSPEND;
246 }
247 ip_fd->if_flags &= ~IFF_IOCTL_IP;
248 data= bf_memreq(sizeof(*ipconf));
249 ipconf= (nwio_ipconf_t *)ptr2acc_data(data);
250 ipconf->nwic_flags= NWIC_IPADDR_SET;
251 ipconf->nwic_ipaddr= ip_port->ip_ipaddr;
252 ipconf->nwic_netmask= ip_port->ip_subnetmask;
253 if (ip_port->ip_flags & IPF_NETMASKSET)
254 ipconf->nwic_flags |= NWIC_NETMASK_SET;
255 ipconf->nwic_mtu= ip_port->ip_mtu;
256
257 result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data,
258 TRUE);
259 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result,
260 (acc_t *)0, TRUE);
261
262 case NWIOGIPOROUTE:
263 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,
264 0, sizeof(nwio_route_t), TRUE);
265 if (data == NULL)
266 {
267 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
268 EFAULT, NULL, TRUE);
269 }
270
271 data= bf_packIffLess (data, sizeof(nwio_route_t) );
272 route_ent= (nwio_route_t *)ptr2acc_data(data);
273 ent_no= route_ent->nwr_ent_no;
274 bf_afree(data);
275
276 data= bf_memreq(sizeof(nwio_route_t));
277 route_ent= (nwio_route_t *)ptr2acc_data(data);
278 result= ipr_get_oroute(ent_no, route_ent);
279 if (result < 0)
280 bf_afree(data);
281 else
282 {
283 assert(result == NW_OK);
284 result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0,
285 data, TRUE);
286 }
287 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
288 result, (acc_t *)0, TRUE);
289
290 case NWIOSIPOROUTE:
291 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,
292 0, sizeof(nwio_route_t), TRUE);
293 if (data == NULL)
294 {
295 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
296 EFAULT, NULL, TRUE);
297 }
298 if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET))
299 {
300 /* Interface is down, no changes allowed */
301 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
302 EINVAL, NULL, TRUE);
303 }
304
305 data= bf_packIffLess (data, sizeof(nwio_route_t) );
306 route_ent= (nwio_route_t *)ptr2acc_data(data);
307 result= ipr_add_oroute(ip_fd->if_port-ip_port_table,
308 route_ent->nwr_dest, route_ent->nwr_netmask,
309 route_ent->nwr_gateway, (time_t)0,
310 route_ent->nwr_dist, route_ent->nwr_mtu,
311 !!(route_ent->nwr_flags & NWRF_STATIC),
312 route_ent->nwr_pref, NULL);
313 bf_afree(data);
314
315 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
316 result, (acc_t *)0, TRUE);
317
318 case NWIODIPOROUTE:
319 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,
320 0, sizeof(nwio_route_t), TRUE);
321 if (data == NULL)
322 {
323 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
324 EFAULT, NULL, TRUE);
325 }
326
327 data= bf_packIffLess (data, sizeof(nwio_route_t) );
328 route_ent= (nwio_route_t *)ptr2acc_data(data);
329 result= ipr_del_oroute(ip_fd->if_port-ip_port_table,
330 route_ent->nwr_dest, route_ent->nwr_netmask,
331 route_ent->nwr_gateway,
332 !!(route_ent->nwr_flags & NWRF_STATIC));
333 bf_afree(data);
334
335 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
336 result, (acc_t *)0, TRUE);
337
338 case NWIOGIPIROUTE:
339 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,
340 0, sizeof(nwio_route_t), TRUE);
341 if (data == NULL)
342 {
343 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
344 EFAULT, NULL, TRUE);
345 }
346
347 data= bf_packIffLess (data, sizeof(nwio_route_t) );
348 route_ent= (nwio_route_t *)ptr2acc_data(data);
349 ent_no= route_ent->nwr_ent_no;
350 bf_afree(data);
351
352 data= bf_memreq(sizeof(nwio_route_t));
353 route_ent= (nwio_route_t *)ptr2acc_data(data);
354 result= ipr_get_iroute(ent_no, route_ent);
355 if (result < 0)
356 bf_afree(data);
357 else
358 {
359 assert(result == NW_OK);
360 result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0,
361 data, TRUE);
362 }
363 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
364 result, (acc_t *)0, TRUE);
365
366 case NWIOSIPIROUTE:
367 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,
368 0, sizeof(nwio_route_t), TRUE);
369 if (data == NULL)
370 {
371 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
372 EFAULT, NULL, TRUE);
373 }
374 if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET))
375 {
376 /* Interface is down, no changes allowed */
377 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
378 EINVAL, NULL, TRUE);
379 }
380
381 data= bf_packIffLess (data, sizeof(nwio_route_t) );
382 route_ent= (nwio_route_t *)ptr2acc_data(data);
383 result= ipr_add_iroute(ip_fd->if_port-ip_port_table,
384 route_ent->nwr_dest, route_ent->nwr_netmask,
385 route_ent->nwr_gateway,
386 (route_ent->nwr_flags & NWRF_UNREACHABLE) ?
387 IRTD_UNREACHABLE : route_ent->nwr_dist,
388 route_ent->nwr_mtu,
389 !!(route_ent->nwr_flags & NWRF_STATIC), NULL);
390 bf_afree(data);
391
392 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
393 result, (acc_t *)0, TRUE);
394
395 case NWIODIPIROUTE:
396 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,
397 0, sizeof(nwio_route_t), TRUE);
398 if (data == NULL)
399 {
400 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
401 EFAULT, NULL, TRUE);
402 }
403
404 data= bf_packIffLess (data, sizeof(nwio_route_t) );
405 route_ent= (nwio_route_t *)ptr2acc_data(data);
406 result= ipr_del_iroute(ip_fd->if_port-ip_port_table,
407 route_ent->nwr_dest, route_ent->nwr_netmask,
408 route_ent->nwr_gateway,
409 !!(route_ent->nwr_flags & NWRF_STATIC));
410 bf_afree(data);
411
412 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
413 result, (acc_t *)0, TRUE);
414
415 /* The following ARP ioctls are only valid if the
416 * underlying device is an ethernet.
417 */
418 case NWIOARPGIP:
419 case NWIOARPGNEXT:
420 case NWIOARPSIP:
421 case NWIOARPDIP:
422 ip_port= ip_fd->if_port;
423
424 if (ip_port->ip_dl_type != IPDL_ETH)
425 {
426 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
427 EBADIOCTL, (acc_t *)0, TRUE);
428 }
429 result= arp_ioctl(ip_port->ip_dl.dl_eth.de_port,
430 ip_fd->if_srfd, req, ip_fd->if_get_userdata,
431 ip_fd->if_put_userdata);
432 assert (result != SUSPEND);
433 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result,
434 (acc_t *)0, TRUE);
435
436 default:
437 break;
438 }
439 DBLOCK(1, printf("replying EBADIOCTL: 0x%x\n", req));
440 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, EBADIOCTL,
441 (acc_t *)0, TRUE);
442}
443
444PUBLIC void ip_hash_proto(ip_fd)
445ip_fd_t *ip_fd;
446{
447 ip_port_t *ip_port;
448 int hash;
449
450 ip_port= ip_fd->if_port;
451 if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOANY)
452 {
453 ip_fd->if_proto_next= ip_port->ip_proto_any;
454 ip_port->ip_proto_any= ip_fd;
455 }
456 else
457 {
458 hash= ip_fd->if_ipopt.nwio_proto & (IP_PROTO_HASH_NR-1);
459 ip_fd->if_proto_next= ip_port->ip_proto[hash];
460 ip_port->ip_proto[hash]= ip_fd;
461 }
462}
463
464PUBLIC void ip_unhash_proto(ip_fd)
465ip_fd_t *ip_fd;
466{
467 ip_port_t *ip_port;
468 ip_fd_t *prev, *curr, **ip_fd_p;
469 int hash;
470
471 ip_port= ip_fd->if_port;
472 if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOANY)
473 {
474 ip_fd_p= &ip_port->ip_proto_any;
475 }
476 else
477 {
478 hash= ip_fd->if_ipopt.nwio_proto & (IP_PROTO_HASH_NR-1);
479 ip_fd_p= &ip_port->ip_proto[hash];
480 }
481 for (prev= NULL, curr= *ip_fd_p; curr;
482 prev= curr, curr= curr->if_proto_next)
483 {
484 if (curr == ip_fd)
485 break;
486 }
487 assert(curr);
488 if (prev)
489 prev->if_proto_next= curr->if_proto_next;
490 else
491 *ip_fd_p= curr->if_proto_next;
492}
493
494PUBLIC int ip_setconf(ip_port_nr, ipconf)
495int ip_port_nr;
496nwio_ipconf_t *ipconf;
497{
498 int i, old_ip_flags, do_report;
499 ip_port_t *ip_port;
500 ip_fd_t *ip_fd;
501 ipaddr_t ipaddr;
502 u32_t mtu;
503
504 ip_port= &ip_port_table[ip_port_nr];
505
506 old_ip_flags= ip_port->ip_flags;
507
508 if (ipconf->nwic_flags & ~NWIC_FLAGS)
509 return EBADMODE;
510
511 do_report= 0;
512 if (ipconf->nwic_flags & NWIC_MTU_SET)
513 {
514 mtu= ipconf->nwic_mtu;
515 if (mtu < IP_MIN_MTU || mtu > ip_port->ip_mtu_max)
516 return EINVAL;
517 ip_port->ip_mtu= mtu;
518 do_report= 1;
519 }
520
521 if (ipconf->nwic_flags & NWIC_NETMASK_SET)
522 {
523 ip_port->ip_subnetmask= ipconf->nwic_netmask;
524 ip_port->ip_flags |= IPF_NETMASKSET|IPF_SUBNET_BCAST;
525 if (ntohl(ip_port->ip_subnetmask) >= 0xfffffffe)
526 ip_port->ip_flags &= ~IPF_SUBNET_BCAST;
527 do_report= 1;
528 }
529 if (ipconf->nwic_flags & NWIC_IPADDR_SET)
530 {
531 ipaddr= ipconf->nwic_ipaddr;
532 ip_port->ip_ipaddr= ipaddr;
533 ip_port->ip_flags |= IPF_IPADDRSET;
534 ip_port->ip_classfulmask=
535 ip_netmask(ip_nettype(ipaddr));
536 if (!(ip_port->ip_flags & IPF_NETMASKSET))
537 {
538 ip_port->ip_subnetmask= ip_port->ip_classfulmask;
539 }
540 if (ipaddr == HTONL(0x00000000))
541 {
542 /* Special case. Use 0.0.0.0 to shutdown interface. */
543 ip_port->ip_flags &= ~(IPF_IPADDRSET|IPF_NETMASKSET);
544 ip_port->ip_subnetmask= HTONL(0x00000000);
545 }
546 (*ip_port->ip_dev_set_ipaddr)(ip_port);
547
548 /* revive calls waiting for an ip addresses */
549 for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
550 {
551 if (!(ip_fd->if_flags & IFF_INUSE))
552 continue;
553 if (ip_fd->if_port != ip_port)
554 continue;
555 if (ip_fd->if_flags & IFF_IOCTL_IP)
556 ip_ioctl (i, ip_fd->if_ioctl);
557 }
558
559 do_report= 1;
560 }
561
562 ipr_chk_itab(ip_port-ip_port_table, ip_port->ip_ipaddr,
563 ip_port->ip_subnetmask);
564 ipr_chk_otab(ip_port-ip_port_table, ip_port->ip_ipaddr,
565 ip_port->ip_subnetmask);
566 if (do_report)
567 report_addr(ip_port);
568
569 return 0;
570}
571
572PRIVATE int ip_checkopt (ip_fd)
573ip_fd_t *ip_fd;
574{
575/* bug: we don't check access modes yet */
576
577 unsigned long flags;
578 unsigned int en_di_flags;
579 acc_t *pack;
580 int result;
581
582 flags= ip_fd->if_ipopt.nwio_flags;
583 en_di_flags= (flags >>16) | (flags & 0xffff);
584
585 if (flags & NWIO_HDR_O_SPEC)
586 {
587 result= ip_chk_hdropt (ip_fd->if_ipopt.nwio_hdropt.iho_data,
588 ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz);
589 if (result<0)
590 return result;
591 }
592 if ((en_di_flags & NWIO_ACC_MASK) &&
593 (en_di_flags & NWIO_LOC_MASK) &&
594 (en_di_flags & NWIO_BROAD_MASK) &&
595 (en_di_flags & NWIO_REM_MASK) &&
596 (en_di_flags & NWIO_PROTO_MASK) &&
597 (en_di_flags & NWIO_HDR_O_MASK) &&
598 (en_di_flags & NWIO_RW_MASK))
599 {
600 ip_fd->if_flags |= IFF_OPTSET;
601
602 ip_hash_proto(ip_fd);
603 }
604
605 else
606 ip_fd->if_flags &= ~IFF_OPTSET;
607
608 while (ip_fd->if_rdbuf_head)
609 {
610 pack= ip_fd->if_rdbuf_head;
611 ip_fd->if_rdbuf_head= pack->acc_ext_link;
612 bf_afree(pack);
613 }
614 return NW_OK;
615}
616
617PRIVATE void reply_thr_get(ip_fd, reply, for_ioctl)
618ip_fd_t *ip_fd;
619size_t reply;
620int for_ioctl;
621{
622 acc_t *result;
623 result= (ip_fd->if_get_userdata)(ip_fd->if_srfd, reply,
624 (size_t)0, for_ioctl);
625 assert (!result);
626}
627
628PRIVATE void report_addr(ip_port)
629ip_port_t *ip_port;
630{
631 int i, hdr_len;
632 ip_fd_t *ip_fd;
633 acc_t *pack;
634 ip_hdr_t *ip_hdr;
635
636 pack= bf_memreq(IP_MIN_HDR_SIZE);
637 ip_hdr= (ip_hdr_t *)ptr2acc_data(pack);
638
639 hdr_len= IP_MIN_HDR_SIZE;
640 ip_hdr->ih_vers_ihl= (IP_VERSION << 4) | (hdr_len/4);
641 ip_hdr->ih_tos= 0;
642 ip_hdr->ih_length= htons(ip_port->ip_mtu);
643 ip_hdr->ih_id= 0;
644 ip_hdr->ih_flags_fragoff= 0;
645 ip_hdr->ih_ttl= 0;
646 ip_hdr->ih_proto= 0;
647 ip_hdr->ih_src= ip_port->ip_ipaddr;
648 ip_hdr->ih_dst= ip_port->ip_subnetmask;
649 ip_hdr_chksum(ip_hdr, hdr_len);
650
651 for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
652 {
653 if (!(ip_fd->if_flags & IFF_INUSE))
654 {
655 continue;
656 }
657 if (ip_fd->if_port != ip_port)
658 {
659 continue;
660 }
661
662 /* Deliver packet to user */
663 pack->acc_linkC++;
664 ip_packet2user(ip_fd, pack, 255, IP_MIN_HDR_SIZE);
665 }
666 bf_afree(pack); pack= NULL;
667}
668
669/*
670 * $PchId: ip_ioctl.c,v 1.22 2004/08/03 11:10:08 philip Exp $
671 */
Note: See TracBrowser for help on using the repository browser.