From: Roy Marples Date: Mon, 12 Feb 2007 16:12:50 +0000 (+0000) Subject: Add DHCP over FireWire 1394 (RFC 2855) and InfiniBand (RFC 4390) support. X-Git-Tag: v3.2.3~316 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=092592331f8838823edeab9fb364b553cea608c2;p=thirdparty%2Fdhcpcd.git Add DHCP over FireWire 1394 (RFC 2855) and InfiniBand (RFC 4390) support. --- diff --git a/ChangeLog b/ChangeLog index 34929b7a..229758ed 100644 --- 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. diff --git a/Makefile b/Makefile index e5d5318b..551c000a 100644 --- 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 4d210bc8..aae3aaeb 100644 --- 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. */ diff --git a/configure.c b/configure.c index 8b06b8de..184a9be9 100644 --- a/configure.c +++ b/configure.c @@ -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 3fa18bed..3b81b486 100644 --- 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 b6fbfefc..29a90b79 100644 --- 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; diff --git a/dhcpcd.c b/dhcpcd.c index feb03dbb..2dcb5537 100644 --- 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); } diff --git a/interface.c b/interface.c index 8ee0ad5d..3da3eaf9 100644 --- a/interface.c +++ b/interface.c @@ -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; diff --git a/interface.h b/interface.h index 131b42ef..d174dc8d 100644 --- a/interface.h +++ b/interface.h @@ -31,6 +31,14 @@ #include #include +#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 diff --git a/socket.c b/socket.c index 69c12ef2..f3f412b8 100644 --- 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));