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