4 Copyright 1995 Philip Homburg
22 static void read_ip_packets
ARGS(( udp_port_t
*udp_port
));
23 static void udp_buffree
ARGS(( int priority
));
24 #ifdef BUF_CONSISTENCY_CHECK
25 static void udp_bufcheck
ARGS(( void ));
27 static void udp_main
ARGS(( udp_port_t
*udp_port
));
28 static int udp_select
ARGS(( int fd
, unsigned operations
));
29 static acc_t
*udp_get_data
ARGS(( int fd
, size_t offset
, size_t count
,
31 static int udp_put_data
ARGS(( int fd
, size_t offset
, acc_t
*data
,
33 static int udp_peek
ARGS(( udp_fd_t
* ));
34 static int udp_sel_read
ARGS(( udp_fd_t
* ));
35 static void udp_restart_write_port
ARGS(( udp_port_t
*udp_port
));
36 static void udp_ip_arrived
ARGS(( int port
, acc_t
*pack
, size_t pack_size
));
37 static void reply_thr_put
ARGS(( udp_fd_t
*udp_fd
, int reply
,
39 static void reply_thr_get
ARGS(( udp_fd_t
*udp_fd
, int reply
,
41 static int udp_setopt
ARGS(( udp_fd_t
*udp_fd
));
42 static udpport_t find_unused_port
ARGS(( int fd
));
43 static int is_unused_port
ARGS(( udpport_t port
));
44 static int udp_packet2user
ARGS(( udp_fd_t
*udp_fd
));
45 static void restart_write_fd
ARGS(( udp_fd_t
*udp_fd
));
46 static u16_t pack_oneCsum
ARGS(( acc_t
*pack
));
47 static void udp_rd_enqueue
ARGS(( udp_fd_t
*udp_fd
, acc_t
*pack
,
49 static void hash_fd
ARGS(( udp_fd_t
*udp_fd
));
50 static void unhash_fd
ARGS(( udp_fd_t
*udp_fd
));
52 udp_port_t
*udp_port_table
;
53 udp_fd_t udp_fd_table
[UDP_FD_NR
];
57 udp_port_table
= alloc(udp_conf_nr
* sizeof(udp_port_table
[0]));
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 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 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 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 static 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 static int udp_select(fd
, operations
)
302 udp_fd
= &udp_fd_table
[fd
];
303 assert (udp_fd
->uf_flags
& UFF_INUSE
);
307 if (operations
& SR_SELECT_READ
)
309 if (udp_sel_read(udp_fd
))
310 resops
|= SR_SELECT_READ
;
311 else if (!(operations
& SR_SELECT_POLL
))
312 udp_fd
->uf_flags
|= UFF_SEL_READ
;
314 if (operations
& SR_SELECT_WRITE
)
316 /* Should handle special case when the interface is down */
317 resops
|= SR_SELECT_WRITE
;
319 if (operations
& SR_SELECT_EXCEPTION
)
321 printf("udp_select: not implemented for exceptions\n");
326 static acc_t
*udp_get_data (port
, offset
, count
, for_ioctl
)
332 udp_port_t
*udp_port
;
336 udp_port
= &udp_port_table
[port
];
338 switch(udp_port
->up_state
)
347 udp_port
->up_state
= UPS_ERROR
;
350 udp_port
->up_state
= UPS_GETCONF
;
351 if (udp_port
->up_flags
& UPF_SUSPEND
)
357 struct nwio_ipopt
*ipopt
;
361 assert (count
== sizeof(*ipopt
));
363 acc
= bf_memreq(sizeof(*ipopt
));
364 ipopt
= (struct nwio_ipopt
*)ptr2acc_data(acc
);
365 ipopt
->nwio_flags
= NWIO_COPY
| NWIO_EN_LOC
|
366 NWIO_EN_BROAD
| NWIO_REMANY
| NWIO_PROTOSPEC
|
367 NWIO_HDR_O_ANY
| NWIO_RWDATALL
;
368 ipopt
->nwio_proto
= IPPROTO_UDP
;
373 assert (udp_port
->up_flags
& UPF_WRITE_IP
);
377 assert (udp_port
->up_wr_pack
);
378 bf_afree(udp_port
->up_wr_pack
);
379 udp_port
->up_wr_pack
= 0;
380 if (udp_port
->up_flags
& UPF_WRITE_SP
)
382 if (udp_port
->up_write_fd
)
384 udp_fd
= udp_port
->up_write_fd
;
385 udp_port
->up_write_fd
= NULL
;
386 udp_fd
->uf_flags
&= ~UFF_WRITE_IP
;
387 reply_thr_get(udp_fd
, result
, FALSE
);
389 udp_port
->up_flags
&= ~(UPF_WRITE_SP
|
391 if (udp_port
->up_flags
& UPF_MORE2WRITE
)
393 udp_restart_write_port(udp_port
);
397 udp_port
->up_flags
&= ~UPF_WRITE_IP
;
401 return bf_cut (udp_port
->up_wr_pack
, offset
, count
);
405 printf("udp_get_data(%d, 0x%x, 0x%x) called but up_state= 0x%x\n",
406 port
, offset
, count
, udp_port
->up_state
);
412 static int udp_put_data (fd
, offset
, data
, for_ioctl
)
418 udp_port_t
*udp_port
;
421 udp_port
= &udp_port_table
[fd
];
423 switch (udp_port
->up_state
)
431 udp_port
->up_state
= UPS_ERROR
;
434 udp_port
->up_state
= UPS_MAIN
;
435 if (udp_port
->up_flags
& UPF_SUSPEND
)
440 struct nwio_ipconf
*ipconf
;
442 data
= bf_packIffLess(data
, sizeof(*ipconf
));
443 ipconf
= (struct nwio_ipconf
*)ptr2acc_data(data
);
444 assert (ipconf
->nwic_flags
& NWIC_IPADDR_SET
);
445 udp_port
->up_ipaddr
= ipconf
->nwic_ipaddr
;
452 assert (udp_port
->up_flags
& UPF_READ_IP
);
456 compare (result
, >=, 0);
457 if (udp_port
->up_flags
& UPF_READ_SP
)
459 udp_port
->up_flags
&= ~(UPF_READ_SP
|
461 read_ip_packets(udp_port
);
464 udp_port
->up_flags
&= ~UPF_READ_IP
;
468 assert (!offset
); /* This isn't a valid assertion but ip sends only
469 * whole datagrams up */
470 udp_ip_arrived(fd
, data
, bf_bufsize(data
));
475 "udp_put_data(%d, 0x%x, %p) called but up_state= 0x%x\n",
476 fd
, offset
, data
, udp_port
->up_state
));
481 static int udp_setopt(udp_fd
)
485 nwio_udpopt_t oldopt
, newopt
;
487 unsigned int new_en_flags
, new_di_flags
, old_en_flags
, old_di_flags
,
489 unsigned long new_flags
;
492 data
= (*udp_fd
->uf_get_userdata
)(udp_fd
->uf_srfd
, 0,
493 sizeof(nwio_udpopt_t
), TRUE
);
498 data
= bf_packIffLess(data
, sizeof(nwio_udpopt_t
));
499 assert (data
->acc_length
== sizeof(nwio_udpopt_t
));
501 newopt
= *(nwio_udpopt_t
*)ptr2acc_data(data
);
503 oldopt
= udp_fd
->uf_udpopt
;
505 old_en_flags
= oldopt
.nwuo_flags
& 0xffff;
506 old_di_flags
= (oldopt
.nwuo_flags
>> 16) & 0xffff;
508 new_en_flags
= newopt
.nwuo_flags
& 0xffff;
509 new_di_flags
= (newopt
.nwuo_flags
>> 16) & 0xffff;
511 if (new_en_flags
& new_di_flags
)
513 DBLOCK(1, printf("returning EBADMODE\n"));
515 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
520 if (new_di_flags
& NWUO_ACC_MASK
)
522 DBLOCK(1, printf("returning EBADMODE\n"));
524 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
526 /* access modes can't be disabled */
529 if (!(new_en_flags
& NWUO_ACC_MASK
))
530 new_en_flags
|= (old_en_flags
& NWUO_ACC_MASK
);
532 /* NWUO_LOCPORT_MASK */
533 if (new_di_flags
& NWUO_LOCPORT_MASK
)
535 DBLOCK(1, printf("returning EBADMODE\n"));
537 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
539 /* the loc ports can't be disabled */
541 if (!(new_en_flags
& NWUO_LOCPORT_MASK
))
543 new_en_flags
|= (old_en_flags
& NWUO_LOCPORT_MASK
);
544 newopt
.nwuo_locport
= oldopt
.nwuo_locport
;
546 else if ((new_en_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SEL
)
548 newopt
.nwuo_locport
= find_unused_port(udp_fd
-udp_fd_table
);
550 else if ((new_en_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SET
)
552 if (!newopt
.nwuo_locport
)
554 DBLOCK(1, printf("returning EBADMODE\n"));
556 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
561 /* NWUO_LOCADDR_MASK */
562 if (!((new_en_flags
| new_di_flags
) & NWUO_LOCADDR_MASK
))
564 new_en_flags
|= (old_en_flags
& NWUO_LOCADDR_MASK
);
565 new_di_flags
|= (old_di_flags
& NWUO_LOCADDR_MASK
);
568 /* NWUO_BROAD_MASK */
569 if (!((new_en_flags
| new_di_flags
) & NWUO_BROAD_MASK
))
571 new_en_flags
|= (old_en_flags
& NWUO_BROAD_MASK
);
572 new_di_flags
|= (old_di_flags
& NWUO_BROAD_MASK
);
575 /* NWUO_REMPORT_MASK */
576 if (!((new_en_flags
| new_di_flags
) & NWUO_REMPORT_MASK
))
578 new_en_flags
|= (old_en_flags
& NWUO_REMPORT_MASK
);
579 new_di_flags
|= (old_di_flags
& NWUO_REMPORT_MASK
);
580 newopt
.nwuo_remport
= oldopt
.nwuo_remport
;
583 /* NWUO_REMADDR_MASK */
584 if (!((new_en_flags
| new_di_flags
) & NWUO_REMADDR_MASK
))
586 new_en_flags
|= (old_en_flags
& NWUO_REMADDR_MASK
);
587 new_di_flags
|= (old_di_flags
& NWUO_REMADDR_MASK
);
588 newopt
.nwuo_remaddr
= oldopt
.nwuo_remaddr
;
592 if (!((new_en_flags
| new_di_flags
) & NWUO_RW_MASK
))
594 new_en_flags
|= (old_en_flags
& NWUO_RW_MASK
);
595 new_di_flags
|= (old_di_flags
& NWUO_RW_MASK
);
598 /* NWUO_IPOPT_MASK */
599 if (!((new_en_flags
| new_di_flags
) & NWUO_IPOPT_MASK
))
601 new_en_flags
|= (old_en_flags
& NWUO_IPOPT_MASK
);
602 new_di_flags
|= (old_di_flags
& NWUO_IPOPT_MASK
);
605 new_flags
= ((unsigned long)new_di_flags
<< 16) | new_en_flags
;
606 if ((new_flags
& NWUO_RWDATONLY
) &&
607 ((new_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_ANY
||
608 (new_flags
& (NWUO_RP_ANY
|NWUO_RA_ANY
|NWUO_EN_IPOPT
))))
610 DBLOCK(1, printf("returning EBADMODE\n"));
612 reply_thr_get(udp_fd
, EBADMODE
, TRUE
);
616 /* Check the access modes */
617 if ((new_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SEL
||
618 (new_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SET
)
620 for (i
= 0, fd_ptr
= udp_fd_table
; i
<UDP_FD_NR
; i
++, fd_ptr
++)
622 if (fd_ptr
== udp_fd
)
624 if (!(fd_ptr
->uf_flags
& UFF_INUSE
))
626 if (fd_ptr
->uf_port
!= udp_fd
->uf_port
)
628 flags
= fd_ptr
->uf_udpopt
.nwuo_flags
;
629 if ((flags
& NWUO_LOCPORT_MASK
) != NWUO_LP_SEL
&&
630 (flags
& NWUO_LOCPORT_MASK
) != NWUO_LP_SET
)
632 if (fd_ptr
->uf_udpopt
.nwuo_locport
!=
637 if ((flags
& NWUO_ACC_MASK
) !=
638 (new_flags
& NWUO_ACC_MASK
))
641 "address inuse: new fd= %d, old_fd= %d, port= %u\n",
644 newopt
.nwuo_locport
));
646 reply_thr_get(udp_fd
, EADDRINUSE
, TRUE
);
652 if (udp_fd
->uf_flags
& UFF_OPTSET
)
655 newopt
.nwuo_flags
= new_flags
;
656 udp_fd
->uf_udpopt
= newopt
;
658 all_flags
= new_en_flags
| new_di_flags
;
659 if ((all_flags
& NWUO_ACC_MASK
) && (all_flags
& NWUO_LOCPORT_MASK
) &&
660 (all_flags
& NWUO_LOCADDR_MASK
) &&
661 (all_flags
& NWUO_BROAD_MASK
) &&
662 (all_flags
& NWUO_REMPORT_MASK
) &&
663 (all_flags
& NWUO_REMADDR_MASK
) &&
664 (all_flags
& NWUO_RW_MASK
) &&
665 (all_flags
& NWUO_IPOPT_MASK
))
666 udp_fd
->uf_flags
|= UFF_OPTSET
;
669 udp_fd
->uf_flags
&= ~UFF_OPTSET
;
672 if (udp_fd
->uf_flags
& UFF_OPTSET
)
675 reply_thr_get(udp_fd
, NW_OK
, TRUE
);
679 static udpport_t
find_unused_port(int fd
)
681 udpport_t port
, nw_port
;
683 for (port
= 0x8000+fd
; port
< 0xffff-UDP_FD_NR
; port
+= UDP_FD_NR
)
685 nw_port
= htons(port
);
686 if (is_unused_port(nw_port
))
689 for (port
= 0x8000; port
< 0xffff; port
++)
691 nw_port
= htons(port
);
692 if (is_unused_port(nw_port
))
695 ip_panic(( "unable to find unused port (shouldn't occur)" ));
703 static void reply_thr_put(udp_fd
, reply
, for_ioctl
)
710 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
, reply
,
711 (acc_t
*)0, for_ioctl
);
712 assert(result
== NW_OK
);
719 static void reply_thr_get(udp_fd
, reply
, for_ioctl
)
725 result
= (*udp_fd
->uf_get_userdata
)(udp_fd
->uf_srfd
, reply
,
726 (size_t)0, for_ioctl
);
730 static int is_unused_port(udpport_t port
)
735 for (i
= 0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++,
738 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
740 if (udp_fd
->uf_udpopt
.nwuo_locport
== port
)
746 static void read_ip_packets(udp_port
)
747 udp_port_t
*udp_port
;
753 udp_port
->up_flags
|= UPF_READ_IP
;
754 result
= ip_read(udp_port
->up_ipfd
, UDP_MAX_DATAGRAM
);
755 if (result
== NW_SUSPEND
)
757 udp_port
->up_flags
|= UPF_READ_SP
;
760 assert(result
== NW_OK
);
761 udp_port
->up_flags
&= ~UPF_READ_IP
;
762 } while(!(udp_port
->up_flags
& UPF_READ_IP
));
766 static int udp_peek (udp_fd
)
769 acc_t
*pack
, *tmp_acc
, *next_acc
;
772 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
774 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
775 reply_thr_put(udp_fd
, EBADMODE
, TRUE
);
779 if (udp_fd
->uf_rdbuf_head
)
781 if (get_time() <= udp_fd
->uf_exp_tim
)
783 pack
= bf_cut(udp_fd
->uf_rdbuf_head
, 0,
784 sizeof(udp_io_hdr_t
));
785 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
786 (size_t)0, pack
, TRUE
);
788 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
789 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
790 result
, (acc_t
*)0, TRUE
);
791 assert (result
== 0);
794 tmp_acc
= udp_fd
->uf_rdbuf_head
;
797 next_acc
= tmp_acc
->acc_ext_link
;
801 udp_fd
->uf_rdbuf_head
= NULL
;
803 udp_fd
->uf_flags
|= UFF_PEEK_IP
;
807 static int udp_sel_read (udp_fd_t
*udp_fd
)
809 acc_t
*tmp_acc
, *next_acc
;
811 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
812 return 1; /* Read will not block */
814 if (udp_fd
->uf_rdbuf_head
)
816 if (get_time() <= udp_fd
->uf_exp_tim
)
819 tmp_acc
= udp_fd
->uf_rdbuf_head
;
822 next_acc
= tmp_acc
->acc_ext_link
;
826 udp_fd
->uf_rdbuf_head
= NULL
;
831 static int udp_packet2user (udp_fd
)
834 acc_t
*pack
, *tmp_pack
;
837 size_t size
, transf_size
;
839 pack
= udp_fd
->uf_rdbuf_head
;
840 udp_fd
->uf_rdbuf_head
= pack
->acc_ext_link
;
842 size
= bf_bufsize (pack
);
844 if (udp_fd
->uf_udpopt
.nwuo_flags
& NWUO_RWDATONLY
)
847 pack
= bf_packIffLess (pack
, UDP_IO_HDR_SIZE
);
848 assert (pack
->acc_length
>= UDP_IO_HDR_SIZE
);
850 hdr
= (udp_io_hdr_t
*)ptr2acc_data(pack
);
851 #if CONF_UDP_IO_NW_BYTE_ORDER
852 hdr_len
= UDP_IO_HDR_SIZE
+NTOHS(hdr
->uih_ip_opt_len
);
854 hdr_len
= UDP_IO_HDR_SIZE
+hdr
->uih_ip_opt_len
;
857 assert (size
>= hdr_len
);
859 tmp_pack
= bf_cut(pack
, hdr_len
, size
);
864 if (size
>udp_fd
->uf_rd_count
)
866 tmp_pack
= bf_cut (pack
, 0, udp_fd
->uf_rd_count
);
869 transf_size
= udp_fd
->uf_rd_count
;
874 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
875 (size_t)0, pack
, FALSE
);
878 if (size
> transf_size
)
884 udp_fd
->uf_flags
&= ~UFF_READ_IP
;
885 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
, result
,
887 assert (result
== 0);
892 static void udp_ip_arrived(port
, pack
, pack_size
)
897 udp_port_t
*udp_port
;
898 udp_fd_t
*udp_fd
, *share_fd
;
899 acc_t
*ip_hdr_acc
, *udp_acc
, *ipopt_pack
, *no_ipopt_pack
, *tmp_acc
;
902 udp_io_hdr_t
*udp_io_hdr
;
903 size_t ip_hdr_size
, udp_size
, data_size
, opt_size
;
904 ipaddr_t src_addr
, dst_addr
, ipaddr
;
905 udpport_t src_port
, dst_port
;
908 unsigned long dst_type
, flags
;
910 int i
, delivered
, hash
;
912 udp_port
= &udp_port_table
[port
];
914 ip_hdr_acc
= bf_cut(pack
, 0, IP_MIN_HDR_SIZE
);
915 ip_hdr_acc
= bf_packIffLess(ip_hdr_acc
, IP_MIN_HDR_SIZE
);
916 ip_hdr
= (ip_hdr_t
*)ptr2acc_data(ip_hdr_acc
);
917 ip_hdr_size
= (ip_hdr
->ih_vers_ihl
& IH_IHL_MASK
) << 2;
918 if (ip_hdr_size
!= IP_MIN_HDR_SIZE
)
920 bf_afree(ip_hdr_acc
);
921 ip_hdr_acc
= bf_cut(pack
, 0, ip_hdr_size
);
922 ip_hdr_acc
= bf_packIffLess(ip_hdr_acc
, ip_hdr_size
);
923 ip_hdr
= (ip_hdr_t
*)ptr2acc_data(ip_hdr_acc
);
926 pack_size
-= ip_hdr_size
;
927 if (pack_size
< UDP_HDR_SIZE
)
929 if (pack_size
== 0 && ip_hdr
->ih_proto
== 0)
931 /* IP layer reports new IP address */
932 ipaddr
= ip_hdr
->ih_src
;
933 udp_port
->up_ipaddr
= ipaddr
;
934 DBLOCK(1, printf("udp_ip_arrived: using address ");
935 writeIpAddr(ipaddr
); printf("\n"));
938 DBLOCK(1, printf("packet too small\n"));
940 bf_afree(ip_hdr_acc
);
945 udp_acc
= bf_delhead(pack
, ip_hdr_size
);
949 udp_acc
= bf_packIffLess(udp_acc
, UDP_HDR_SIZE
);
950 udp_hdr
= (udp_hdr_t
*)ptr2acc_data(udp_acc
);
951 udp_size
= ntohs(udp_hdr
->uh_length
);
952 if (udp_size
> pack_size
)
954 DBLOCK(1, printf("packet too large\n"));
956 bf_afree(ip_hdr_acc
);
961 src_addr
= ip_hdr
->ih_src
;
962 dst_addr
= ip_hdr
->ih_dst
;
964 if (udp_hdr
->uh_chksum
)
967 u16
[1]= ip_hdr
->ih_proto
;
968 chksum
= pack_oneCsum(udp_acc
);
969 chksum
= oneC_sum(chksum
, (u16_t
*)&src_addr
, sizeof(ipaddr_t
));
970 chksum
= oneC_sum(chksum
, (u16_t
*)&dst_addr
, sizeof(ipaddr_t
));
971 chksum
= oneC_sum(chksum
, (u16_t
*)u16
, sizeof(u16
));
972 chksum
= oneC_sum(chksum
, (u16_t
*)&udp_hdr
->uh_length
,
973 sizeof(udp_hdr
->uh_length
));
974 if (~chksum
& 0xffff)
976 DBLOCK(1, printf("checksum error in udp packet\n");
977 printf("src ip_addr= ");
978 writeIpAddr(src_addr
);
979 printf(" dst ip_addr= ");
980 writeIpAddr(dst_addr
);
982 printf("packet chksum= 0x%x, sum= 0x%x\n",
983 udp_hdr
->uh_chksum
, chksum
));
985 bf_afree(ip_hdr_acc
);
991 exp_tim
= get_time() + UDP_READ_EXP_TIME
;
992 src_port
= udp_hdr
->uh_src_port
;
993 dst_port
= udp_hdr
->uh_dst_port
;
995 /* Send an ICMP port unreachable if the packet could not be
1000 if (dst_addr
== udp_port
->up_ipaddr
)
1001 dst_type
= NWUO_EN_LOC
;
1004 dst_type
= NWUO_EN_BROAD
;
1006 /* Don't send ICMP error packets for broadcast packets */
1010 DBLOCK(0x20, printf("udp: got packet from ");
1011 writeIpAddr(src_addr
);
1012 printf(".%u to ", ntohs(src_port
));
1013 writeIpAddr(dst_addr
);
1014 printf(".%u\n", ntohs(dst_port
)));
1016 no_ipopt_pack
= bf_memreq(UDP_IO_HDR_SIZE
);
1017 udp_io_hdr
= (udp_io_hdr_t
*)ptr2acc_data(no_ipopt_pack
);
1018 udp_io_hdr
->uih_src_addr
= src_addr
;
1019 udp_io_hdr
->uih_dst_addr
= dst_addr
;
1020 udp_io_hdr
->uih_src_port
= src_port
;
1021 udp_io_hdr
->uih_dst_port
= dst_port
;
1022 data_size
= udp_size
-UDP_HDR_SIZE
;
1023 #if CONF_UDP_IO_NW_BYTE_ORDER
1024 udp_io_hdr
->uih_ip_opt_len
= HTONS(0);
1025 udp_io_hdr
->uih_data_len
= htons(data_size
);
1027 udp_io_hdr
->uih_ip_opt_len
= 0;
1028 udp_io_hdr
->uih_data_len
= data_size
;
1030 no_ipopt_pack
->acc_next
= bf_cut(udp_acc
, UDP_HDR_SIZE
, data_size
);
1032 if (ip_hdr_size
== IP_MIN_HDR_SIZE
)
1034 ipopt_pack
= no_ipopt_pack
;
1035 ipopt_pack
->acc_linkC
++;
1039 ipopt_pack
= bf_memreq(UDP_IO_HDR_SIZE
);
1040 *(udp_io_hdr_t
*)ptr2acc_data(ipopt_pack
)= *udp_io_hdr
;
1041 udp_io_hdr
= (udp_io_hdr_t
*)ptr2acc_data(ipopt_pack
);
1042 opt_size
= ip_hdr_size
-IP_MIN_HDR_SIZE
;
1043 #if CONF_UDP_IO_NW_BYTE_ORDER
1044 udp_io_hdr
->uih_ip_opt_len
= htons(opt_size
);
1046 udp_io_hdr
->uih_ip_opt_len
= opt_size
;
1048 tmp_acc
= bf_cut(ip_hdr_acc
, (size_t)IP_MIN_HDR_SIZE
, opt_size
);
1049 assert(tmp_acc
->acc_linkC
== 1);
1050 assert(tmp_acc
->acc_next
== NULL
);
1051 ipopt_pack
->acc_next
= tmp_acc
;
1053 tmp_acc
->acc_next
= no_ipopt_pack
->acc_next
;
1054 if (tmp_acc
->acc_next
)
1055 tmp_acc
->acc_next
->acc_linkC
++;
1059 hash
^= (hash
>> 8);
1060 hash
&= (UDP_PORT_HASH_NR
-1);
1062 for (i
= 0; i
<2; i
++)
1066 udp_fd
= (i
== 0) ? udp_port
->up_port_any
:
1067 udp_port
->up_port_hash
[hash
];
1068 for (; udp_fd
; udp_fd
= udp_fd
->uf_port_next
)
1070 if (i
&& udp_fd
->uf_udpopt
.nwuo_locport
!= dst_port
)
1073 assert(udp_fd
->uf_flags
& UFF_INUSE
);
1074 assert(udp_fd
->uf_flags
& UFF_OPTSET
);
1076 if (udp_fd
->uf_port
!= udp_port
)
1079 flags
= udp_fd
->uf_udpopt
.nwuo_flags
;
1080 if (!(flags
& dst_type
))
1083 if ((flags
& NWUO_RP_SET
) &&
1084 udp_fd
->uf_udpopt
.nwuo_remport
!= src_port
)
1089 if ((flags
& NWUO_RA_SET
) &&
1090 udp_fd
->uf_udpopt
.nwuo_remaddr
!= src_addr
)
1097 /* Packet is considdered to be delivered */
1101 if ((flags
& NWUO_ACC_MASK
) == NWUO_SHARED
&&
1102 (!share_fd
|| !udp_fd
->uf_rdbuf_head
))
1108 if (flags
& NWUO_EN_IPOPT
)
1111 pack
= no_ipopt_pack
;
1114 udp_rd_enqueue(udp_fd
, pack
, exp_tim
);
1115 if (udp_fd
->uf_flags
& UFF_READ_IP
)
1116 udp_packet2user(udp_fd
);
1121 flags
= share_fd
->uf_udpopt
.nwuo_flags
;
1122 if (flags
& NWUO_EN_IPOPT
)
1125 pack
= no_ipopt_pack
;
1128 udp_rd_enqueue(share_fd
, pack
, exp_tim
);
1129 if (share_fd
->uf_flags
& UFF_READ_IP
)
1130 udp_packet2user(share_fd
);
1135 bf_afree(ipopt_pack
);
1137 bf_afree(no_ipopt_pack
);
1141 DBLOCK(0x2, printf("udp: could not deliver packet from ");
1142 writeIpAddr(src_addr
);
1143 printf(".%u to ", ntohs(src_port
));
1144 writeIpAddr(dst_addr
);
1145 printf(".%u\n", ntohs(dst_port
)));
1147 pack
= bf_append(ip_hdr_acc
, udp_acc
);
1150 icmp_snd_unreachable(udp_port
->up_ipdev
, pack
,
1155 assert (ip_hdr_acc
);
1156 bf_afree(ip_hdr_acc
);
1165 acc_t
*tmp_acc
, *next_acc
;
1167 udp_fd
= &udp_fd_table
[fd
];
1169 assert (udp_fd
->uf_flags
& UFF_INUSE
);
1171 if (udp_fd
->uf_flags
& UFF_OPTSET
)
1174 udp_fd
->uf_flags
= UFF_EMPTY
;
1175 tmp_acc
= udp_fd
->uf_rdbuf_head
;
1178 next_acc
= tmp_acc
->acc_ext_link
;
1182 udp_fd
->uf_rdbuf_head
= NULL
;
1185 int udp_write(int fd
, size_t count
)
1189 udp_fd
= &udp_fd_table
[fd
];
1191 if (!(udp_fd
->uf_flags
& UFF_OPTSET
))
1193 reply_thr_get (udp_fd
, EBADMODE
, FALSE
);
1197 assert (!(udp_fd
->uf_flags
& UFF_WRITE_IP
));
1199 udp_fd
->uf_wr_count
= count
;
1201 udp_fd
->uf_flags
|= UFF_WRITE_IP
;
1203 restart_write_fd(udp_fd
);
1205 if (udp_fd
->uf_flags
& UFF_WRITE_IP
)
1207 DBLOCK(1, printf("replying NW_SUSPEND\n"));
1217 static void restart_write_fd(udp_fd
)
1220 udp_port_t
*udp_port
;
1221 acc_t
*pack
, *ip_hdr_pack
, *udp_hdr_pack
, *ip_opt_pack
, *user_data
;
1223 udp_io_hdr_t
*udp_io_hdr
;
1225 size_t ip_opt_size
, user_data_size
;
1226 unsigned long flags
;
1231 udp_port
= udp_fd
->uf_port
;
1233 if (udp_port
->up_flags
& UPF_WRITE_IP
)
1235 udp_port
->up_flags
|= UPF_MORE2WRITE
;
1239 assert (udp_fd
->uf_flags
& UFF_WRITE_IP
);
1240 udp_fd
->uf_flags
&= ~UFF_WRITE_IP
;
1242 assert (!udp_port
->up_wr_pack
);
1244 pack
= (*udp_fd
->uf_get_userdata
)(udp_fd
->uf_srfd
, 0,
1245 udp_fd
->uf_wr_count
, FALSE
);
1248 udp_fd
->uf_flags
&= ~UFF_WRITE_IP
;
1249 reply_thr_get (udp_fd
, EFAULT
, FALSE
);
1253 flags
= udp_fd
->uf_udpopt
.nwuo_flags
;
1255 ip_hdr_pack
= bf_memreq(IP_MIN_HDR_SIZE
);
1256 ip_hdr
= (ip_hdr_t
*)ptr2acc_data(ip_hdr_pack
);
1258 udp_hdr_pack
= bf_memreq(UDP_HDR_SIZE
);
1259 udp_hdr
= (udp_hdr_t
*)ptr2acc_data(udp_hdr_pack
);
1261 if (flags
& NWUO_RWDATALL
)
1263 pack
= bf_packIffLess(pack
, UDP_IO_HDR_SIZE
);
1264 udp_io_hdr
= (udp_io_hdr_t
*)ptr2acc_data(pack
);
1265 #if CONF_UDP_IO_NW_BYTE_ORDER
1266 ip_opt_size
= ntohs(udp_io_hdr
->uih_ip_opt_len
);
1268 ip_opt_size
= udp_io_hdr
->uih_ip_opt_len
;
1270 if (UDP_IO_HDR_SIZE
+ip_opt_size
>udp_fd
->uf_wr_count
)
1272 bf_afree(ip_hdr_pack
);
1273 bf_afree(udp_hdr_pack
);
1275 reply_thr_get (udp_fd
, EINVAL
, FALSE
);
1278 if (ip_opt_size
& 3)
1280 bf_afree(ip_hdr_pack
);
1281 bf_afree(udp_hdr_pack
);
1283 reply_thr_get (udp_fd
, EFAULT
, FALSE
);
1287 ip_opt_pack
= bf_cut(pack
, UDP_IO_HDR_SIZE
, ip_opt_size
);
1290 user_data_size
= udp_fd
->uf_wr_count
-UDP_IO_HDR_SIZE
-
1292 user_data
= bf_cut(pack
, UDP_IO_HDR_SIZE
+ip_opt_size
,
1300 user_data_size
= udp_fd
->uf_wr_count
;
1305 ip_hdr
->ih_vers_ihl
= (IP_MIN_HDR_SIZE
+ip_opt_size
) >> 2;
1306 ip_hdr
->ih_tos
= UDP_TOS
;
1307 ip_hdr
->ih_flags_fragoff
= HTONS(UDP_IP_FLAGS
);
1308 ip_hdr
->ih_ttl
= IP_DEF_TTL
;
1309 ip_hdr
->ih_proto
= IPPROTO_UDP
;
1310 if (flags
& NWUO_RA_SET
)
1312 ip_hdr
->ih_dst
= udp_fd
->uf_udpopt
.nwuo_remaddr
;
1316 assert (udp_io_hdr
);
1317 ip_hdr
->ih_dst
= udp_io_hdr
->uih_dst_addr
;
1320 if ((flags
& NWUO_LOCPORT_MASK
) != NWUO_LP_ANY
)
1321 udp_hdr
->uh_src_port
= udp_fd
->uf_udpopt
.nwuo_locport
;
1324 assert (udp_io_hdr
);
1325 udp_hdr
->uh_src_port
= udp_io_hdr
->uih_src_port
;
1328 if (flags
& NWUO_RP_SET
)
1329 udp_hdr
->uh_dst_port
= udp_fd
->uf_udpopt
.nwuo_remport
;
1332 assert (udp_io_hdr
);
1333 udp_hdr
->uh_dst_port
= udp_io_hdr
->uih_dst_port
;
1336 udp_hdr
->uh_length
= htons(UDP_HDR_SIZE
+user_data_size
);
1337 udp_hdr
->uh_chksum
= 0;
1339 udp_hdr_pack
->acc_next
= user_data
;
1340 chksum
= pack_oneCsum(udp_hdr_pack
);
1341 chksum
= oneC_sum(chksum
, (u16_t
*)&udp_fd
->uf_port
->up_ipaddr
,
1343 chksum
= oneC_sum(chksum
, (u16_t
*)&ip_hdr
->ih_dst
, sizeof(ipaddr_t
));
1345 u16
[1]= IPPROTO_UDP
;
1346 chksum
= oneC_sum(chksum
, (u16_t
*)u16
, sizeof(u16
));
1347 chksum
= oneC_sum(chksum
, (u16_t
*)&udp_hdr
->uh_length
, sizeof(u16_t
));
1350 udp_hdr
->uh_chksum
= chksum
;
1354 ip_opt_pack
= bf_packIffLess(ip_opt_pack
, ip_opt_size
);
1355 ip_opt_pack
->acc_next
= udp_hdr_pack
;
1356 udp_hdr_pack
= ip_opt_pack
;
1358 ip_hdr_pack
->acc_next
= udp_hdr_pack
;
1360 assert (!udp_port
->up_wr_pack
);
1361 assert (!(udp_port
->up_flags
& UPF_WRITE_IP
));
1363 udp_port
->up_wr_pack
= ip_hdr_pack
;
1364 udp_port
->up_flags
|= UPF_WRITE_IP
;
1365 result
= ip_write(udp_port
->up_ipfd
, bf_bufsize(ip_hdr_pack
));
1366 if (result
== NW_SUSPEND
)
1368 udp_port
->up_flags
|= UPF_WRITE_SP
;
1369 udp_fd
->uf_flags
|= UFF_WRITE_IP
;
1370 udp_port
->up_write_fd
= udp_fd
;
1373 reply_thr_get(udp_fd
, result
, FALSE
);
1375 reply_thr_get (udp_fd
, udp_fd
->uf_wr_count
, FALSE
);
1378 static u16_t
pack_oneCsum(pack
)
1392 for (; pack
; pack
= pack
->acc_next
)
1395 data_ptr
= ptr2acc_data(pack
);
1396 length
= pack
->acc_length
;
1402 byte_buf
[1]= *data_ptr
;
1403 prev
= oneC_sum(prev
, (u16_t
*)byte_buf
, 2);
1412 byte_buf
[0]= data_ptr
[length
];
1416 prev
= oneC_sum (prev
, (u16_t
*)data_ptr
, length
);
1421 prev
= oneC_sum (prev
, (u16_t
*)byte_buf
, 1);
1426 static void udp_restart_write_port(udp_port
)
1427 udp_port_t
*udp_port
;
1432 assert (!udp_port
->up_wr_pack
);
1433 assert (!(udp_port
->up_flags
& (UPF_WRITE_IP
|UPF_WRITE_SP
)));
1435 while (udp_port
->up_flags
& UPF_MORE2WRITE
)
1437 udp_port
->up_flags
&= ~UPF_MORE2WRITE
;
1439 for (i
= 0, udp_fd
= udp_port
->up_next_fd
; i
<UDP_FD_NR
;
1442 if (udp_fd
== &udp_fd_table
[UDP_FD_NR
])
1443 udp_fd
= udp_fd_table
;
1445 if (!(udp_fd
->uf_flags
& UFF_INUSE
))
1447 if (!(udp_fd
->uf_flags
& UFF_WRITE_IP
))
1449 if (udp_fd
->uf_port
!= udp_port
)
1451 restart_write_fd(udp_fd
);
1452 if (udp_port
->up_flags
& UPF_WRITE_IP
)
1454 udp_port
->up_next_fd
= udp_fd
+1;
1455 udp_port
->up_flags
|= UPF_MORE2WRITE
;
1462 int udp_cancel(fd
, which_operation
)
1464 int which_operation
;
1468 DBLOCK(0x10, printf("udp_cancel(%d, %d)\n", fd
, which_operation
));
1470 udp_fd
= &udp_fd_table
[fd
];
1472 switch (which_operation
)
1474 case SR_CANCEL_READ
:
1475 assert (udp_fd
->uf_flags
& UFF_READ_IP
);
1476 udp_fd
->uf_flags
&= ~UFF_READ_IP
;
1477 reply_thr_put(udp_fd
, EINTR
, FALSE
);
1479 case SR_CANCEL_WRITE
:
1480 assert (udp_fd
->uf_flags
& UFF_WRITE_IP
);
1481 udp_fd
->uf_flags
&= ~UFF_WRITE_IP
;
1482 if (udp_fd
->uf_port
->up_write_fd
== udp_fd
)
1483 udp_fd
->uf_port
->up_write_fd
= NULL
;
1484 reply_thr_get(udp_fd
, EINTR
, FALSE
);
1486 case SR_CANCEL_IOCTL
:
1487 assert (udp_fd
->uf_flags
& UFF_IOCTL_IP
);
1488 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
1489 udp_fd
->uf_flags
&= ~UFF_PEEK_IP
;
1490 reply_thr_get(udp_fd
, EINTR
, TRUE
);
1493 ip_panic(( "got unknown cancel request" ));
1498 static void udp_buffree (priority
)
1505 if (priority
== UDP_PRI_FDBUFS_EXTRA
)
1507 for (i
=0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++, udp_fd
++)
1509 while (udp_fd
->uf_rdbuf_head
&&
1510 udp_fd
->uf_rdbuf_head
->acc_ext_link
)
1512 tmp_acc
= udp_fd
->uf_rdbuf_head
;
1513 udp_fd
->uf_rdbuf_head
= tmp_acc
->acc_ext_link
;
1519 if (priority
== UDP_PRI_FDBUFS
)
1521 for (i
=0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++, udp_fd
++)
1523 while (udp_fd
->uf_rdbuf_head
)
1525 tmp_acc
= udp_fd
->uf_rdbuf_head
;
1526 udp_fd
->uf_rdbuf_head
= tmp_acc
->acc_ext_link
;
1533 static void udp_rd_enqueue(udp_fd
, pack
, exp_tim
)
1541 if (pack
->acc_linkC
!= 1)
1543 tmp_acc
= bf_dupacc(pack
);
1547 pack
->acc_ext_link
= NULL
;
1548 if (udp_fd
->uf_rdbuf_head
== NULL
)
1550 udp_fd
->uf_exp_tim
= exp_tim
;
1551 udp_fd
->uf_rdbuf_head
= pack
;
1554 udp_fd
->uf_rdbuf_tail
->acc_ext_link
= pack
;
1555 udp_fd
->uf_rdbuf_tail
= pack
;
1557 if (udp_fd
->uf_flags
& UFF_PEEK_IP
)
1559 pack
= bf_cut(udp_fd
->uf_rdbuf_head
, 0,
1560 sizeof(udp_io_hdr_t
));
1561 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
1562 (size_t)0, pack
, TRUE
);
1564 udp_fd
->uf_flags
&= ~UFF_IOCTL_IP
;
1565 udp_fd
->uf_flags
&= ~UFF_PEEK_IP
;
1566 result
= (*udp_fd
->uf_put_userdata
)(udp_fd
->uf_srfd
,
1567 result
, (acc_t
*)0, TRUE
);
1568 assert (result
== 0);
1571 if (udp_fd
->uf_flags
& UFF_SEL_READ
)
1573 udp_fd
->uf_flags
&= ~UFF_SEL_READ
;
1574 if (udp_fd
->uf_select_res
)
1575 udp_fd
->uf_select_res(udp_fd
->uf_srfd
, SR_SELECT_READ
);
1577 printf("udp_rd_enqueue: no select_res\n");
1581 static void hash_fd(udp_fd
)
1584 udp_port_t
*udp_port
;
1587 udp_port
= udp_fd
->uf_port
;
1588 if ((udp_fd
->uf_udpopt
.nwuo_flags
& NWUO_LOCPORT_MASK
) ==
1591 udp_fd
->uf_port_next
= udp_port
->up_port_any
;
1592 udp_port
->up_port_any
= udp_fd
;
1596 hash
= udp_fd
->uf_udpopt
.nwuo_locport
;
1597 hash
^= (hash
>> 8);
1598 hash
&= (UDP_PORT_HASH_NR
-1);
1600 udp_fd
->uf_port_next
= udp_port
->up_port_hash
[hash
];
1601 udp_port
->up_port_hash
[hash
]= udp_fd
;
1605 static void unhash_fd(udp_fd
)
1608 udp_port_t
*udp_port
;
1609 udp_fd_t
*prev
, *curr
, **udp_fd_p
;
1612 udp_port
= udp_fd
->uf_port
;
1613 if ((udp_fd
->uf_udpopt
.nwuo_flags
& NWUO_LOCPORT_MASK
) ==
1616 udp_fd_p
= &udp_port
->up_port_any
;
1620 hash
= udp_fd
->uf_udpopt
.nwuo_locport
;
1621 hash
^= (hash
>> 8);
1622 hash
&= (UDP_PORT_HASH_NR
-1);
1624 udp_fd_p
= &udp_port
->up_port_hash
[hash
];
1626 for (prev
= NULL
, curr
= *udp_fd_p
; curr
;
1627 prev
= curr
, curr
= curr
->uf_port_next
)
1634 prev
->uf_port_next
= curr
->uf_port_next
;
1636 *udp_fd_p
= curr
->uf_port_next
;
1639 #ifdef BUF_CONSISTENCY_CHECK
1640 static void udp_bufcheck()
1643 udp_port_t
*udp_port
;
1647 for (i
= 0, udp_port
= udp_port_table
; i
<udp_conf_nr
; i
++, udp_port
++)
1649 if (udp_port
->up_wr_pack
)
1650 bf_check_acc(udp_port
->up_wr_pack
);
1653 for (i
= 0, udp_fd
= udp_fd_table
; i
<UDP_FD_NR
; i
++, udp_fd
++)
1655 for (tmp_acc
= udp_fd
->uf_rdbuf_head
; tmp_acc
;
1656 tmp_acc
= tmp_acc
->acc_ext_link
)
1658 bf_check_acc(tmp_acc
);
1665 * $PchId: udp.c,v 1.25 2005/06/28 14:14:44 philip Exp $