4 Copyright 1995 Philip Homburg
22 FORWARD
void read_ip_packets
ARGS(( udp_port_t
*udp_port
));
23 FORWARD
void udp_buffree
ARGS(( int priority
));
24 #ifdef BUF_CONSISTENCY_CHECK
25 FORWARD
void udp_bufcheck
ARGS(( void ));
27 FORWARD
void udp_main
ARGS(( udp_port_t
*udp_port
));
28 FORWARD
int udp_select
ARGS(( int fd
, unsigned operations
));
29 FORWARD acc_t
*udp_get_data
ARGS(( int fd
, size_t offset
, size_t count
,
31 FORWARD
int udp_put_data
ARGS(( int fd
, size_t offset
, acc_t
*data
,
33 FORWARD
int udp_peek
ARGS(( udp_fd_t
* ));
34 FORWARD
int udp_sel_read
ARGS(( udp_fd_t
* ));
35 FORWARD
void udp_restart_write_port
ARGS(( udp_port_t
*udp_port
));
36 FORWARD
void udp_ip_arrived
ARGS(( int port
, acc_t
*pack
, size_t pack_size
));
37 FORWARD
void reply_thr_put
ARGS(( udp_fd_t
*udp_fd
, int reply
,
39 FORWARD
void reply_thr_get
ARGS(( udp_fd_t
*udp_fd
, int reply
,
41 FORWARD
int udp_setopt
ARGS(( udp_fd_t
*udp_fd
));
42 FORWARD udpport_t find_unused_port
ARGS(( int fd
));
43 FORWARD
int is_unused_port
ARGS(( Udpport_t port
));
44 FORWARD
int udp_packet2user
ARGS(( udp_fd_t
*udp_fd
));
45 FORWARD
void restart_write_fd
ARGS(( udp_fd_t
*udp_fd
));
46 FORWARD u16_t pack_oneCsum
ARGS(( acc_t
*pack
));
47 FORWARD
void udp_rd_enqueue
ARGS(( udp_fd_t
*udp_fd
, acc_t
*pack
,
49 FORWARD
void hash_fd
ARGS(( udp_fd_t
*udp_fd
));
50 FORWARD
void unhash_fd
ARGS(( udp_fd_t
*udp_fd
));
52 PUBLIC udp_port_t
*udp_port_table
;
53 PUBLIC udp_fd_t udp_fd_table
[UDP_FD_NR
];
55 PUBLIC
void udp_prep()
57 udp_port_table
= alloc(udp_conf_nr
* sizeof(udp_port_table
[0]));
60 PUBLIC
void udp_init()
66 assert (BUF_S
>= sizeof(struct nwio_ipopt
));
67 assert (BUF_S
>= sizeof(struct nwio_ipconf
));
68 assert (BUF_S
>= sizeof(struct nwio_udpopt
));
69 assert (BUF_S
>= sizeof(struct udp_io_hdr
));
70 assert (UDP_HDR_SIZE
== sizeof(udp_hdr_t
));
71 assert (UDP_IO_HDR_SIZE
== sizeof(udp_io_hdr_t
));
73 for (i
= 0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++, udp_fd
++)
75 udp_fd
->uf_flags
= UFF_EMPTY
;
76 udp_fd
->uf_rdbuf_head
= NULL
;
79 #ifndef BUF_CONSISTENCY_CHECK
80 bf_logon(udp_buffree
);
82 bf_logon(udp_buffree
, udp_bufcheck
);
85 for (i
= 0, udp_port
= udp_port_table
; i
<udp_conf_nr
; i
++, udp_port
++)
87 udp_port
->up_ipdev
= udp_conf
[i
].uc_port
;
89 udp_port
->up_flags
= UPF_EMPTY
;
90 udp_port
->up_state
= UPS_EMPTY
;
91 udp_port
->up_next_fd
= udp_fd_table
;
92 udp_port
->up_write_fd
= NULL
;
93 udp_port
->up_wr_pack
= NULL
;
94 udp_port
->up_port_any
= NULL
;
95 for (j
= 0; j
<UDP_PORT_HASH_NR
; j
++)
96 udp_port
->up_port_hash
[j
]= NULL
;
98 ifno
= ip_conf
[udp_port
->up_ipdev
].ic_ifno
;
99 sr_add_minor(if2minor(ifno
, UDP_DEV_OFF
),
100 i
, udp_open
, udp_close
, udp_read
,
101 udp_write
, udp_ioctl
, udp_cancel
, udp_select
);
107 PUBLIC
int udp_open (port
, srfd
, get_userdata
, put_userdata
, put_pkt
,
111 get_userdata_t get_userdata
;
112 put_userdata_t put_userdata
;
114 select_res_t select_res
;
119 for (i
= 0; i
<UDP_FD_NR
&& (udp_fd_table
[i
].uf_flags
& UFF_INUSE
);
124 DBLOCK(1, printf("out of fds\n"));
128 udp_fd
= &udp_fd_table
[i
];
130 udp_fd
->uf_flags
= UFF_INUSE
;
131 udp_fd
->uf_port
= &udp_port_table
[port
];
132 udp_fd
->uf_srfd
= srfd
;
133 udp_fd
->uf_udpopt
.nwuo_flags
= UDP_DEF_OPT
;
134 udp_fd
->uf_get_userdata
= get_userdata
;
135 udp_fd
->uf_put_userdata
= put_userdata
;
136 udp_fd
->uf_select_res
= select_res
;
137 assert(udp_fd
->uf_rdbuf_head
== NULL
);
138 udp_fd
->uf_port_next
= NULL
;
144 PUBLIC
int udp_ioctl (fd
, req
)
149 udp_port_t
*udp_port
;
150 nwio_udpopt_t
*udp_opt
;
154 udp_fd
= &udp_fd_table
[fd
];
156 assert (udp_fd
->uf_flags
& UFF_INUSE
);
158 udp_port
= udp_fd
->uf_port
;
159 udp_fd
->uf_flags
|= UFF_IOCTL_IP
;
160 udp_fd
->uf_ioreq
= req
;
162 if (udp_port
->up_state
!= UPS_MAIN
)
168 result
= udp_setopt(udp_fd
);
171 opt_acc
= bf_memreq(sizeof(*udp_opt
));
172 assert (opt_acc
->acc_length
== sizeof(*udp_opt
));
173 udp_opt
= (nwio_udpopt_t
*)ptr2acc_data(opt_acc
);
175 *udp_opt
= udp_fd
->uf_udpopt
;
176 udp_opt
->nwuo_locaddr
= udp_fd
->uf_port
->up_ipaddr
;
177 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
, 0, opt_acc
,
180 reply_thr_put(udp_fd
, NW_OK
, TRUE
);
183 result
= udp_peek(udp_fd
);
186 reply_thr_get(udp_fd
, EBADIOCTL
, TRUE
);
190 if (result
!= NW_SUSPEND
)
191 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
195 PUBLIC
int udp_read (fd
, count
)
200 acc_t
*tmp_acc
, *next_acc
;
202 udp_fd
= &udp_fd_table
[fd
];
203 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
205 reply_thr_put(udp_fd
, EBADMODE
, FALSE
);
209 udp_fd
->uf_rd_count
= count
;
211 if (udp_fd
->uf_rdbuf_head
)
213 if (get_time() <= udp_fd
->uf_exp_tim
)
214 return udp_packet2user (udp_fd
);
215 tmp_acc
= udp_fd
->uf_rdbuf_head
;
218 next_acc
= tmp_acc
->acc_ext_link
;
222 udp_fd
->uf_rdbuf_head
= NULL
;
224 udp_fd
->uf_flags
|= UFF_READ_IP
;
228 PRIVATE
void udp_main(udp_port
)
229 udp_port_t
*udp_port
;
234 switch (udp_port
->up_state
)
237 udp_port
->up_state
= UPS_SETPROTO
;
239 udp_port
->up_ipfd
= ip_open(udp_port
->up_ipdev
,
240 udp_port
->up_ipdev
, udp_get_data
, udp_put_data
,
241 udp_ip_arrived
, 0 /* no select_res */);
242 if (udp_port
->up_ipfd
< 0)
244 udp_port
->up_state
= UPS_ERROR
;
245 DBLOCK(1, printf("%s, %d: unable to open ip port\n",
246 __FILE__
, __LINE__
));
250 result
= ip_ioctl(udp_port
->up_ipfd
, NWIOSIPOPT
);
251 if (result
== NW_SUSPEND
)
252 udp_port
->up_flags
|= UPF_SUSPEND
;
257 if (udp_port
->up_state
!= UPS_GETCONF
)
261 udp_port
->up_flags
&= ~UPF_SUSPEND
;
263 result
= ip_ioctl(udp_port
->up_ipfd
, NWIOGIPCONF
);
264 if (result
== NW_SUSPEND
)
265 udp_port
->up_flags
|= UPF_SUSPEND
;
270 if (udp_port
->up_state
!= UPS_MAIN
)
274 udp_port
->up_flags
&= ~UPF_SUSPEND
;
276 for (i
= 0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++, udp_fd
++)
278 if (!(udp_fd
->uf_flags
& UFF_INUSE
))
280 if (udp_fd
->uf_port
!= udp_port
)
282 if (udp_fd
->uf_flags
& UFF_IOCTL_IP
)
283 udp_ioctl(i
, udp_fd
->uf_ioreq
);
285 read_ip_packets(udp_port
);
288 DBLOCK(1, printf("udp_port_table[%d].up_state= %d\n",
289 udp_port
->up_ipdev
, udp_port
->up_state
));
290 ip_panic(( "unknown state" ));
295 PRIVATE
int udp_select(fd
, operations
)
303 udp_fd
= &udp_fd_table
[fd
];
304 assert (udp_fd
->uf_flags
& UFF_INUSE
);
308 if (operations
& SR_SELECT_READ
)
310 if (udp_sel_read(udp_fd
))
311 resops
|= SR_SELECT_READ
;
312 else if (!(operations
& SR_SELECT_POLL
))
313 udp_fd
->uf_flags
|= UFF_SEL_READ
;
315 if (operations
& SR_SELECT_WRITE
)
317 /* Should handle special case when the interface is down */
318 resops
|= SR_SELECT_WRITE
;
320 if (operations
& SR_SELECT_EXCEPTION
)
322 printf("udp_select: not implemented for exceptions\n");
327 PRIVATE acc_t
*udp_get_data (port
, offset
, count
, for_ioctl
)
333 udp_port_t
*udp_port
;
337 udp_port
= &udp_port_table
[port
];
339 switch(udp_port
->up_state
)
348 udp_port
->up_state
= UPS_ERROR
;
351 udp_port
->up_state
= UPS_GETCONF
;
352 if (udp_port
->up_flags
& UPF_SUSPEND
)
358 struct nwio_ipopt
*ipopt
;
362 assert (count
== sizeof(*ipopt
));
364 acc
= bf_memreq(sizeof(*ipopt
));
365 ipopt
= (struct nwio_ipopt
*)ptr2acc_data(acc
);
366 ipopt
->nwio_flags
= NWIO_COPY
| NWIO_EN_LOC
|
367 NWIO_EN_BROAD
| NWIO_REMANY
| NWIO_PROTOSPEC
|
368 NWIO_HDR_O_ANY
| NWIO_RWDATALL
;
369 ipopt
->nwio_proto
= IPPROTO_UDP
;
374 assert (udp_port
->up_flags
& UPF_WRITE_IP
);
378 assert (udp_port
->up_wr_pack
);
379 bf_afree(udp_port
->up_wr_pack
);
380 udp_port
->up_wr_pack
= 0;
381 if (udp_port
->up_flags
& UPF_WRITE_SP
)
383 if (udp_port
->up_write_fd
)
385 udp_fd
= udp_port
->up_write_fd
;
386 udp_port
->up_write_fd
= NULL
;
387 udp_fd
->uf_flags
&= ~UFF_WRITE_IP
;
388 reply_thr_get(udp_fd
, result
, FALSE
);
390 udp_port
->up_flags
&= ~(UPF_WRITE_SP
|
392 if (udp_port
->up_flags
& UPF_MORE2WRITE
)
394 udp_restart_write_port(udp_port
);
398 udp_port
->up_flags
&= ~UPF_WRITE_IP
;
402 return bf_cut (udp_port
->up_wr_pack
, offset
, count
);
406 printf("udp_get_data(%d, 0x%x, 0x%x) called but up_state= 0x%x\n",
407 port
, offset
, count
, udp_port
->up_state
);
413 PRIVATE
int udp_put_data (fd
, offset
, data
, for_ioctl
)
419 udp_port_t
*udp_port
;
422 udp_port
= &udp_port_table
[fd
];
424 switch (udp_port
->up_state
)
432 udp_port
->up_state
= UPS_ERROR
;
435 udp_port
->up_state
= UPS_MAIN
;
436 if (udp_port
->up_flags
& UPF_SUSPEND
)
441 struct nwio_ipconf
*ipconf
;
443 data
= bf_packIffLess(data
, sizeof(*ipconf
));
444 ipconf
= (struct nwio_ipconf
*)ptr2acc_data(data
);
445 assert (ipconf
->nwic_flags
& NWIC_IPADDR_SET
);
446 udp_port
->up_ipaddr
= ipconf
->nwic_ipaddr
;
453 assert (udp_port
->up_flags
& UPF_READ_IP
);
457 compare (result
, >=, 0);
458 if (udp_port
->up_flags
& UPF_READ_SP
)
460 udp_port
->up_flags
&= ~(UPF_READ_SP
|
462 read_ip_packets(udp_port
);
465 udp_port
->up_flags
&= ~UPF_READ_IP
;
469 assert (!offset
); /* This isn't a valid assertion but ip sends only
470 * whole datagrams up */
471 udp_ip_arrived(fd
, data
, bf_bufsize(data
));
476 "udp_put_data(%d, 0x%x, %p) called but up_state= 0x%x\n",
477 fd
, offset
, data
, udp_port
->up_state
));
482 PRIVATE
int udp_setopt(udp_fd
)
486 nwio_udpopt_t oldopt
, newopt
;
488 unsigned int new_en_flags
, new_di_flags
, old_en_flags
, old_di_flags
,
490 unsigned long new_flags
;
493 data
= (*udp_fd
->uf_get_userdata
)(udp_fd
->uf_srfd
, 0,
494 sizeof(nwio_udpopt_t
), TRUE
);
499 data
= bf_packIffLess(data
, sizeof(nwio_udpopt_t
));
500 assert (data
->acc_length
== sizeof(nwio_udpopt_t
));
502 newopt
= *(nwio_udpopt_t
*)ptr2acc_data(data
);
504 oldopt
= udp_fd
->uf_udpopt
;
506 old_en_flags
= oldopt
.nwuo_flags
& 0xffff;
507 old_di_flags
= (oldopt
.nwuo_flags
>> 16) & 0xffff;
509 new_en_flags
= newopt
.nwuo_flags
& 0xffff;
510 new_di_flags
= (newopt
.nwuo_flags
>> 16) & 0xffff;
512 if (new_en_flags
& new_di_flags
)
514 DBLOCK(1, printf("returning EBADMODE\n"));
516 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
521 if (new_di_flags
& NWUO_ACC_MASK
)
523 DBLOCK(1, printf("returning EBADMODE\n"));
525 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
527 /* access modes can't be disabled */
530 if (!(new_en_flags
& NWUO_ACC_MASK
))
531 new_en_flags
|= (old_en_flags
& NWUO_ACC_MASK
);
533 /* NWUO_LOCPORT_MASK */
534 if (new_di_flags
& NWUO_LOCPORT_MASK
)
536 DBLOCK(1, printf("returning EBADMODE\n"));
538 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
540 /* the loc ports can't be disabled */
542 if (!(new_en_flags
& NWUO_LOCPORT_MASK
))
544 new_en_flags
|= (old_en_flags
& NWUO_LOCPORT_MASK
);
545 newopt
.nwuo_locport
= oldopt
.nwuo_locport
;
547 else if ((new_en_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SEL
)
549 newopt
.nwuo_locport
= find_unused_port(udp_fd
-udp_fd_table
);
551 else if ((new_en_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SET
)
553 if (!newopt
.nwuo_locport
)
555 DBLOCK(1, printf("returning EBADMODE\n"));
557 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
562 /* NWUO_LOCADDR_MASK */
563 if (!((new_en_flags
| new_di_flags
) & NWUO_LOCADDR_MASK
))
565 new_en_flags
|= (old_en_flags
& NWUO_LOCADDR_MASK
);
566 new_di_flags
|= (old_di_flags
& NWUO_LOCADDR_MASK
);
569 /* NWUO_BROAD_MASK */
570 if (!((new_en_flags
| new_di_flags
) & NWUO_BROAD_MASK
))
572 new_en_flags
|= (old_en_flags
& NWUO_BROAD_MASK
);
573 new_di_flags
|= (old_di_flags
& NWUO_BROAD_MASK
);
576 /* NWUO_REMPORT_MASK */
577 if (!((new_en_flags
| new_di_flags
) & NWUO_REMPORT_MASK
))
579 new_en_flags
|= (old_en_flags
& NWUO_REMPORT_MASK
);
580 new_di_flags
|= (old_di_flags
& NWUO_REMPORT_MASK
);
581 newopt
.nwuo_remport
= oldopt
.nwuo_remport
;
584 /* NWUO_REMADDR_MASK */
585 if (!((new_en_flags
| new_di_flags
) & NWUO_REMADDR_MASK
))
587 new_en_flags
|= (old_en_flags
& NWUO_REMADDR_MASK
);
588 new_di_flags
|= (old_di_flags
& NWUO_REMADDR_MASK
);
589 newopt
.nwuo_remaddr
= oldopt
.nwuo_remaddr
;
593 if (!((new_en_flags
| new_di_flags
) & NWUO_RW_MASK
))
595 new_en_flags
|= (old_en_flags
& NWUO_RW_MASK
);
596 new_di_flags
|= (old_di_flags
& NWUO_RW_MASK
);
599 /* NWUO_IPOPT_MASK */
600 if (!((new_en_flags
| new_di_flags
) & NWUO_IPOPT_MASK
))
602 new_en_flags
|= (old_en_flags
& NWUO_IPOPT_MASK
);
603 new_di_flags
|= (old_di_flags
& NWUO_IPOPT_MASK
);
606 new_flags
= ((unsigned long)new_di_flags
<< 16) | new_en_flags
;
607 if ((new_flags
& NWUO_RWDATONLY
) &&
608 ((new_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_ANY
||
609 (new_flags
& (NWUO_RP_ANY
|NWUO_RA_ANY
|NWUO_EN_IPOPT
))))
611 DBLOCK(1, printf("returning EBADMODE\n"));
613 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
617 /* Check the access modes */
618 if ((new_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SEL
||
619 (new_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SET
)
621 for (i
= 0, fd_ptr
= udp_fd_table
; i
<UDP_FD_NR
; i
++, fd_ptr
++)
623 if (fd_ptr
== udp_fd
)
625 if (!(fd_ptr
->uf_flags
& UFF_INUSE
))
627 if (fd_ptr
->uf_port
!= udp_fd
->uf_port
)
629 flags
= fd_ptr
->uf_udpopt
.nwuo_flags
;
630 if ((flags
& NWUO_LOCPORT_MASK
) != NWUO_LP_SEL
&&
631 (flags
& NWUO_LOCPORT_MASK
) != NWUO_LP_SET
)
633 if (fd_ptr
->uf_udpopt
.nwuo_locport
!=
638 if ((flags
& NWUO_ACC_MASK
) !=
639 (new_flags
& NWUO_ACC_MASK
))
642 "address inuse: new fd= %d, old_fd= %d, port= %u\n",
645 newopt
.nwuo_locport
));
647 reply_thr_get(udp_fd
, EADDRINUSE
, TRUE
);
653 if (udp_fd
->uf_flags
& UFF_OPTSET
)
656 newopt
.nwuo_flags
= new_flags
;
657 udp_fd
->uf_udpopt
= newopt
;
659 all_flags
= new_en_flags
| new_di_flags
;
660 if ((all_flags
& NWUO_ACC_MASK
) && (all_flags
& NWUO_LOCPORT_MASK
) &&
661 (all_flags
& NWUO_LOCADDR_MASK
) &&
662 (all_flags
& NWUO_BROAD_MASK
) &&
663 (all_flags
& NWUO_REMPORT_MASK
) &&
664 (all_flags
& NWUO_REMADDR_MASK
) &&
665 (all_flags
& NWUO_RW_MASK
) &&
666 (all_flags
& NWUO_IPOPT_MASK
))
667 udp_fd
->uf_flags
|= UFF_OPTSET
;
670 udp_fd
->uf_flags
&= ~UFF_OPTSET
;
673 if (udp_fd
->uf_flags
& UFF_OPTSET
)
676 reply_thr_get(udp_fd
, NW_OK
, TRUE
);
680 PRIVATE udpport_t
find_unused_port(fd
)
683 udpport_t port
, nw_port
;
685 for (port
= 0x8000+fd
; port
< 0xffff-UDP_FD_NR
; port
+= UDP_FD_NR
)
687 nw_port
= htons(port
);
688 if (is_unused_port(nw_port
))
691 for (port
= 0x8000; port
< 0xffff; port
++)
693 nw_port
= htons(port
);
694 if (is_unused_port(nw_port
))
697 ip_panic(( "unable to find unused port (shouldn't occur)" ));
705 PRIVATE
void reply_thr_put(udp_fd
, reply
, for_ioctl
)
712 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
, reply
,
713 (acc_t
*)0, for_ioctl
);
714 assert(result
== NW_OK
);
721 PRIVATE
void reply_thr_get(udp_fd
, reply
, for_ioctl
)
727 result
= (*udp_fd
->uf_get_userdata
)(udp_fd
->uf_srfd
, reply
,
728 (size_t)0, for_ioctl
);
732 PRIVATE
int is_unused_port(port
)
738 for (i
= 0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++,
741 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
743 if (udp_fd
->uf_udpopt
.nwuo_locport
== port
)
749 PRIVATE
void read_ip_packets(udp_port
)
750 udp_port_t
*udp_port
;
756 udp_port
->up_flags
|= UPF_READ_IP
;
757 result
= ip_read(udp_port
->up_ipfd
, UDP_MAX_DATAGRAM
);
758 if (result
== NW_SUSPEND
)
760 udp_port
->up_flags
|= UPF_READ_SP
;
763 assert(result
== NW_OK
);
764 udp_port
->up_flags
&= ~UPF_READ_IP
;
765 } while(!(udp_port
->up_flags
& UPF_READ_IP
));
769 PRIVATE
int udp_peek (udp_fd
)
772 acc_t
*pack
, *tmp_acc
, *next_acc
;
775 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
777 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
778 reply_thr_put(udp_fd
, EBADMODE
, TRUE
);
782 if (udp_fd
->uf_rdbuf_head
)
784 if (get_time() <= udp_fd
->uf_exp_tim
)
786 pack
= bf_cut(udp_fd
->uf_rdbuf_head
, 0,
787 sizeof(udp_io_hdr_t
));
788 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
789 (size_t)0, pack
, TRUE
);
791 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
792 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
793 result
, (acc_t
*)0, TRUE
);
794 assert (result
== 0);
797 tmp_acc
= udp_fd
->uf_rdbuf_head
;
800 next_acc
= tmp_acc
->acc_ext_link
;
804 udp_fd
->uf_rdbuf_head
= NULL
;
806 udp_fd
->uf_flags
|= UFF_PEEK_IP
;
810 PRIVATE
int udp_sel_read (udp_fd
)
813 acc_t
*pack
, *tmp_acc
, *next_acc
;
816 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
817 return 1; /* Read will not block */
819 if (udp_fd
->uf_rdbuf_head
)
821 if (get_time() <= udp_fd
->uf_exp_tim
)
824 tmp_acc
= udp_fd
->uf_rdbuf_head
;
827 next_acc
= tmp_acc
->acc_ext_link
;
831 udp_fd
->uf_rdbuf_head
= NULL
;
836 PRIVATE
int udp_packet2user (udp_fd
)
839 acc_t
*pack
, *tmp_pack
;
842 size_t size
, transf_size
;
844 pack
= udp_fd
->uf_rdbuf_head
;
845 udp_fd
->uf_rdbuf_head
= pack
->acc_ext_link
;
847 size
= bf_bufsize (pack
);
849 if (udp_fd
->uf_udpopt
.nwuo_flags
& NWUO_RWDATONLY
)
852 pack
= bf_packIffLess (pack
, UDP_IO_HDR_SIZE
);
853 assert (pack
->acc_length
>= UDP_IO_HDR_SIZE
);
855 hdr
= (udp_io_hdr_t
*)ptr2acc_data(pack
);
856 #if CONF_UDP_IO_NW_BYTE_ORDER
857 hdr_len
= UDP_IO_HDR_SIZE
+NTOHS(hdr
->uih_ip_opt_len
);
859 hdr_len
= UDP_IO_HDR_SIZE
+hdr
->uih_ip_opt_len
;
862 assert (size
>= hdr_len
);
864 tmp_pack
= bf_cut(pack
, hdr_len
, size
);
869 if (size
>udp_fd
->uf_rd_count
)
871 tmp_pack
= bf_cut (pack
, 0, udp_fd
->uf_rd_count
);
874 transf_size
= udp_fd
->uf_rd_count
;
879 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
880 (size_t)0, pack
, FALSE
);
883 if (size
> transf_size
)
888 udp_fd
->uf_flags
&= ~UFF_READ_IP
;
889 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
, result
,
891 assert (result
== 0);
896 PRIVATE
void udp_ip_arrived(port
, pack
, pack_size
)
901 udp_port_t
*udp_port
;
902 udp_fd_t
*udp_fd
, *share_fd
;
903 acc_t
*ip_hdr_acc
, *udp_acc
, *ipopt_pack
, *no_ipopt_pack
, *tmp_acc
;
906 udp_io_hdr_t
*udp_io_hdr
;
907 size_t ip_hdr_size
, udp_size
, data_size
, opt_size
;
908 ipaddr_t src_addr
, dst_addr
, ipaddr
;
909 udpport_t src_port
, dst_port
;
912 unsigned long dst_type
, flags
;
914 int i
, delivered
, hash
;
916 udp_port
= &udp_port_table
[port
];
918 ip_hdr_acc
= bf_cut(pack
, 0, IP_MIN_HDR_SIZE
);
919 ip_hdr_acc
= bf_packIffLess(ip_hdr_acc
, IP_MIN_HDR_SIZE
);
920 ip_hdr
= (ip_hdr_t
*)ptr2acc_data(ip_hdr_acc
);
921 ip_hdr_size
= (ip_hdr
->ih_vers_ihl
& IH_IHL_MASK
) << 2;
922 if (ip_hdr_size
!= IP_MIN_HDR_SIZE
)
924 bf_afree(ip_hdr_acc
);
925 ip_hdr_acc
= bf_cut(pack
, 0, ip_hdr_size
);
926 ip_hdr_acc
= bf_packIffLess(ip_hdr_acc
, ip_hdr_size
);
927 ip_hdr
= (ip_hdr_t
*)ptr2acc_data(ip_hdr_acc
);
930 pack_size
-= ip_hdr_size
;
931 if (pack_size
< UDP_HDR_SIZE
)
933 if (pack_size
== 0 && ip_hdr
->ih_proto
== 0)
935 /* IP layer reports new IP address */
936 ipaddr
= ip_hdr
->ih_src
;
937 udp_port
->up_ipaddr
= ipaddr
;
938 DBLOCK(1, printf("udp_ip_arrived: using address ");
939 writeIpAddr(ipaddr
); printf("\n"));
942 DBLOCK(1, printf("packet too small\n"));
944 bf_afree(ip_hdr_acc
);
949 udp_acc
= bf_delhead(pack
, ip_hdr_size
);
953 udp_acc
= bf_packIffLess(udp_acc
, UDP_HDR_SIZE
);
954 udp_hdr
= (udp_hdr_t
*)ptr2acc_data(udp_acc
);
955 udp_size
= ntohs(udp_hdr
->uh_length
);
956 if (udp_size
> pack_size
)
958 DBLOCK(1, printf("packet too large\n"));
960 bf_afree(ip_hdr_acc
);
965 src_addr
= ip_hdr
->ih_src
;
966 dst_addr
= ip_hdr
->ih_dst
;
968 if (udp_hdr
->uh_chksum
)
971 u16
[1]= ip_hdr
->ih_proto
;
972 chksum
= pack_oneCsum(udp_acc
);
973 chksum
= oneC_sum(chksum
, (u16_t
*)&src_addr
, sizeof(ipaddr_t
));
974 chksum
= oneC_sum(chksum
, (u16_t
*)&dst_addr
, sizeof(ipaddr_t
));
975 chksum
= oneC_sum(chksum
, (u16_t
*)u16
, sizeof(u16
));
976 chksum
= oneC_sum(chksum
, (u16_t
*)&udp_hdr
->uh_length
,
977 sizeof(udp_hdr
->uh_length
));
978 if (~chksum
& 0xffff)
980 DBLOCK(1, printf("checksum error in udp packet\n");
981 printf("src ip_addr= ");
982 writeIpAddr(src_addr
);
983 printf(" dst ip_addr= ");
984 writeIpAddr(dst_addr
);
986 printf("packet chksum= 0x%x, sum= 0x%x\n",
987 udp_hdr
->uh_chksum
, chksum
));
989 bf_afree(ip_hdr_acc
);
995 exp_tim
= get_time() + UDP_READ_EXP_TIME
;
996 src_port
= udp_hdr
->uh_src_port
;
997 dst_port
= udp_hdr
->uh_dst_port
;
999 /* Send an ICMP port unreachable if the packet could not be
1004 if (dst_addr
== udp_port
->up_ipaddr
)
1005 dst_type
= NWUO_EN_LOC
;
1008 dst_type
= NWUO_EN_BROAD
;
1010 /* Don't send ICMP error packets for broadcast packets */
1014 DBLOCK(0x20, printf("udp: got packet from ");
1015 writeIpAddr(src_addr
);
1016 printf(".%u to ", ntohs(src_port
));
1017 writeIpAddr(dst_addr
);
1018 printf(".%u\n", ntohs(dst_port
)));
1020 no_ipopt_pack
= bf_memreq(UDP_IO_HDR_SIZE
);
1021 udp_io_hdr
= (udp_io_hdr_t
*)ptr2acc_data(no_ipopt_pack
);
1022 udp_io_hdr
->uih_src_addr
= src_addr
;
1023 udp_io_hdr
->uih_dst_addr
= dst_addr
;
1024 udp_io_hdr
->uih_src_port
= src_port
;
1025 udp_io_hdr
->uih_dst_port
= dst_port
;
1026 data_size
= udp_size
-UDP_HDR_SIZE
;
1027 #if CONF_UDP_IO_NW_BYTE_ORDER
1028 udp_io_hdr
->uih_ip_opt_len
= HTONS(0);
1029 udp_io_hdr
->uih_data_len
= htons(data_size
);
1031 udp_io_hdr
->uih_ip_opt_len
= 0;
1032 udp_io_hdr
->uih_data_len
= data_size
;
1034 no_ipopt_pack
->acc_next
= bf_cut(udp_acc
, UDP_HDR_SIZE
, data_size
);
1036 if (ip_hdr_size
== IP_MIN_HDR_SIZE
)
1038 ipopt_pack
= no_ipopt_pack
;
1039 ipopt_pack
->acc_linkC
++;
1043 ipopt_pack
= bf_memreq(UDP_IO_HDR_SIZE
);
1044 *(udp_io_hdr_t
*)ptr2acc_data(ipopt_pack
)= *udp_io_hdr
;
1045 udp_io_hdr
= (udp_io_hdr_t
*)ptr2acc_data(ipopt_pack
);
1046 opt_size
= ip_hdr_size
-IP_MIN_HDR_SIZE
;
1047 #if CONF_UDP_IO_NW_BYTE_ORDER
1048 udp_io_hdr
->uih_ip_opt_len
= htons(opt_size
);
1050 udp_io_hdr
->uih_ip_opt_len
= opt_size
;
1052 tmp_acc
= bf_cut(ip_hdr_acc
, (size_t)IP_MIN_HDR_SIZE
, opt_size
);
1053 assert(tmp_acc
->acc_linkC
== 1);
1054 assert(tmp_acc
->acc_next
== NULL
);
1055 ipopt_pack
->acc_next
= tmp_acc
;
1057 tmp_acc
->acc_next
= no_ipopt_pack
->acc_next
;
1058 if (tmp_acc
->acc_next
)
1059 tmp_acc
->acc_next
->acc_linkC
++;
1063 hash
^= (hash
>> 8);
1064 hash
&= (UDP_PORT_HASH_NR
-1);
1066 for (i
= 0; i
<2; i
++)
1070 udp_fd
= (i
== 0) ? udp_port
->up_port_any
:
1071 udp_port
->up_port_hash
[hash
];
1072 for (; udp_fd
; udp_fd
= udp_fd
->uf_port_next
)
1074 if (i
&& udp_fd
->uf_udpopt
.nwuo_locport
!= dst_port
)
1077 assert(udp_fd
->uf_flags
& UFF_INUSE
);
1078 assert(udp_fd
->uf_flags
& UFF_OPTSET
);
1080 if (udp_fd
->uf_port
!= udp_port
)
1083 flags
= udp_fd
->uf_udpopt
.nwuo_flags
;
1084 if (!(flags
& dst_type
))
1087 if ((flags
& NWUO_RP_SET
) &&
1088 udp_fd
->uf_udpopt
.nwuo_remport
!= src_port
)
1093 if ((flags
& NWUO_RA_SET
) &&
1094 udp_fd
->uf_udpopt
.nwuo_remaddr
!= src_addr
)
1101 /* Packet is considdered to be delivered */
1105 if ((flags
& NWUO_ACC_MASK
) == NWUO_SHARED
&&
1106 (!share_fd
|| !udp_fd
->uf_rdbuf_head
))
1112 if (flags
& NWUO_EN_IPOPT
)
1115 pack
= no_ipopt_pack
;
1118 udp_rd_enqueue(udp_fd
, pack
, exp_tim
);
1119 if (udp_fd
->uf_flags
& UFF_READ_IP
)
1120 udp_packet2user(udp_fd
);
1125 flags
= share_fd
->uf_udpopt
.nwuo_flags
;
1126 if (flags
& NWUO_EN_IPOPT
)
1129 pack
= no_ipopt_pack
;
1132 udp_rd_enqueue(share_fd
, pack
, exp_tim
);
1133 if (share_fd
->uf_flags
& UFF_READ_IP
)
1134 udp_packet2user(share_fd
);
1139 bf_afree(ipopt_pack
);
1141 bf_afree(no_ipopt_pack
);
1145 DBLOCK(0x2, printf("udp: could not deliver packet from ");
1146 writeIpAddr(src_addr
);
1147 printf(".%u to ", ntohs(src_port
));
1148 writeIpAddr(dst_addr
);
1149 printf(".%u\n", ntohs(dst_port
)));
1151 pack
= bf_append(ip_hdr_acc
, udp_acc
);
1154 icmp_snd_unreachable(udp_port
->up_ipdev
, pack
,
1159 assert (ip_hdr_acc
);
1160 bf_afree(ip_hdr_acc
);
1165 PUBLIC
void udp_close(fd
)
1169 acc_t
*tmp_acc
, *next_acc
;
1171 udp_fd
= &udp_fd_table
[fd
];
1173 assert (udp_fd
->uf_flags
& UFF_INUSE
);
1175 if (udp_fd
->uf_flags
& UFF_OPTSET
)
1178 udp_fd
->uf_flags
= UFF_EMPTY
;
1179 tmp_acc
= udp_fd
->uf_rdbuf_head
;
1182 next_acc
= tmp_acc
->acc_ext_link
;
1186 udp_fd
->uf_rdbuf_head
= NULL
;
1189 PUBLIC
int udp_write(fd
, count
)
1194 udp_port_t
*udp_port
;
1196 udp_fd
= &udp_fd_table
[fd
];
1197 udp_port
= udp_fd
->uf_port
;
1199 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
1201 reply_thr_get (udp_fd
, EBADMODE
, FALSE
);
1205 assert (!(udp_fd
->uf_flags
& UFF_WRITE_IP
));
1207 udp_fd
->uf_wr_count
= count
;
1209 udp_fd
->uf_flags
|= UFF_WRITE_IP
;
1211 restart_write_fd(udp_fd
);
1213 if (udp_fd
->uf_flags
& UFF_WRITE_IP
)
1215 DBLOCK(1, printf("replying NW_SUSPEND\n"));
1225 PRIVATE
void restart_write_fd(udp_fd
)
1228 udp_port_t
*udp_port
;
1229 acc_t
*pack
, *ip_hdr_pack
, *udp_hdr_pack
, *ip_opt_pack
, *user_data
;
1231 udp_io_hdr_t
*udp_io_hdr
;
1233 size_t ip_opt_size
, user_data_size
;
1234 unsigned long flags
;
1239 udp_port
= udp_fd
->uf_port
;
1241 if (udp_port
->up_flags
& UPF_WRITE_IP
)
1243 udp_port
->up_flags
|= UPF_MORE2WRITE
;
1247 assert (udp_fd
->uf_flags
& UFF_WRITE_IP
);
1248 udp_fd
->uf_flags
&= ~UFF_WRITE_IP
;
1250 assert (!udp_port
->up_wr_pack
);
1252 pack
= (*udp_fd
->uf_get_userdata
)(udp_fd
->uf_srfd
, 0,
1253 udp_fd
->uf_wr_count
, FALSE
);
1256 udp_fd
->uf_flags
&= ~UFF_WRITE_IP
;
1257 reply_thr_get (udp_fd
, EFAULT
, FALSE
);
1261 flags
= udp_fd
->uf_udpopt
.nwuo_flags
;
1263 ip_hdr_pack
= bf_memreq(IP_MIN_HDR_SIZE
);
1264 ip_hdr
= (ip_hdr_t
*)ptr2acc_data(ip_hdr_pack
);
1266 udp_hdr_pack
= bf_memreq(UDP_HDR_SIZE
);
1267 udp_hdr
= (udp_hdr_t
*)ptr2acc_data(udp_hdr_pack
);
1269 if (flags
& NWUO_RWDATALL
)
1271 pack
= bf_packIffLess(pack
, UDP_IO_HDR_SIZE
);
1272 udp_io_hdr
= (udp_io_hdr_t
*)ptr2acc_data(pack
);
1273 #if CONF_UDP_IO_NW_BYTE_ORDER
1274 ip_opt_size
= ntohs(udp_io_hdr
->uih_ip_opt_len
);
1276 ip_opt_size
= udp_io_hdr
->uih_ip_opt_len
;
1278 if (UDP_IO_HDR_SIZE
+ip_opt_size
>udp_fd
->uf_wr_count
)
1280 bf_afree(ip_hdr_pack
);
1281 bf_afree(udp_hdr_pack
);
1283 reply_thr_get (udp_fd
, EINVAL
, FALSE
);
1286 if (ip_opt_size
& 3)
1288 bf_afree(ip_hdr_pack
);
1289 bf_afree(udp_hdr_pack
);
1291 reply_thr_get (udp_fd
, EFAULT
, FALSE
);
1295 ip_opt_pack
= bf_cut(pack
, UDP_IO_HDR_SIZE
, ip_opt_size
);
1298 user_data_size
= udp_fd
->uf_wr_count
-UDP_IO_HDR_SIZE
-
1300 user_data
= bf_cut(pack
, UDP_IO_HDR_SIZE
+ip_opt_size
,
1308 user_data_size
= udp_fd
->uf_wr_count
;
1313 ip_hdr
->ih_vers_ihl
= (IP_MIN_HDR_SIZE
+ip_opt_size
) >> 2;
1314 ip_hdr
->ih_tos
= UDP_TOS
;
1315 ip_hdr
->ih_flags_fragoff
= HTONS(UDP_IP_FLAGS
);
1316 ip_hdr
->ih_ttl
= IP_DEF_TTL
;
1317 ip_hdr
->ih_proto
= IPPROTO_UDP
;
1318 if (flags
& NWUO_RA_SET
)
1320 ip_hdr
->ih_dst
= udp_fd
->uf_udpopt
.nwuo_remaddr
;
1324 assert (udp_io_hdr
);
1325 ip_hdr
->ih_dst
= udp_io_hdr
->uih_dst_addr
;
1328 if ((flags
& NWUO_LOCPORT_MASK
) != NWUO_LP_ANY
)
1329 udp_hdr
->uh_src_port
= udp_fd
->uf_udpopt
.nwuo_locport
;
1332 assert (udp_io_hdr
);
1333 udp_hdr
->uh_src_port
= udp_io_hdr
->uih_src_port
;
1336 if (flags
& NWUO_RP_SET
)
1337 udp_hdr
->uh_dst_port
= udp_fd
->uf_udpopt
.nwuo_remport
;
1340 assert (udp_io_hdr
);
1341 udp_hdr
->uh_dst_port
= udp_io_hdr
->uih_dst_port
;
1344 udp_hdr
->uh_length
= htons(UDP_HDR_SIZE
+user_data_size
);
1345 udp_hdr
->uh_chksum
= 0;
1347 udp_hdr_pack
->acc_next
= user_data
;
1348 chksum
= pack_oneCsum(udp_hdr_pack
);
1349 chksum
= oneC_sum(chksum
, (u16_t
*)&udp_fd
->uf_port
->up_ipaddr
,
1351 chksum
= oneC_sum(chksum
, (u16_t
*)&ip_hdr
->ih_dst
, sizeof(ipaddr_t
));
1353 u16
[1]= IPPROTO_UDP
;
1354 chksum
= oneC_sum(chksum
, (u16_t
*)u16
, sizeof(u16
));
1355 chksum
= oneC_sum(chksum
, (u16_t
*)&udp_hdr
->uh_length
, sizeof(u16_t
));
1358 udp_hdr
->uh_chksum
= chksum
;
1362 ip_opt_pack
= bf_packIffLess(ip_opt_pack
, ip_opt_size
);
1363 ip_opt_pack
->acc_next
= udp_hdr_pack
;
1364 udp_hdr_pack
= ip_opt_pack
;
1366 ip_hdr_pack
->acc_next
= udp_hdr_pack
;
1368 assert (!udp_port
->up_wr_pack
);
1369 assert (!(udp_port
->up_flags
& UPF_WRITE_IP
));
1371 udp_port
->up_wr_pack
= ip_hdr_pack
;
1372 udp_port
->up_flags
|= UPF_WRITE_IP
;
1373 result
= ip_write(udp_port
->up_ipfd
, bf_bufsize(ip_hdr_pack
));
1374 if (result
== NW_SUSPEND
)
1376 udp_port
->up_flags
|= UPF_WRITE_SP
;
1377 udp_fd
->uf_flags
|= UFF_WRITE_IP
;
1378 udp_port
->up_write_fd
= udp_fd
;
1381 reply_thr_get(udp_fd
, result
, FALSE
);
1383 reply_thr_get (udp_fd
, udp_fd
->uf_wr_count
, FALSE
);
1386 PRIVATE u16_t
pack_oneCsum(pack
)
1400 for (; pack
; pack
= pack
->acc_next
)
1403 data_ptr
= ptr2acc_data(pack
);
1404 length
= pack
->acc_length
;
1410 byte_buf
[1]= *data_ptr
;
1411 prev
= oneC_sum(prev
, (u16_t
*)byte_buf
, 2);
1420 byte_buf
[0]= data_ptr
[length
];
1424 prev
= oneC_sum (prev
, (u16_t
*)data_ptr
, length
);
1429 prev
= oneC_sum (prev
, (u16_t
*)byte_buf
, 1);
1434 PRIVATE
void udp_restart_write_port(udp_port
)
1435 udp_port_t
*udp_port
;
1440 assert (!udp_port
->up_wr_pack
);
1441 assert (!(udp_port
->up_flags
& (UPF_WRITE_IP
|UPF_WRITE_SP
)));
1443 while (udp_port
->up_flags
& UPF_MORE2WRITE
)
1445 udp_port
->up_flags
&= ~UPF_MORE2WRITE
;
1447 for (i
= 0, udp_fd
= udp_port
->up_next_fd
; i
<UDP_FD_NR
;
1450 if (udp_fd
== &udp_fd_table
[UDP_FD_NR
])
1451 udp_fd
= udp_fd_table
;
1453 if (!(udp_fd
->uf_flags
& UFF_INUSE
))
1455 if (!(udp_fd
->uf_flags
& UFF_WRITE_IP
))
1457 if (udp_fd
->uf_port
!= udp_port
)
1459 restart_write_fd(udp_fd
);
1460 if (udp_port
->up_flags
& UPF_WRITE_IP
)
1462 udp_port
->up_next_fd
= udp_fd
+1;
1463 udp_port
->up_flags
|= UPF_MORE2WRITE
;
1470 PUBLIC
int udp_cancel(fd
, which_operation
)
1472 int which_operation
;
1476 DBLOCK(0x10, printf("udp_cancel(%d, %d)\n", fd
, which_operation
));
1478 udp_fd
= &udp_fd_table
[fd
];
1480 switch (which_operation
)
1482 case SR_CANCEL_READ
:
1483 assert (udp_fd
->uf_flags
& UFF_READ_IP
);
1484 udp_fd
->uf_flags
&= ~UFF_READ_IP
;
1485 reply_thr_put(udp_fd
, EINTR
, FALSE
);
1487 case SR_CANCEL_WRITE
:
1488 assert (udp_fd
->uf_flags
& UFF_WRITE_IP
);
1489 udp_fd
->uf_flags
&= ~UFF_WRITE_IP
;
1490 if (udp_fd
->uf_port
->up_write_fd
== udp_fd
)
1491 udp_fd
->uf_port
->up_write_fd
= NULL
;
1492 reply_thr_get(udp_fd
, EINTR
, FALSE
);
1494 case SR_CANCEL_IOCTL
:
1495 assert (udp_fd
->uf_flags
& UFF_IOCTL_IP
);
1496 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
1497 udp_fd
->uf_flags
&= ~UFF_PEEK_IP
;
1498 reply_thr_get(udp_fd
, EINTR
, TRUE
);
1501 ip_panic(( "got unknown cancel request" ));
1506 PRIVATE
void udp_buffree (priority
)
1513 if (priority
== UDP_PRI_FDBUFS_EXTRA
)
1515 for (i
=0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++, udp_fd
++)
1517 while (udp_fd
->uf_rdbuf_head
&&
1518 udp_fd
->uf_rdbuf_head
->acc_ext_link
)
1520 tmp_acc
= udp_fd
->uf_rdbuf_head
;
1521 udp_fd
->uf_rdbuf_head
= tmp_acc
->acc_ext_link
;
1527 if (priority
== UDP_PRI_FDBUFS
)
1529 for (i
=0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++, udp_fd
++)
1531 while (udp_fd
->uf_rdbuf_head
)
1533 tmp_acc
= udp_fd
->uf_rdbuf_head
;
1534 udp_fd
->uf_rdbuf_head
= tmp_acc
->acc_ext_link
;
1541 PRIVATE
void udp_rd_enqueue(udp_fd
, pack
, exp_tim
)
1549 if (pack
->acc_linkC
!= 1)
1551 tmp_acc
= bf_dupacc(pack
);
1555 pack
->acc_ext_link
= NULL
;
1556 if (udp_fd
->uf_rdbuf_head
== NULL
)
1558 udp_fd
->uf_exp_tim
= exp_tim
;
1559 udp_fd
->uf_rdbuf_head
= pack
;
1562 udp_fd
->uf_rdbuf_tail
->acc_ext_link
= pack
;
1563 udp_fd
->uf_rdbuf_tail
= pack
;
1565 if (udp_fd
->uf_flags
& UFF_PEEK_IP
)
1567 pack
= bf_cut(udp_fd
->uf_rdbuf_head
, 0,
1568 sizeof(udp_io_hdr_t
));
1569 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
1570 (size_t)0, pack
, TRUE
);
1572 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
1573 udp_fd
->uf_flags
&= ~UFF_PEEK_IP
;
1574 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
1575 result
, (acc_t
*)0, TRUE
);
1576 assert (result
== 0);
1579 if (udp_fd
->uf_flags
& UFF_SEL_READ
)
1581 udp_fd
->uf_flags
&= ~UFF_SEL_READ
;
1582 if (udp_fd
->uf_select_res
)
1583 udp_fd
->uf_select_res(udp_fd
->uf_srfd
, SR_SELECT_READ
);
1585 printf("udp_rd_enqueue: no select_res\n");
1589 PRIVATE
void hash_fd(udp_fd
)
1592 udp_port_t
*udp_port
;
1595 udp_port
= udp_fd
->uf_port
;
1596 if ((udp_fd
->uf_udpopt
.nwuo_flags
& NWUO_LOCPORT_MASK
) ==
1599 udp_fd
->uf_port_next
= udp_port
->up_port_any
;
1600 udp_port
->up_port_any
= udp_fd
;
1604 hash
= udp_fd
->uf_udpopt
.nwuo_locport
;
1605 hash
^= (hash
>> 8);
1606 hash
&= (UDP_PORT_HASH_NR
-1);
1608 udp_fd
->uf_port_next
= udp_port
->up_port_hash
[hash
];
1609 udp_port
->up_port_hash
[hash
]= udp_fd
;
1613 PRIVATE
void unhash_fd(udp_fd
)
1616 udp_port_t
*udp_port
;
1617 udp_fd_t
*prev
, *curr
, **udp_fd_p
;
1620 udp_port
= udp_fd
->uf_port
;
1621 if ((udp_fd
->uf_udpopt
.nwuo_flags
& NWUO_LOCPORT_MASK
) ==
1624 udp_fd_p
= &udp_port
->up_port_any
;
1628 hash
= udp_fd
->uf_udpopt
.nwuo_locport
;
1629 hash
^= (hash
>> 8);
1630 hash
&= (UDP_PORT_HASH_NR
-1);
1632 udp_fd_p
= &udp_port
->up_port_hash
[hash
];
1634 for (prev
= NULL
, curr
= *udp_fd_p
; curr
;
1635 prev
= curr
, curr
= curr
->uf_port_next
)
1642 prev
->uf_port_next
= curr
->uf_port_next
;
1644 *udp_fd_p
= curr
->uf_port_next
;
1647 #ifdef BUF_CONSISTENCY_CHECK
1648 PRIVATE
void udp_bufcheck()
1651 udp_port_t
*udp_port
;
1655 for (i
= 0, udp_port
= udp_port_table
; i
<udp_conf_nr
; i
++, udp_port
++)
1657 if (udp_port
->up_wr_pack
)
1658 bf_check_acc(udp_port
->up_wr_pack
);
1661 for (i
= 0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++, udp_fd
++)
1663 for (tmp_acc
= udp_fd
->uf_rdbuf_head
; tmp_acc
;
1664 tmp_acc
= tmp_acc
->acc_ext_link
)
1666 bf_check_acc(tmp_acc
);
1673 * $PchId: udp.c,v 1.25 2005/06/28 14:14:44 philip Exp $