add/re-enable at_wini debug output
[minix3.git] / servers / inet / generic / ip_ioctl.c
blobbbfaf247a217658deaa4a4d6247c2c4bf9dc7d93
1 /*
2 ip_ioctl.c
4 Copyright 1995 Philip Homburg
5 */
7 #include "inet.h"
8 #include "buf.h"
9 #include "event.h"
10 #include "type.h"
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"
20 THIS_FILE
22 FORWARD int ip_checkopt ARGS(( ip_fd_t *ip_fd ));
23 FORWARD void reply_thr_get ARGS(( ip_fd_t *ip_fd, size_t
24 reply, int for_ioctl ));
25 FORWARD void report_addr ARGS(( ip_port_t *ip_port ));
27 PUBLIC int ip_ioctl (fd, req)
28 int fd;
29 ioreq_t req;
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;
46 assert (fd>=0 && fd<=IP_FD_NR);
47 ip_fd= &ip_fd_table[fd];
49 assert (ip_fd->if_flags & IFF_INUSE);
51 switch (req)
53 case NWIOSIPOPT:
54 ip_port= ip_fd->if_port;
56 if (!(ip_port->ip_flags & IPF_IPADDRSET))
58 ip_fd->if_ioctl= NWIOSIPOPT;
59 ip_fd->if_flags |= IFF_IOCTL_IP;
60 return NW_SUSPEND;
62 ip_fd->if_flags &= ~IFF_IOCTL_IP;
64 data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0,
65 sizeof(nwio_ipopt_t), TRUE);
67 data= bf_packIffLess (data, sizeof(nwio_ipopt_t));
68 assert (data->acc_length == sizeof(nwio_ipopt_t));
70 ipopt= (nwio_ipopt_t *)ptr2acc_data(data);
71 oldopt= ip_fd->if_ipopt;
72 newopt= *ipopt;
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)
80 bf_afree(data);
81 reply_thr_get (ip_fd, EBADMODE, TRUE);
82 return NW_OK;
85 /* NWIO_ACC_MASK */
86 if (new_di_flags & NWIO_ACC_MASK)
88 bf_afree(data);
89 reply_thr_get (ip_fd, EBADMODE, TRUE);
90 return NW_OK;
91 /* access modes can't be disable */
94 if (!(new_en_flags & NWIO_ACC_MASK))
95 new_en_flags |= (old_en_flags & NWIO_ACC_MASK);
97 /* NWIO_LOC_MASK */
98 if (!((new_en_flags|new_di_flags) & NWIO_LOC_MASK))
100 new_en_flags |= (old_en_flags & NWIO_LOC_MASK);
101 new_di_flags |= (old_di_flags & NWIO_LOC_MASK);
104 /* NWIO_BROAD_MASK */
105 if (!((new_en_flags|new_di_flags) & NWIO_BROAD_MASK))
107 new_en_flags |= (old_en_flags & NWIO_BROAD_MASK);
108 new_di_flags |= (old_di_flags & NWIO_BROAD_MASK);
111 /* NWIO_REM_MASK */
112 if (!((new_en_flags|new_di_flags) & NWIO_REM_MASK))
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;
119 /* NWIO_PROTO_MASK */
120 if (!((new_en_flags|new_di_flags) & NWIO_PROTO_MASK))
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;
127 /* NWIO_HDR_O_MASK */
128 if (!((new_en_flags|new_di_flags) & NWIO_HDR_O_MASK))
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;
138 /* NWIO_RW_MASK */
139 if (!((new_en_flags|new_di_flags) & NWIO_RW_MASK))
141 new_en_flags |= (old_en_flags & NWIO_RW_MASK);
142 new_di_flags |= (old_di_flags & NWIO_RW_MASK);
145 new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags;
147 if ((new_flags & NWIO_RWDATONLY) && (new_flags &
148 (NWIO_REMANY|NWIO_PROTOANY|NWIO_HDR_O_ANY)))
150 bf_afree(data);
151 reply_thr_get(ip_fd, EBADMODE, TRUE);
152 return NW_OK;
155 if (ip_fd->if_flags & IFF_OPTSET)
156 ip_unhash_proto(ip_fd);
158 newopt.nwio_flags= new_flags;
159 ip_fd->if_ipopt= newopt;
161 result= ip_checkopt(ip_fd);
163 if (result<0)
164 ip_fd->if_ipopt= oldopt;
166 bf_afree(data);
167 reply_thr_get (ip_fd, result, TRUE);
168 return NW_OK;
170 case NWIOGIPOPT:
171 data= bf_memreq(sizeof(nwio_ipopt_t));
173 ipopt= (nwio_ipopt_t *)ptr2acc_data(data);
175 *ipopt= ip_fd->if_ipopt;
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);
182 case NWIOSIPCONF2:
183 case NWIOSIPCONF:
184 ip_port= ip_fd->if_port;
186 if (req == NWIOSIPCONF2)
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));
193 ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data);
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;
201 else
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));
208 ipconf= (nwio_ipconf_t *)ptr2acc_data(data);
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);
215 case NWIOGIPCONF2:
216 ip_port= ip_fd->if_port;
218 if (!(ip_port->ip_flags & IPF_IPADDRSET))
220 ip_fd->if_ioctl= NWIOGIPCONF2;
221 ip_fd->if_flags |= IFF_IOCTL_IP;
222 return NW_SUSPEND;
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;
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);
238 case NWIOGIPCONF:
239 ip_port= ip_fd->if_port;
241 if (!(ip_port->ip_flags & IPF_IPADDRSET))
243 ip_fd->if_ioctl= NWIOGIPCONF;
244 ip_fd->if_flags |= IFF_IOCTL_IP;
245 return NW_SUSPEND;
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;
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);
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)
267 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
268 EFAULT, NULL, TRUE);
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);
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
283 assert(result == NW_OK);
284 result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0,
285 data, TRUE);
287 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
288 result, (acc_t *)0, TRUE);
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)
295 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
296 EFAULT, NULL, TRUE);
298 if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET))
300 /* Interface is down, no changes allowed */
301 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
302 EINVAL, NULL, TRUE);
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);
315 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
316 result, (acc_t *)0, TRUE);
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)
323 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
324 EFAULT, NULL, TRUE);
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);
335 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
336 result, (acc_t *)0, TRUE);
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)
343 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
344 EFAULT, NULL, TRUE);
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);
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
359 assert(result == NW_OK);
360 result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0,
361 data, TRUE);
363 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
364 result, (acc_t *)0, TRUE);
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)
371 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
372 EFAULT, NULL, TRUE);
374 if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET))
376 /* Interface is down, no changes allowed */
377 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
378 EINVAL, NULL, TRUE);
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);
392 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
393 result, (acc_t *)0, TRUE);
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)
400 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
401 EFAULT, NULL, TRUE);
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);
412 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
413 result, (acc_t *)0, TRUE);
415 /* The following ARP ioctls are only valid if the
416 * underlying device is an ethernet.
418 case NWIOARPGIP:
419 case NWIOARPGNEXT:
420 case NWIOARPSIP:
421 case NWIOARPDIP:
422 ip_port= ip_fd->if_port;
424 if (ip_port->ip_dl_type != IPDL_ETH)
426 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
427 EBADIOCTL, (acc_t *)0, TRUE);
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);
436 default:
437 break;
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);
444 PUBLIC void ip_hash_proto(ip_fd)
445 ip_fd_t *ip_fd;
447 ip_port_t *ip_port;
448 int hash;
450 ip_port= ip_fd->if_port;
451 if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOANY)
453 ip_fd->if_proto_next= ip_port->ip_proto_any;
454 ip_port->ip_proto_any= ip_fd;
456 else
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;
464 PUBLIC void ip_unhash_proto(ip_fd)
465 ip_fd_t *ip_fd;
467 ip_port_t *ip_port;
468 ip_fd_t *prev, *curr, **ip_fd_p;
469 int hash;
471 ip_port= ip_fd->if_port;
472 if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOANY)
474 ip_fd_p= &ip_port->ip_proto_any;
476 else
478 hash= ip_fd->if_ipopt.nwio_proto & (IP_PROTO_HASH_NR-1);
479 ip_fd_p= &ip_port->ip_proto[hash];
481 for (prev= NULL, curr= *ip_fd_p; curr;
482 prev= curr, curr= curr->if_proto_next)
484 if (curr == ip_fd)
485 break;
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;
494 PUBLIC int ip_setconf(ip_port_nr, ipconf)
495 int ip_port_nr;
496 nwio_ipconf_t *ipconf;
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;
504 ip_port= &ip_port_table[ip_port_nr];
506 old_ip_flags= ip_port->ip_flags;
508 if (ipconf->nwic_flags & ~NWIC_FLAGS)
509 return EBADMODE;
511 do_report= 0;
512 if (ipconf->nwic_flags & NWIC_MTU_SET)
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;
521 if (ipconf->nwic_flags & NWIC_NETMASK_SET)
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;
529 if (ipconf->nwic_flags & NWIC_IPADDR_SET)
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))
538 ip_port->ip_subnetmask= ip_port->ip_classfulmask;
540 if (ipaddr == HTONL(0x00000000))
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);
546 (*ip_port->ip_dev_set_ipaddr)(ip_port);
548 /* revive calls waiting for an ip addresses */
549 for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
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);
559 do_report= 1;
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);
569 return 0;
572 PRIVATE int ip_checkopt (ip_fd)
573 ip_fd_t *ip_fd;
575 /* bug: we don't check access modes yet */
577 unsigned long flags;
578 unsigned int en_di_flags;
579 acc_t *pack;
580 int result;
582 flags= ip_fd->if_ipopt.nwio_flags;
583 en_di_flags= (flags >>16) | (flags & 0xffff);
585 if (flags & NWIO_HDR_O_SPEC)
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;
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))
600 ip_fd->if_flags |= IFF_OPTSET;
602 ip_hash_proto(ip_fd);
605 else
606 ip_fd->if_flags &= ~IFF_OPTSET;
608 while (ip_fd->if_rdbuf_head)
610 pack= ip_fd->if_rdbuf_head;
611 ip_fd->if_rdbuf_head= pack->acc_ext_link;
612 bf_afree(pack);
614 return NW_OK;
617 PRIVATE void reply_thr_get(ip_fd, reply, for_ioctl)
618 ip_fd_t *ip_fd;
619 size_t reply;
620 int for_ioctl;
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);
628 PRIVATE void report_addr(ip_port)
629 ip_port_t *ip_port;
631 int i, hdr_len;
632 ip_fd_t *ip_fd;
633 acc_t *pack;
634 ip_hdr_t *ip_hdr;
636 pack= bf_memreq(IP_MIN_HDR_SIZE);
637 ip_hdr= (ip_hdr_t *)ptr2acc_data(pack);
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);
651 for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
653 if (!(ip_fd->if_flags & IFF_INUSE))
655 continue;
657 if (ip_fd->if_port != ip_port)
659 continue;
662 /* Deliver packet to user */
663 pack->acc_linkC++;
664 ip_packet2user(ip_fd, pack, 255, IP_MIN_HDR_SIZE);
666 bf_afree(pack); pack= NULL;
670 * $PchId: ip_ioctl.c,v 1.22 2004/08/03 11:10:08 philip Exp $