]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add DHCP over FireWire 1394 (RFC 2855) and InfiniBand (RFC 4390) support.
authorRoy Marples <roy@marples.name>
Mon, 12 Feb 2007 16:12:50 +0000 (16:12 +0000)
committerRoy Marples <roy@marples.name>
Mon, 12 Feb 2007 16:12:50 +0000 (16:12 +0000)
ChangeLog
Makefile
arp.c
configure.c
dhcp.c
dhcp.h
dhcpcd.c
interface.c
interface.h
socket.c

index 34929b7ab51f015898fbcca86909b92cf24df672..229758edd854a5c0d781b312a5f0cd2e619a201b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+Add DHCP over FireWire 1394 (RFC 2855) and InfiniBand (RFC 4390) support.
+We should add support for DUIDs (RFC4361) as well.
+
 dhcpcd-3.0.11
 Don't try to send messages when we infinite leasetime and the interface
 fd is closed.
index e5d5318b3c72a9523007966dd4b310e37df0499a..551c000a225c022e45d86326f377d854ce5254e2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # Should work for both GNU make and BSD make
 
-VERSION = 3.0.11
+VERSION = 3.0.12_pre1
 
 CFLAGS ?= -O2 -pipe
 
@@ -59,7 +59,7 @@ install: $(TARGET)
        $(INSTALL) -m 0755 $(MAN8_TARGETS) $(MANDIR)/man8
 
 clean:
-       rm -f $(TARGET) $(dhcpcd_H) *.o *~ *.core
+       rm -f $(TARGET) $(dhcpcd_H) *.o *~ *.core *.bz2
 
 dist:
        $(INSTALL) -m 0755 -d /tmp/dhcpcd-$(VERSION)
diff --git a/arp.c b/arp.c
index 4d210bc8465089b76e9557b1ef62dfed87f8dc53..aae3aaeb13a956a1b6fcd5cc77cd33e3506a708c 100644 (file)
--- a/arp.c
+++ b/arp.c
@@ -78,12 +78,12 @@ int arp_check (interface_t *iface, struct in_addr address)
 
   memset (arp.buffer, 0, sizeof (arp.buffer));
 
-  arp.ah.ar_hrd = htons (ARPHRD_ETHER);
+  arp.ah.ar_hrd = htons (iface->family);
   arp.ah.ar_pro = htons (ETHERTYPE_IP);
-  arp.ah.ar_hln = ETHER_ADDR_LEN;
+  arp.ah.ar_hln = iface->hwlen;
   arp.ah.ar_pln = sizeof (struct in_addr);
   arp.ah.ar_op = htons (ARPOP_REQUEST);
