summaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2013-06-25 08:31:11 +0000
committerRoy Marples <roy@marples.name>2013-06-25 08:31:11 +0000
commitecf297d6c7930bc56ea7433063473de3ce7b2996 (patch)
treee7bdeb3952b4f61bf8836132544d7d489cc51814 /if-bsd.c
parentc72645007c9a8a28c94587ef3687540cf9f34233 (diff)
downloaddhcpcd-ecf297d6c7930bc56ea7433063473de3ce7b2996.tar.xz
Detect link address changes on Linux.
Only NetBSD emits RTM_CHGADDR for link address changes. Sadly no other BSD emits anything for link address changes so we have to do a full discovery on carrier up. When a link address does change, simply carry on as we are, no need to drop any existing lease as the carrier change will do that for us.
Diffstat (limited to 'if-bsd.c')
-rw-r--r--if-bsd.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/if-bsd.c b/if-bsd.c
index 96f483d9..4cf87187 100644
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -79,6 +79,10 @@
sin.s6_addr = ((sa) != NULL) ? \
(((struct sockaddr_in6 *)(void *)sa)->sin6_addr).s6_addr : 0
+#ifndef CLLADDR
+# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
+#endif
+
static int r_fd = -1;
static char *link_buf;
static ssize_t link_buflen;
@@ -531,10 +535,7 @@ manage_link(int fd)
struct ifa_msghdr *ifam;
struct sockaddr *sa, *rti_info[RTAX_MAX];
int len;
-#ifdef RTM_CHGADDR
struct sockaddr_dl sdl;
- unsigned char *hwaddr;
-#endif
#ifdef INET
struct rt rt;
#endif
@@ -637,23 +638,20 @@ manage_link(int fd)
if (rti_info[RTAX_IFA] == NULL)
break;
switch (rti_info[RTAX_IFA]->sa_family) {
-#ifdef RTM_CHGADDR
case AF_LINK:
+#ifdef RTM_CHGADDR
if (rtm->rtm_type != RTM_CHGADDR)
break;
+#else
+ if (rtm->rtm_type != RTM_NEWADDR)
+ break;
+#endif
memcpy(&sdl, rti_info[RTAX_IFA],
rti_info[RTAX_IFA]->sa_len);
- hwaddr = malloc(sdl.sdl_alen);
- if (hwaddr) {
- memcpy(hwaddr, LLADDR(&sdl),
- sdl.sdl_alen);
- handle_hwaddr(ifname, hwaddr,
- sdl.sdl_alen);
- } else
- syslog(LOG_ERR, "%s: %m",
- __func__);
+ handle_hwaddr(ifname,
+ (const unsigned char*)CLLADDR(&sdl),
+ sdl.sdl_alen);
break;
-#endif
#ifdef INET
case AF_INET:
case 255: /* FIXME: Why 255? */