to work, such as loopback and ppp.
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 30, 2014
+.Dd November 18, 2014
.Dt DHCPCD 8
.Os
.Sh NAME
changes when the lease beings to expire or the DHCP server sends message
to renew early.
.Pp
+If any interface reports a working carrier then
+.Nm
+will try and obtain a lease before forking to the background,
+otherwise it will fork right away.
+This behaviour can be modified with the
+.Fl b , Fl Fl background
+and
+.Fl w , Fl Fl waitip
+options.
+.Pp
.Nm
is also an implementation of the BOOTP client specified in
.Li RFC 951 .
.Nm
only works with those interfaces, otherwise
.Nm
-discovers available Ethernet interfaces.
-This is called Master mode and this behaviour can be forced with the
+discovers available Ethernet interfaces that can be configured.
+When
+.Nm
+is operating on more than one interface,
+it is called Master mode. and this behaviour can be forced with the
.Fl M , Fl Fl master
option so that an individual interface can start
.Nm
The
.Nm dhcpcd-ui
project expects dhcpcd to be running this way.
-If any interface reports a working carrier then
-.Nm
-will try and obtain a lease before forking to the background,
-otherwise it will fork right away.
-This behaviour can be modified with the
-.Fl b , Fl Fl background
-and
-.Fl w , Fl Fl waitip
-options.
.Pp
If a single interface is given then
.Nm
free(ctx->ifdv);
ctx->ifdv = NULL;
}
+ if (ctx->ifcc) {
+ for (; ctx->ifcc > 0; ctx->ifcc--)
+ free(ctx->ifcv[ctx->ifcc - 1]);
+ free(ctx->ifcv);
+ ctx->ifcv = NULL;
+ }
#ifdef INET
if (ctx->dhcp_opts) {
char **ifdv; /* denied interfaces */
int ifc; /* listed interfaces */
char **ifv; /* listed interfaces */
+ int ifcc; /* configured interfaces */
+ char **ifcv; /* configured interfaces */
unsigned char *duid;
size_t duid_len;
int pid_fd;
}
/* Start of an interface block, skip if not ours */
if (strcmp(option, "interface") == 0) {
+ char **n;
+
if (ifname && line && strcmp(line, ifname) == 0)
skip = 0;
else
skip = 1;
+ if (ifname)
+ continue;
+
+ n = realloc(ctx->ifcv,
+ sizeof(char *) * ((size_t)ctx->ifcc + 1));
+ if (n == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
+ continue;
+ }
+ ctx->ifcv = n;
+ ctx->ifcv[ctx->ifcc] = strdup(line);
+ if (ctx->ifcv[ctx->ifcc] == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
+ continue;
+ }
+ ctx->ifcc++;
+ syslog(LOG_DEBUG, "allowing interface %s",
+ ctx->ifcv[ctx->ifcc - 1]);
continue;
}
/* Start of an ssid block, skip if not ours */
return r;
}
+static int
+if_hasconf(struct dhcpcd_ctx *ctx, const char *ifname)
+{
+ int i;
+
+ for (i = 0; i < ctx->ifcc; i++) {
+ if (strcmp(ctx->ifcv[i], ifname) == 0)
+ return 1;
+ }
+ return 0;
+}
+
struct if_head *
if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
{
/* Don't allow loopback or pointopoint unless explicit */
if (ifa->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) {
- if ((argc == 0 || argc == -1) && ctx->ifac == 0)
+ if ((argc == 0 || argc == -1) &&
+ ctx->ifac == 0 && !if_hasconf(ctx, p))
continue;
}
-
if (if_vimaster(p) == 1) {
syslog(argc ? LOG_ERR : LOG_DEBUG,
"%s: is a Virtual Interface Master, skipping", p);
#ifdef IFT_BRIDGE
case IFT_BRIDGE:
/* Don't allow bridge unless explicit */
- if ((argc == 0 || argc == -1)
- && ctx->ifac == 0)
+ if ((argc == 0 || argc == -1) &&
+ ctx->ifac == 0 &&
+ !if_hasconf(ctx, ifp->name))
{
if_free(ifp);
continue;
/* We only work on ethernet by default */
if (ifp->family != ARPHRD_ETHER) {
- if ((argc == 0 || argc == -1) && ctx->ifac == 0) {
+ if ((argc == 0 || argc == -1) &&
+ ctx->ifac == 0 && !if_hasconf(ctx, ifp->name))
+ {
if_free(ifp);
continue;
}
break;
default:
syslog(LOG_WARNING,
- "%s: unsupported interface type %.2x"
- ", family %.2x",
+ "%s: unsupported interface type %.2x, "
+ "family %.2x",
ifp->name, sdl_type, ifp->family);
break;
}