VM: simplify slab allocator
[minix.git] / servers / inet / generic / ip_ioctl.c
blob327e85106d8009d707d4c578e280784fbaf88bbb
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 static int ip_checkopt ARGS(( ip_fd_t *ip_fd ));
23 static void reply_thr_get ARGS(( ip_fd_t *ip_fd, size_t
24 reply, int for_ioctl ));
25 static void report_addr ARGS(( ip_port_t *ip_port ));
27 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 ENETDOWN, 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 ENETDOWN, 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);
430 if (!(ip_port->ip_flags & IPF_IPADDRSET))
432 ip_fd->if_ioctl= req;
433 ip_fd->if_flags |= IFF_IOCTL_IP;
434 printf("ip_ioctl: suspending ARP request\n");
435 return NW_SUSPEND;
438 result= arp_ioctl(ip_port->ip_dl.dl_eth.de_port,
439 ip_fd->if_srfd, req, ip_fd->if_get_userdata,
440 ip_fd->if_put_userdata);
441 assert (result != SUSPEND);
442 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result,
443 (acc_t *)0, TRUE);
445 default:
446 break;
448 DBLOCK(1, printf("replying EBADIOCTL: 0x%x\n", req));
449 return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, EBADIOCTL,
450 (acc_t *)0, TRUE);
453 void ip_hash_proto(ip_fd)
454 ip_fd_t *ip_fd;
456 ip_port_t *ip_port;
457 int hash;
459 ip_port= ip_fd->if_port;
460 if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOANY)
462 ip_fd->if_proto_next= ip_port->ip_proto_any;
463 ip_port->ip_proto_any= ip_fd;
465 else
467 hash= ip_fd->if_ipopt.nwio_proto & (IP_PROTO_HASH_NR-1);
468 ip_fd->if_proto_next= ip_port->ip_proto[hash];
469 ip_port->ip_proto[hash]= ip_fd;
473 void ip_unhash_proto(ip_fd)
474 ip_fd_t *ip_fd;
476 ip_port_t *ip_port;
477 ip_fd_t *prev, *curr, **ip_fd_p;
478 int hash;
480 ip_port= ip_fd->if_port;
481 if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOANY)
483 ip_fd_p= &ip_port->ip_proto_any;
485 else
487 hash= ip_fd->if_ipopt.nwio_proto & (IP_PROTO_HASH_NR-1);
488 ip_fd_p= &ip_port->ip_proto[hash];
490 for (prev= NULL, curr= *ip_fd_p; curr;
491 prev= curr, curr= curr->if_proto_next)
493 if (curr == ip_fd)
494 break;
496 assert(curr);
497 if (prev)
498 prev->if_proto_next= curr->if_proto_next;
499 else
500 *ip_fd_p= curr->if_proto_next;
503 int ip_setconf(ip_port_nr, ipconf)
504 int ip_port_nr;
505 nwio_ipconf_t *ipconf;
507 int i, do_report;
508 ip_port_t *ip_port;
509 ip_fd_t *ip_fd;
510 ipaddr_t ipaddr;
511 u32_t mtu;
513 ip_port= &ip_port_table[ip_port_nr];
515 if (ipconf->nwic_flags & ~NWIC_FLAGS)
516 return EBADMODE;
518 do_report= 0;
519 if (ipconf->nwic_flags & NWIC_MTU_SET)
521 mtu= ipconf->nwic_mtu;
522 if (mtu < IP_MIN_MTU || mtu > ip_port->ip_mtu_max)
523 return EINVAL;
524 ip_port->ip_mtu= mtu;
525 do_report= 1;
528 if (ipconf->nwic_flags & NWIC_NETMASK_SET)
530 ip_port->ip_subnetmask= ipconf->nwic_netmask;
531 ip_port->ip_flags |= IPF_NETMASKSET|IPF_SUBNET_BCAST;
532 if (ntohl(ip_port->ip_subnetmask) >= 0xfffffffe)
533 ip_port->ip_flags &= ~IPF_SUBNET_BCAST;
534 do_report= 1;
536 if (ipconf->nwic_flags & NWIC_IPADDR_SET)
538 ipaddr= ipconf->nwic_ipaddr;
539 ip_port->ip_ipaddr= ipaddr;
540 ip_port->ip_flags |= IPF_IPADDRSET;
541 ip_port->ip_classfulmask=
542 ip_netmask(ip_nettype(ipaddr));
543 if (!(ip_port->ip_flags & IPF_NETMASKSET))
545 ip_port->ip_subnetmask= ip_port->ip_classfulmask;
547 if (ipaddr == HTONL(0x00000000))
549 /* Special case. Use 0.0.0.0 to shutdown interface. */
550 ip_port->ip_flags &= ~(IPF_IPADDRSET|IPF_NETMASKSET);
551 ip_port->ip_subnetmask= HTONL(0x00000000);
553 (*ip_port->ip_dev_set_ipaddr)(ip_port);
555 /* revive calls waiting for an ip addresses */
556 for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
558 if (!(ip_fd->if_flags & IFF_INUSE))
559 continue;
560 if (ip_fd->if_port != ip_port)
561 continue;
562 if (ip_fd->if_flags & IFF_IOCTL_IP)
563 ip_ioctl (i, ip_fd->if_ioctl);
566 do_report= 1;
569 ipr_chk_itab(ip_port-ip_port_table, ip_port->ip_ipaddr,
570 ip_port->ip_subnetmask);
571 ipr_chk_otab(ip_port-ip_port_table, ip_port->ip_ipaddr,
572 ip_port->ip_subnetmask);
573 if (do_report)
574 report_addr(ip_port);
576 return 0;
579 static int ip_checkopt (ip_fd)
580 ip_fd_t *ip_fd;
582 /* bug: we don't check access modes yet */
584 unsigned long flags;
585 unsigned int en_di_flags;
586 acc_t *pack;
587 int result;
589 flags= ip_fd->if_ipopt.nwio_flags;
590 en_di_flags= (flags >>16) | (flags & 0xffff);
592 if (flags & NWIO_HDR_O_SPEC)
594 result= ip_chk_hdropt (ip_fd->if_ipopt.nwio_hdropt.iho_data,
595 ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz);
596 if (result<0)
597 return result;
599 if ((en_di_flags & NWIO_ACC_MASK) &&
600 (en_di_flags & NWIO_LOC_MASK) &&
601 (en_di_flags & NWIO_BROAD_MASK) &&
602 (en_di_flags & NWIO_REM_MASK) &&
603 (en_di_flags & NWIO_PROTO_MASK) &&
604 (en_di_flags & NWIO_HDR_O_MASK) &&
605 (en_di_flags & NWIO_RW_MASK))
607 ip_fd->if_flags |= IFF_OPTSET;
609 ip_hash_proto(ip_fd);
612 else
613 ip_fd->if_flags &= ~IFF_OPTSET;
615 while (ip_fd->if_rdbuf_head)
617 pack= ip_fd->if_rdbuf_head;
618 ip_fd->if_rdbuf_head= pack->acc_ext_link;
619 bf_afree(pack);
621 return NW_OK;
624 static void reply_thr_get(ip_fd, reply, for_ioctl)
625 ip_fd_t *ip_fd;
626 size_t reply;
627 int for_ioctl;
629 acc_t *result;
630 result= (ip_fd->if_get_userdata)(ip_fd->if_srfd, reply,
631 (size_t)0, for_ioctl);
632 assert (!result);
635 static void report_addr(ip_port)
636 ip_port_t *ip_port;
638 int i, hdr_len;
639 ip_fd_t *ip_fd;
640 acc_t *pack;
641 ip_hdr_t *ip_hdr;
643 pack= bf_memreq(IP_MIN_HDR_SIZE);
644 ip_hdr= (ip_hdr_t *)ptr2acc_data(pack);
646 hdr_len= IP_MIN_HDR_SIZE;
647 ip_hdr->ih_vers_ihl= (IP_VERSION << 4) | (hdr_len/4);
648 ip_hdr->ih_tos= 0;
649 ip_hdr->ih_length= htons(ip_port->ip_mtu);
650 ip_hdr->ih_id= 0;
651 ip_hdr->ih_flags_fragoff= 0;
652 ip_hdr->ih_ttl= 0;
653 ip_hdr->ih_proto= 0;
654 ip_hdr->ih_src= ip_port->ip_ipaddr;
655 ip_hdr->ih_dst= ip_port->ip_subnetmask;
656 ip_hdr_chksum(ip_hdr, hdr_len);
658 for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
660 if (!(ip_fd->if_flags & IFF_INUSE))
662 continue;
664 if (ip_fd->if_port != ip_port)
666 continue;
669 /* Deliver packet to user */
670 pack->acc_linkC++;
671 ip_packet2user(ip_fd, pack, 255, IP_MIN_HDR_SIZE);
673 bf_afree(pack); pack= NULL;
677 * $PchId: ip_ioctl.c,v 1.22 2004/08/03 11:10:08 philip Exp $