Using DLPI with HP-UX 11
Johannes Berg
johannes at sipsolutions.net
Mon Aug 30 13:08:36 UTC 2004
Johannes Berg said:
> Doing this surfaced a bug in dhcpd -- you can't define USE_SOCKET_RECEIVE
> without USE_SOCKET_SEND because then the fallback interface will screw you
> up. The solution is to add a global variable in common/socket.c to store
> the rfdesc and use that in the fallback logic instead of interface ->
> rfdesc (which points to fallback_interface where rfdesc is still -1)
Let me follow up on this:
socket.c contains the following code in if_register_send:
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK)
void if_register_send (info)
struct interface_info *info;
{
#ifndef USE_SOCKET_RECEIVE
info -> wfdesc = if_register_socket (info);
#if defined (USE_SOCKET_FALLBACK)
/* Fallback only registers for send, but may need to receive as
well. */
info -> rfdesc = info -> wfdesc;
#endif
#else
info -> wfdesc = info -> rfdesc;
#endif
which after processing looks like (defining USE_SOCKET_FALLBACK and
USE_SOCKET_RECEIVE:
void if_register_send (info)
struct interface_info *info;
{
info -> wfdesc = info -> rfdesc;
That is wrong.
Let us examine the situation in which that code is called, if
USE_SOCKET_FALLBACK is defined, and USE_SOCKET_RECEIVE is defined, but not
USE_SOCKET_SEND (in the case of USE_SOCKETS (receive+send) fallback
doesn't make sense)
In this case, the info structure points to the fallback interface. This
means, that rfdesc is still -1. That way, wfdesc will also be -1 a while
later. Accordingly, all calls to send_packet that need to fall back to
sockets will fail.
My solution was to add a global variable read_file_descriptor that is set
when initially opening a socket in if_register_receive:
- info -> rfdesc = if_register_socket (info);
+ read_file_descriptor = info -> rfdesc = if_register_socket (info);
And then use that descriptor later in if_register_send:
- info -> wfdesc = info -> rfdesc;
+ info -> wfdesc = read_file_descriptor;
I am not sure if this covers all corner cases, and maybe there's a better
solution -- if so I'd like to hear it.
I think you can reproduce this behaviour by just defining
USE_SOCKET_RECEIVE for the linux version of dhcpd (instead of receiving
via LPF; but I am not sure if the linux specific code supports this).
johannes
PS:
For reference, here's the complete patch I am using; the static
declaration of the file descriptor should probably be #ifdef'ed.
--- dhcp-3.0pl2/common/socket.c 2000-09-30 03:24:55.000000000 +0200
+++ dhcp-3.0pl2-new/common/socket.c 2004-08-27 11:06:32.000000000 +0200
@@ -162,6 +162,8 @@
}
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE || USE_SOCKET_FALLBACK */
+static int read_file_descriptor;
+
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK)
void if_register_send (info)
struct interface_info *info;
@@ -174,10 +176,11 @@
info -> rfdesc = info -> wfdesc;
#endif
#else
- info -> wfdesc = info -> rfdesc;
+ info -> wfdesc = read_file_descriptor;
#endif
if (!quiet_interface_discovery)
- log_info ("Sending on Socket/%s%s%s",
+ log_info ("Sending on Socket %d/%s%s%s",
+ info -> wfdesc,
info -> name,
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
@@ -209,7 +212,7 @@
{
/* If we're using the socket API for sending and receiving,
we don't need to register this interface twice. */
- info -> rfdesc = if_register_socket (info);
+ read_file_descriptor = info -> rfdesc = if_register_socket (info);
if (!quiet_interface_discovery)
log_info ("Listening on Socket/%s%s%s",
info -> name,
More information about the dhcp-hackers
mailing list