-  memcpy (ar_sha (&arp.ah), &iface->ethernet_address, arp.ah.ar_hln);
+  memcpy (ar_sha (&arp.ah), &iface->hwaddr, arp.ah.ar_hln);
   memcpy (ar_tpa (&arp.ah), &address, arp.ah.ar_pln);
 
   logger (LOG_INFO, "checking %s is available on attached networks", inet_ntoa
@@ -139,8 +139,7 @@ int arp_check (interface_t *iface, struct in_addr address)
            break;
 
          /* Only these types are recognised */
-         if (reply.hdr.ar_op != htons(ARPOP_REPLY)
-             || reply.hdr.ar_hrd != htons (ARPHRD_ETHER))
+         if (reply.hdr.ar_op != htons(ARPOP_REPLY))
            continue;
 
          /* Protocol must be IP. */
index 8b06b8dee087f60def7a63c2694e85879c37d58e..184a9be92545be1aa586c1735e593c64e673c2d0 100644 (file)
@@ -411,8 +411,8 @@ static int write_info(const interface_t *iface, const dhcp_t *dhcp,
   if (options->clientid[0])
     fprintf (f, "CLIENTID='%s'\n", cleanmetas (options->clientid));
   else
-    fprintf (f, "CLIENTID='%s'\n", ether_ntoa (&iface->ethernet_address));
-  fprintf (f, "DHCPCHADDR='%s'\n", ether_ntoa (&iface->ethernet_address));
+    fprintf (f, "CLIENTID='%s'\n", hwaddr_ntoa (iface->hwaddr, iface->hwlen));
+  fprintf (f, "DHCPCHADDR='%s'\n", hwaddr_ntoa (iface->hwaddr, iface->hwlen));
   fclose (f);
   return 0;
 }
diff --git a/dhcp.c b/dhcp.c
index 3fa18bedd52ad497694e6378af76d5df24ac4cf3..3b81b48639d43e16f94d835e824ba77370d488a0 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -72,13 +72,6 @@ size_t send_message (const interface_t *iface, const dhcp_t *dhcp,
   if (!iface || !options || !dhcp)
     return -1;
 
-  if (type == DHCP_RELEASE || type == DHCP_INFORM ||
-      (type == DHCP_REQUEST &&
-       iface->previous_address.s_addr == dhcp->address.s_addr))
-    from.s_addr = dhcp->address.s_addr;
-  else
-    from.s_addr = 0;
-
   if (type == DHCP_RELEASE)
     to.s_addr = dhcp->serveraddress.s_addr;
   else
@@ -86,23 +79,41 @@ size_t send_message (const interface_t *iface, const dhcp_t *dhcp,
 
   memset (&message, 0, sizeof (dhcpmessage_t));
 
+  if (iface->previous_address.s_addr != 0
+      && (type == DHCP_INFORM || type == DHCP_RELEASE
+         || (type == DHCP_REQUEST
+             && iface->previous_address.s_addr == dhcp->address.s_addr)))
+    {
+      message.ciaddr = iface->previous_address.s_addr;
+      from.s_addr = iface->previous_address.s_addr;
+    }
+
   message.op = DHCP_BOOTREQUEST;
-  message.hwtype = ARPHRD_ETHER;
-  message.hwlen = ETHER_ADDR_LEN;
+  message.hwtype = iface->family;
+  switch (iface->family)
+    {
+    case ARPHRD_ETHER:
+    case ARPHRD_IEEE802:
+      message.hwlen = ETHER_ADDR_LEN;
+      memcpy (&message.chaddr, &iface->hwaddr, ETHER_ADDR_LEN);
+      break;
+    case ARPHRD_IEEE1394:
+    case ARPHRD_INFINIBAND:
+      if (message.ciaddr == 0)
+       message.flags = htons (BROADCAST_FLAG);
+      message.hwlen = 0;
+      break;
+    default:
+      logger (LOG_ERR, "dhcp: unknown hardware type %d", iface->family);
+    }
+
   if (up < 0 || up > UINT16_MAX)
     message.secs = htons ((short) UINT16_MAX);
   else
     message.secs = htons (up);
   message.xid = xid;
-  memcpy (&message.hwaddr, &iface->ethernet_address, ETHER_ADDR_LEN);
   message.cookie = htonl (MAGIC_COOKIE);
 
-  if (iface->previous_address.s_addr != 0
-      && (type == DHCP_INFORM || type == DHCP_RELEASE
-         || (type == DHCP_REQUEST
-             && iface->previous_address.s_addr == dhcp->address.s_addr)))
-    message.ciaddr = iface->previous_address.s_addr;
-
   *p++ = DHCP_MESSAGETYPE; 
   *p++ = 1;
   *p++ = type;
@@ -239,10 +250,10 @@ size_t send_message (const interface_t *iface, const dhcp_t *dhcp,
     }
   else
     {
-      *p++ = ETHER_ADDR_LEN + 1;
-      *p++ = ARPHRD_ETHER;
-      memcpy (p, &iface->ethernet_address, ETHER_ADDR_LEN);
-      p += ETHER_ADDR_LEN;
+      *p++ = iface->hwlen + 1;
+      *p++ = iface->family;
+      memcpy (p, &iface->hwaddr, iface->hwlen);
+      p += iface->hwlen;
     }
 
   *p++ = DHCP_END;
diff --git a/dhcp.h b/dhcp.h
index b6fbfefcea56cb5990e84422591d6ae2f5a86125..29a90b793055cbc2fb355ea1f56ed25d2dcfe17e 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -152,13 +152,13 @@ typedef struct dhcp_t
 } dhcp_t;
 
 /* Sizes for DHCP options */
-#define HWADDR_LEN             16
+#define DHCP_CHADDR_LEN                16
 #define SERVERNAME_LEN         64
 #define BOOTFILE_LEN           128
 #define DHCP_UDP_LEN           (20 + 8)
 #define DHCP_BASE_LEN          (4 + 4 + 2 + 2 + 4 + 4 + 4 + 4 + 4)
 #define DHCP_RESERVE_LEN       (4 + 4 + 4 + 4 + 2)
-#define DHCP_FIXED_LEN         (DHCP_BASE_LEN + HWADDR_LEN + \
+#define DHCP_FIXED_LEN         (DHCP_BASE_LEN + DHCP_CHADDR_LEN + \
                                + SERVERNAME_LEN + BOOTFILE_LEN)
 #define DHCP_OPTION_LEN                (MTU_MAX - DHCP_FIXED_LEN - DHCP_UDP_LEN \
                                 - DHCP_RESERVE_LEN)
