From: Roy Marples Date: Thu, 1 Jan 2009 20:51:04 +0000 (+0000) Subject: You can now add a configure block per ssid if the interface is wireless. X-Git-Tag: v5.0.0~139 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c53cf4ef4b332cd1ff0cb1b0dc23fc193aebb892;p=thirdparty%2Fdhcpcd.git You can now add a configure block per ssid if the interface is wireless. --- diff --git a/dhcpcd.c b/dhcpcd.c index 033f1368..aa2a6020 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -73,6 +73,8 @@ char **ifav = NULL; int ifdc = 0; char **ifdv = NULL; +static char **margv; +static int margc; static char **ifv; static int ifc; static int linkfd = -1; @@ -642,10 +644,67 @@ send_release(struct interface *iface) } } +static void +configure_interface(struct interface *iface, int argc, char **argv) +{ + struct if_state *ifs = iface->state; + struct if_options *ifo; + uint8_t *duid; + size_t len = 0, ifl; + + free_options(ifs->options); + ifo = ifs->options = read_config(cffile, iface->name, iface->ssid); + add_options(ifo, argc, argv); + + if (ifo->metric != -1) + iface->metric = ifo->metric; + + /* If we haven't specified a ClientID and our hardware address + * length is greater than DHCP_CHADDR_LEN then we enforce a ClientID + * of the hardware address family and the hardware address. */ + if (iface->hwlen > DHCP_CHADDR_LEN) + ifo->options |= DHCPCD_CLIENTID; + + free(iface->clientid); + if (*ifo->clientid) { + iface->clientid = xmalloc(ifo->clientid[0] + 1); + memcpy(iface->clientid, ifo->clientid, ifo->clientid[0] + 1); + } else if (ifo->options & DHCPCD_CLIENTID) { + if (ifo->options & DHCPCD_DUID) { + duid = xmalloc(DUID_LEN); + if ((len = get_duid(duid, iface)) == 0) + syslog(LOG_ERR, "get_duid: %m"); + } + if (len > 0) { + iface->clientid = xmalloc(len + 6); + iface->clientid[0] = len + 5; + iface->clientid[1] = 255; /* RFC 4361 */ + ifl = strlen(iface->name); + if (ifl < 5) { + memcpy(iface->clientid + 2, iface->name, ifl); + if (ifl < 4) + memset(iface->clientid + 2 + ifl, + 0, 4 - ifl); + } else { + ifl = htonl(if_nametoindex(iface->name)); + memcpy(iface->clientid + 2, &ifl, 4); + } + } else if (len == 0) { + len = iface->hwlen + 1; + iface->clientid = xmalloc(len + 1); + iface->clientid[0] = len; + iface->clientid[1] = iface->family; + memcpy(iface->clientid + 2, iface->hwaddr, + iface->hwlen); + } + } +} + static void handle_carrier(const char *ifname) { struct interface *iface; + char ssid[IF_SSIDSIZE]; for (iface = ifaces; iface; iface = iface->next) if (strcmp(iface->name, ifname) == 0) @@ -669,6 +728,12 @@ handle_carrier(const char *ifname) if (iface->carrier != LINK_UP) { iface->carrier = LINK_UP; syslog(LOG_INFO, "%s: carrier acquired", iface->name); + /* We need to reconfigre for if ssid changed */ + getifssid(iface->name, ssid); + if (strcmp(iface->ssid, ssid) != 0) { + strlcpy(ssid, iface->ssid, sizeof(iface->ssid)); + configure_interface(iface, margc, margv); + } start_interface(iface); } break; @@ -889,62 +954,6 @@ start_interface(void *arg) start_reboot(iface); } -static void -configure_interface(struct interface *iface, int argc, char **argv) -{ - struct if_state *ifs = iface->state; - struct if_options *ifo; - uint8_t *duid; - size_t len = 0, ifl; - - free_options(ifs->options); - ifo = ifs->options = read_config(cffile, iface->name); - add_options(ifo, argc, argv); - - if (ifo->metric != -1) - iface->metric = ifo->metric; - - /* If we haven't specified a ClientID and our hardware address - * length is greater than DHCP_CHADDR_LEN then we enforce a ClientID - * of the hardware address family and the hardware address. */ - if (iface->hwlen > DHCP_CHADDR_LEN) - ifo->options |= DHCPCD_CLIENTID; - - free(iface->clientid); - if (*ifo->clientid) { - iface->clientid = xmalloc(ifo->clientid[0] + 1); - memcpy(iface->clientid, ifo->clientid, ifo->clientid[0] + 1); - } else if (ifo->options & DHCPCD_CLIENTID) { - if (ifo->options & DHCPCD_DUID) { - duid = xmalloc(DUID_LEN); - if ((len = get_duid(duid, iface)) == 0) - syslog(LOG_ERR, "get_duid: %m"); - } - if (len > 0) { - iface->clientid = xmalloc(len + 6); - iface->clientid[0] = len + 5; - iface->clientid[1] = 255; /* RFC 4361 */ - ifl = strlen(iface->name); - if (ifl < 5) { - memcpy(iface->clientid + 2, iface->name, ifl); - if (ifl < 4) - memset(iface->clientid + 2 + ifl, - 0, 4 - ifl); - } else { - ifl = htonl(if_nametoindex(iface->name)); - memcpy(iface->clientid + 2, &ifl, 4); - } - } else if (len == 0) { - len = iface->hwlen + 1; - iface->clientid = xmalloc(len + 1); - iface->clientid[0] = len; - iface->clientid[1] = iface->family; - memcpy(iface->clientid + 2, iface->hwaddr, - iface->hwlen); - } - } -} - static void init_state(struct interface *iface, int argc, char **argv) { @@ -1217,7 +1226,9 @@ main(int argc, char **argv) } } - ifo = read_config(cffile, NULL); + margv = argv; + margc = argc; + ifo = read_config(cffile, NULL, NULL); opt = add_options(ifo, argc, argv); if (opt != 1) { if (opt == 0) diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index f136a944..56090c48 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -175,6 +175,9 @@ Use .Ar script instead of the default .Pa @SCRIPT@ . +.It Ic ssid Ar ssid +Subsequent options are only parsed for this wireless +.Ar ssid . .It Ic static Ar value Configures a static .Ar value . diff --git a/dhcpcd.h b/dhcpcd.h index 07d69c24..0bcb280d 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -1,6 +1,6 @@ /* * dhcpcd - DHCP client daemon - * Copyright 2006-2008 Roy Marples + * Copyright 2006-2009 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ #include "if-options.h" #define HWADDR_LEN 20 +#define IF_SSIDSIZE 33 enum DHS { DHS_INIT, @@ -85,6 +86,7 @@ struct interface int metric; int carrier; int arpable; + char ssid[IF_SSIDSIZE]; int raw_fd; int udp_fd; diff --git a/if-bsd.c b/if-bsd.c index 9bf8a4ed..82bce188 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -1,6 +1,6 @@ /* * dhcpcd - DHCP client daemon - * Copyright 2006-2008 Roy Marples + * Copyright 2006-2009 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -64,7 +64,7 @@ #endif int -if_wireless(const char *ifname) +getifssid(const char *ifname, char *ssid) { int s, retval = -1; #if defined(SIOCG80211NWID) @@ -72,6 +72,7 @@ if_wireless(const char *ifname) struct ieee80211_nwid nwid; #elif defined(IEEE80211_IOC_SSID) struct ieee80211req ireq; + char nwid[IEEE80211_NWID_LEN + 1]; #endif if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) @@ -81,14 +82,22 @@ if_wireless(const char *ifname) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); memset(&nwid, 0, sizeof(nwid)); ifr.ifr_data = (void *)&nwid; - if (ioctl(s, SIOCG80211NWID, &ifr) == 0) - retval = 0; + if (ioctl(s, SIOCG80211NWID, &ifr) == 0) { + retval = nwid.i_len; + memcpy(nwid.i_nwid, ssid, nwid.i_len); + ssid[nwid.i_len] = '\0'; + } #elif defined(IEEE80211_IOC_SSID) /* FreeBSD */ memset(&ireq, 0, sizeof(ireq)); strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name)); - ireq.i_type = IEEE80211_IOC_NUMSSIDS; - if (ioctl(s, SIOCG80211, &ireq) == 0) - retval = 0; + ireq.i_type = IEEE80211_IOC_SSID; + ireq.i_val = -1; + ireq.i_data = &nwid; + if (ioctl(s, SIOCG80211, &ireq) == 0) { + retval = ireq.i_len; + memcpy(nwid, ssid, ireq.i_len); + ssid[ireq.i_len] = '\0'; + } #endif close(s); return retval; diff --git a/if-linux.c b/if-linux.c index c9cba9ef..937b4ad0 100644 --- a/if-linux.c +++ b/if-linux.c @@ -1,6 +1,6 @@ /* * dhcpcd - DHCP client daemon - * Copyright 2006-2008 Roy Marples + * Copyright 2006-2009 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -73,17 +74,22 @@ static void (*nl_add)(const char *); static void (*nl_remove)(const char *); int -if_wireless(const char *ifname) +getifssid(const char *ifname, char *ssid) { - int s, retval = -1; - struct ifreq ifr; + int s, retval; + struct iwreq iwr; if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) - return retval; - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIWNAME, &ifr) == 0) - retval = 0; + return -1; + memset(&iwr, 0, sizeof(iwr)); + strlcpy(iwr.ifr_name, ifname, sizeof(iwr.ifr_name)); + iwr.u.essid.pointer = ssid; + iwr.u.essid.length = IF_SSIDSIZE - 1; + + if (ioctl(s, SIOCGIWESSID, &iwr) == 0) + retval = iwr.u.essid.length; + else + retval = -1; close(s); return retval; } diff --git a/if-options.c b/if-options.c index abbb92cc..4e8ddbfe 100644 --- a/if-options.c +++ b/if-options.c @@ -662,7 +662,7 @@ parse_config_line(struct if_options *ifo, const char *opt, char *line) } struct if_options * -read_config(const char *file, const char *ifname) +read_config(const char *file, const char *ifname, const char *ssid) { struct if_options *ifo; FILE *f; @@ -709,6 +709,14 @@ read_config(const char *file, const char *ifname) skip = 1; continue; } + /* Start of an ssid block, skip if not ours */ + if (strcmp(option, "ssid") == 0) { + if (ssid && line && strcmp(line, ssid) == 0) + skip = 0; + else + skip = 1; + continue; + } if (skip) continue; if (parse_config_line(ifo, option, line) != 1) { diff --git a/if-options.h b/if-options.h index 545e7479..95e83dc6 100644 --- a/if-options.h +++ b/if-options.h @@ -100,7 +100,7 @@ struct if_options { in_addr_t *blacklist; }; -struct if_options *read_config(const char *, const char *); +struct if_options *read_config(const char *, const char *, const char *); int add_options(struct if_options *, int, char **); void free_options(struct if_options *); diff --git a/net.c b/net.c index 45dab802..ed580cc5 100644 --- a/net.c +++ b/net.c @@ -1,6 +1,6 @@ /* * dhcpcd - DHCP client daemon - * Copyright 2006-2008 Roy Marples + * Copyright 2006-2009 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -196,7 +196,7 @@ init_interface(const char *ifname) /* We reserve the 100 range for virtual interfaces, if and when * we can work them out. */ iface->metric = 200 + if_nametoindex(iface->name); - if (if_wireless(ifname) == 0) + if (getifssid(ifname, iface->ssid) != -1) iface->metric += 100; #ifdef SIOCGIFHWADDR diff --git a/net.h b/net.h index 29e7df36..b65dc7ee 100644 --- a/net.h +++ b/net.h @@ -1,6 +1,6 @@ /* * dhcpcd - DHCP client daemon - * Copyright 2006-2008 Roy Marples + * Copyright 2006-2009 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -91,7 +91,7 @@ uint32_t get_netmask(uint32_t); char *hwaddr_ntoa(const unsigned char *, size_t); size_t hwaddr_aton(unsigned char *, const char *); -int if_wireless(const char *); +int getifssid(const char *, char *); struct interface *init_interface(const char *); struct interface *discover_interfaces(int, char * const *); void free_interface(struct interface *);