@@ -177,7 +177,7 @@ typedef struct dhcpmessage_t
   int32_t yiaddr;                      /* 'your' client IP address */
   int32_t siaddr;                      /* should be zero in client's messages */
   int32_t giaddr;                      /* should be zero in client's messages */
-  unsigned char hwaddr[HWADDR_LEN];    /* client's hardware address */
+  unsigned char chaddr[DHCP_CHADDR_LEN];       /* client's hardware address */
   char servername[SERVERNAME_LEN];     /* server host name, null terminated string */
   char bootfile[BOOTFILE_LEN];         /* boot file name, null terminated string */
   uint32_t cookie;
index feb03dbbda61f94becd92f6f4539a38ee71b1d36..2dcb5537646b3c91a9465101c2b4449349a5ed50 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -387,7 +387,10 @@ int main(int argc, char **argv)
 
   logger (LOG_INFO, PACKAGE " " VERSION " starting");
   if (dhcp_run (&options))
-    exit (EXIT_FAILURE);
+    {
+      unlink (options.pidfile);
+      exit (EXIT_FAILURE);
+    }
 
   exit (EXIT_SUCCESS);
 }
index 8ee0ad5ddfb2a44f3857c2bc7dea5524269d3392..3da3eaf9a273666d5e9f9feff2002c909052eb50 100644 (file)
@@ -91,13 +91,31 @@ void free_route (route_t *routes)
     }
 }
 
+
+char *hwaddr_ntoa (const unsigned char *hwaddr, int hwlen)
+{
+  static char buffer[128];
+  char *p = buffer;
+  int i;
+
+  for (i = 0; i < hwlen && i < 125; i++)
+    {
+      if (i > 0)
+       p += sprintf (p, ":");
+      p += sprintf (p, "%.2x", hwaddr[i]);
+    }
+
+  return (buffer);
+}
+
 interface_t *read_interface (const char *ifname, int metric)
 {
 
   int s;
   struct ifreq ifr;
   interface_t *iface;
-  unsigned char hwaddr[ETHER_ADDR_LEN];
+  unsigned char hwaddr[16];
+  int hwlen = 0;
   sa_family_t family;
 
 #ifndef __linux__
@@ -108,6 +126,8 @@ interface_t *read_interface (const char *ifname, int metric)
   if (! ifname)
     return NULL;
 
+  memset (hwaddr, sizeof (hwaddr), 0);
+
 #ifndef __linux__
   if (getifaddrs (&ifap) != 0)
     return NULL;
@@ -137,7 +157,8 @@ interface_t *read_interface (const char *ifname, int metric)
        }
 
       memcpy (hwaddr, us.sdl->sdl_data + us.sdl->sdl_nlen, ETHER_ADDR_LEN);
-      family = us.sdl->sdl_type;
+      family = ARPHRD_ETHER;
+      hwlen = ETHER_ADDR_LEN;
       break;
     }
   freeifaddrs (ifap);
@@ -166,14 +187,23 @@ interface_t *read_interface (const char *ifname, int metric)
       close (s);
       return NULL;
     }
-  if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER &&
-      ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE802_TR)
+  switch (ifr.ifr_hwaddr.sa_family)
     {
-      logger (LOG_ERR, "interface is not Ethernet or Token Ring");
+    case ARPHRD_ETHER:
+    case ARPHRD_IEEE802:
+      hwlen = ETHER_ADDR_LEN;
+      break;
+    case ARPHRD_IEEE1394:
+      hwlen = EUI64_ADDR_LEN;
+    case ARPHRD_INFINIBAND:
+      hwlen = INFINIBAND_ADDR_LEN;
+      break;
+    default:
+      logger (LOG_ERR, "interface is not Ethernet, FireWire, InfiniBand or Token Ring");
       close (s);
       return NULL;
     }
-  memcpy (hwaddr, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
+  memcpy (hwaddr, ifr.ifr_hwaddr.sa_data, hwlen);
   family = ifr.ifr_hwaddr.sa_family;
 #else
   ifr.ifr_metric = metric;
@@ -206,13 +236,14 @@ interface_t *read_interface (const char *ifname, int metric)
   memset (iface, 0, sizeof (interface_t));
   strncpy (iface->name, ifname, IF_NAMESIZE);
   snprintf (iface->infofile, PATH_MAX, INFOFILE, ifname);
-  memcpy (&iface->ethernet_address, hwaddr, ETHER_ADDR_LEN);
+  memcpy (&iface->hwaddr, hwaddr, hwlen);
+  iface->hwlen = hwlen;
 
   iface->family = family;
   iface->arpable = ! (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK));
 
-  logger (LOG_INFO, "ethernet address = %s",
-         ether_ntoa (&iface->ethernet_address));
+  logger (LOG_INFO, "hardware address = %s",
+         hwaddr_ntoa (iface->hwaddr, iface->hwlen));
 
   /* 0 is a valid fd, so init to -1 */
   iface->fd = -1;
index 131b42ef24bed0e2a8770187d4b3ada584e72034..d174dc8deb55f91b47f5bb092fabcc86961d7a59 100644 (file)
 #include <limits.h>
 #include <stdbool.h>
 
+#define EUI64_ADDR_LEN                 8
+#define INFINIBAND_ADDR_LEN            20
+
+/* The BSD's don't define this yet */
+#ifndef ARPHRD_INFINIBAND
+#  define ARPHRD_INFINIBAND            27
+#endif
+
 typedef struct route_t
 {
   struct in_addr destination; 
@@ -48,8 +56,9 @@ typedef struct address_t
 typedef struct interface_t
 {
   char name[IF_NAMESIZE];
-  struct ether_addr ethernet_address;
   sa_family_t family;
+  unsigned char hwaddr[20];
+  int hwlen;
   bool arpable;
 
   int fd;
@@ -82,4 +91,7 @@ int change_route (const char *ifname, struct in_addr destination,
                  struct in_addr netmask, struct in_addr gateway, int metric);
 int del_route (const char *ifname, struct in_addr destination,
               struct in_addr netmask, struct in_addr gateway, int metric);
+
+char *hwaddr_ntoa (const unsigned char *hwaddr, int hwlen);
+
 #endif
index 69c12ef2720deb85cbc947b91badd93b45ffe3e1..f3f412b83d2aff85c6a2a53c34f915fb4235a92e 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -317,7 +317,7 @@ int send_packet (const interface_t *iface, int type,
   int retval = -1;
   struct iovec iov[2];
 
-  if (iface->family == IFT_ETHER)
+  if (iface->family == ARPHRD_ETHER)
     {
       struct ether_header hw;
       memset (&hw, 0, sizeof (struct ether_header));