Import dhcpcd-5.1.2 with these changes:
* ClientID is now reported when interface starts. * -w, --wait forces dhcpcd to wait until an interface gets a lease or times out. * Ensure DHCP socket is open when sending a DECLINE. * Uses new hwaddr if existing interface is downed and then changed. * No longer works on firewire interfaces by default. dhcpcd-5.1.2 has a new behaviour change - when starting up and at least 1 interface has a carrier then it tries to get a lease or times out. It still daemonises regardless. This, along with the -b and -w flags allows total control over the desired behaviour of dhcpcd.
This commit is contained in:
parent
336cbcc88d
commit
3b87816311
|
@ -82,9 +82,8 @@ handle_arp_failure(struct interface *iface)
|
|||
handle_ipv4ll_failure(iface);
|
||||
return;
|
||||
}
|
||||
if (iface->state->lease.frominfo)
|
||||
unlink(iface->leasefile);
|
||||
else
|
||||
unlink(iface->leasefile);
|
||||
if (!iface->state->lease.frominfo)
|
||||
send_decline(iface);
|
||||
close_sockets(iface);
|
||||
delete_timeout(NULL, iface);
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
#define LIBEXECDIR "/libexec"
|
||||
#define DBDIR "/var/db"
|
||||
#define RUNDIR "/var/run"
|
||||
#include "compat/getline.h"
|
||||
#include "compat/getline.h"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#define CONFIG_H
|
||||
|
||||
#define PACKAGE "dhcpcd"
|
||||
#define VERSION "5.1.1"
|
||||
#define VERSION "5.1.2"
|
||||
|
||||
#ifndef CONFIG
|
||||
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* Max MTU - defines dhcp option length */
|
||||
#define MTU_MAX 1500
|
||||
#define MTU_MIN 576
|
||||
|
|
|
@ -137,7 +137,7 @@ read_pid(void)
|
|||
static void
|
||||
usage(void)
|
||||
{
|
||||
printf("usage: "PACKAGE" [-dgknpqxyADEGHKLOTV] [-c script] [-f file]"
|
||||
printf("usage: "PACKAGE" [-dgknpqwxyADEGHKLOTV] [-c script] [-f file]"
|
||||
" [-e var=val]\n"
|
||||
" [-h hostname] [-i classID ] [-l leasetime]"
|
||||
" [-m metric] [-o option]\n"
|
||||
|
@ -185,11 +185,18 @@ cleanup(void)
|
|||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
_noreturn void
|
||||
void
|
||||
handle_exit_timeout(_unused void *arg)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
syslog(LOG_ERR, "timed out");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!(options & DHCPCD_TIMEOUT_IPV4LL))
|
||||
exit(EXIT_FAILURE);
|
||||
options &= ~DHCPCD_TIMEOUT_IPV4LL;
|
||||
timeout = (PROBE_NUM * PROBE_MAX) + PROBE_WAIT + 1;
|
||||
syslog(LOG_WARNING, "allowing %d seconds for IPv4LL timeout", timeout);
|
||||
add_timeout_sec(timeout, handle_exit_timeout, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -387,12 +394,6 @@ start_expire(void *arg)
|
|||
start_interface(iface);
|
||||
}
|
||||
|
||||
void
|
||||
send_decline(struct interface *iface)
|
||||
{
|
||||
send_message(iface, DHCP_DECLINE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
log_dhcp(int lvl, const char *msg,
|
||||
const struct interface *iface, const struct dhcp_message *dhcp)
|
||||
|
@ -715,6 +716,13 @@ send_release(struct interface *iface)
|
|||
unlink(iface->leasefile);
|
||||
}
|
||||
|
||||
void
|
||||
send_decline(struct interface *iface)
|
||||
{
|
||||
open_sockets(iface);
|
||||
send_message(iface, DHCP_DECLINE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
configure_interface1(struct interface *iface)
|
||||
{
|
||||
|
@ -728,7 +736,7 @@ configure_interface1(struct interface *iface)
|
|||
if (iface->flags & IFF_NOARP ||
|
||||
ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))
|
||||
ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL);
|
||||
if (ifo->options & DHCPCD_LINK && carrier_status(iface->name) == -1)
|
||||
if (ifo->options & DHCPCD_LINK && carrier_status(iface) == -1)
|
||||
ifo->options &= ~DHCPCD_LINK;
|
||||
|
||||
if (ifo->metric != -1)
|
||||
|
@ -773,6 +781,9 @@ configure_interface1(struct interface *iface)
|
|||
iface->hwlen);
|
||||
}
|
||||
}
|
||||
if (ifo->options & DHCPCD_CLIENTID)
|
||||
syslog(LOG_DEBUG, "%s: using ClientID %s", iface->name,
|
||||
hwaddr_ntoa(iface->clientid + 1, *iface->clientid));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -821,6 +832,7 @@ static void
|
|||
handle_carrier(const char *ifname)
|
||||
{
|
||||
struct interface *iface;
|
||||
int carrier;
|
||||
|
||||
if (!(options & DHCPCD_LINK))
|
||||
return;
|
||||
|
@ -829,11 +841,10 @@ handle_carrier(const char *ifname)
|
|||
break;
|
||||
if (!iface || !(iface->state->options->options & DHCPCD_LINK))
|
||||
return;
|
||||
switch (carrier_status(iface->name)) {
|
||||
case -1:
|
||||
syslog(LOG_ERR, "carrier_status: %m");
|
||||
break;
|
||||
case 0:
|
||||
carrier = carrier_status(iface);
|
||||
if (carrier == -1)
|
||||
syslog(LOG_ERR, "%s: carrier_status: %m", ifname);
|
||||
else if (carrier == 0 || !(iface->flags & IFF_RUNNING)) {
|
||||
if (iface->carrier != LINK_DOWN) {
|
||||
iface->carrier = LINK_DOWN;
|
||||
syslog(LOG_INFO, "%s: carrier lost", iface->name);
|
||||
|
@ -841,8 +852,7 @@ handle_carrier(const char *ifname)
|
|||
delete_timeouts(iface, start_expire, NULL);
|
||||
drop_config(iface, "NOCARRIER");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
} else if (carrier == 1 && (iface->flags & IFF_RUNNING)) {
|
||||
if (iface->carrier != LINK_UP) {
|
||||
iface->carrier = LINK_UP;
|
||||
syslog(LOG_INFO, "%s: carrier acquired", iface->name);
|
||||
|
@ -854,7 +864,6 @@ handle_carrier(const char *ifname)
|
|||
run_script(iface);
|
||||
start_interface(iface);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1165,7 +1174,7 @@ init_state(struct interface *iface, int argc, char **argv)
|
|||
run_script(iface);
|
||||
|
||||
if (ifs->options->options & DHCPCD_LINK) {
|
||||
switch (carrier_status(iface->name)) {
|
||||
switch (carrier_status(iface)) {
|
||||
case 0:
|
||||
iface->carrier = LINK_DOWN;
|
||||
ifs->reason = "NOCARRIER";
|
||||
|
@ -1220,13 +1229,19 @@ handle_interface(int action, const char *ifname)
|
|||
break;
|
||||
ifl = ifn;
|
||||
}
|
||||
if (ifn)
|
||||
continue;
|
||||
if (ifn) {
|
||||
/* The flags and hwaddr could have changed */
|
||||
ifn->flags = ifp->flags;
|
||||
ifn->hwlen = ifp->hwlen;
|
||||
if (ifp->hwlen != 0)
|
||||
memcpy(ifn->hwaddr, ifp->hwaddr, ifn->hwlen);
|
||||
} else {
|
||||
if (ifl)
|
||||
ifl->next = ifp;
|
||||
else
|
||||
ifaces = ifp;
|
||||
}
|
||||
init_state(ifp, 0, NULL);
|
||||
if (ifl)
|
||||
ifl->next = ifp;
|
||||
else
|
||||
ifaces = ifp;
|
||||
start_interface(ifp);
|
||||
}
|
||||
}
|
||||
|
@ -1665,6 +1680,10 @@ main(int argc, char **argv)
|
|||
if (pid == 0 || kill(pid, sig) != 0) {
|
||||
if (sig != SIGALRM)
|
||||
syslog(LOG_ERR, ""PACKAGE" not running");
|
||||
if (pid != 0 && errno != ESRCH) {
|
||||
syslog(LOG_ERR, "kill: %m");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
unlink(pidfile);
|
||||
if (sig != SIGALRM)
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -1736,7 +1755,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (init_socket() == -1) {
|
||||
if (init_sockets() == -1) {
|
||||
syslog(LOG_ERR, "init_socket: %m");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -1750,17 +1769,6 @@ main(int argc, char **argv)
|
|||
|
||||
ifc = argc - optind;
|
||||
ifv = argv + optind;
|
||||
if (options & DHCPCD_BACKGROUND ||
|
||||
(ifc == 0 && options & DHCPCD_LINK && options & DHCPCD_DAEMONISE))
|
||||
{
|
||||
daemonise();
|
||||
} else if (options & DHCPCD_DAEMONISE && ifo->timeout > 0) {
|
||||
oi = ifo->timeout;
|
||||
if (ifo->options & DHCPCD_IPV4LL)
|
||||
oi += 10;
|
||||
add_timeout_sec(oi, handle_exit_timeout, NULL);
|
||||
}
|
||||
free_options(ifo);
|
||||
|
||||
ifaces = discover_interfaces(ifc, ifv);
|
||||
for (i = 0; i < ifc; i++) {
|
||||
|
@ -1774,15 +1782,37 @@ main(int argc, char **argv)
|
|||
if (!ifaces) {
|
||||
if (ifc == 0)
|
||||
syslog(LOG_ERR, "no valid interfaces found");
|
||||
else
|
||||
exit(EXIT_FAILURE);
|
||||
if (!(options & DHCPCD_LINK)) {
|
||||
syslog(LOG_ERR, "aborting as we're not backgrounding"
|
||||
" with link detection");
|
||||
syslog(LOG_ERR,
|
||||
"aborting as link detection is disabled");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (iface = ifaces; iface; iface = iface->next)
|
||||
if (options & DHCPCD_BACKGROUND)
|
||||
daemonise();
|
||||
|
||||
opt = 0;
|
||||
for (iface = ifaces; iface; iface = iface->next) {
|
||||
init_state(iface, argc, argv);
|
||||
if (iface->carrier != LINK_DOWN)
|
||||
opt = 1;
|
||||
}
|
||||
if (opt == 0 &&
|
||||
options & DHCPCD_LINK &&
|
||||
!(options & DHCPCD_WAITIP))
|
||||
{
|
||||
syslog(LOG_WARNING, "no interfaces have a carrier");
|
||||
daemonise();
|
||||
} else if (options & DHCPCD_DAEMONISE && ifo->timeout > 0) {
|
||||
if (options & DHCPCD_IPV4LL)
|
||||
options |= DHCPCD_TIMEOUT_IPV4LL;
|
||||
add_timeout_sec(ifo->timeout, handle_exit_timeout, NULL);
|
||||
}
|
||||
free_options(ifo);
|
||||
|
||||
sort_interfaces();
|
||||
for (iface = ifaces; iface; iface = iface->next)
|
||||
add_timeout_sec(0, start_interface, iface);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd September 2, 2009
|
||||
.Dd October 16, 2009
|
||||
.Dt DHCPCD.CONF 5 SMM
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -272,6 +272,8 @@ Set un-encapulated vendor option to hello world.
|
|||
.It Ic vendorclassid Ar string
|
||||
Change the default vendorclassid sent from dhcpcd-version.
|
||||
If not set then none is sent.
|
||||
.It Ic waitip
|
||||
Wait for an address to be assigned before forking to the background.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr dhcpcd-run-hooks 8 ,
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
* Copyright (c) 2006-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef GETLINE_H
|
||||
#define GETLINE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
ssize_t getline(char ** __restrict buf, size_t * __restrict buflen,
|
||||
FILE * __restrict fp);
|
||||
#endif
|
|
@ -70,15 +70,14 @@
|
|||
? \
|
||||
(((struct sockaddr_in *)(void *)sa)->sin_addr).s_addr : 0
|
||||
|
||||
static int a_fd = -1;
|
||||
static int r_fd = -1;
|
||||
|
||||
int
|
||||
init_socket(void)
|
||||
init_sockets(void)
|
||||
{
|
||||
if ((a_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
if ((socket_afnet = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
set_cloexec(a_fd);
|
||||
set_cloexec(socket_afnet);
|
||||
if ((r_fd = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
|
||||
return -1;
|
||||
set_cloexec(r_fd);
|
||||
|
@ -102,7 +101,7 @@ getifssid(const char *ifname, char *ssid)
|
|||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
memset(&nwid, 0, sizeof(nwid));
|
||||
ifr.ifr_data = (void *)&nwid;
|
||||
if (ioctl(a_fd, SIOCG80211NWID, &ifr) == 0) {
|
||||
if (ioctl(socket_afnet, SIOCG80211NWID, &ifr) == 0) {
|
||||
retval = nwid.i_len;
|
||||
memcpy(ssid, nwid.i_nwid, nwid.i_len);
|
||||
ssid[nwid.i_len] = '\0';
|
||||
|
@ -113,7 +112,7 @@ getifssid(const char *ifname, char *ssid)
|
|||
ireq.i_type = IEEE80211_IOC_SSID;
|
||||
ireq.i_val = -1;
|
||||
ireq.i_data = &nwid;
|
||||
if (ioctl(a_fd, SIOCG80211, &ireq) == 0) {
|
||||
if (ioctl(socket_afnet, SIOCG80211, &ireq) == 0) {
|
||||
retval = ireq.i_len;
|
||||
memcpy(ssid, nwid, ireq.i_len);
|
||||
ssid[ireq.i_len] = '\0';
|
||||
|
@ -152,9 +151,9 @@ if_address(const struct interface *iface, const struct in_addr *address,
|
|||
#undef ADDADDR
|
||||
|
||||
if (action < 0)
|
||||
retval = ioctl(a_fd, SIOCDIFADDR, &ifa);
|
||||
retval = ioctl(socket_afnet, SIOCDIFADDR, &ifa);
|
||||
else
|
||||
retval = ioctl(a_fd, SIOCAIFADDR, &ifa);
|
||||
retval = ioctl(socket_afnet, SIOCAIFADDR, &ifa);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ const struct option cf_options[] = {
|
|||
{"timeout", required_argument, NULL, 't'},
|
||||
{"userclass", required_argument, NULL, 'u'},
|
||||
{"vendor", required_argument, NULL, 'v'},
|
||||
{"waitip", no_argument, NULL, 'w'},
|
||||
{"exit", no_argument, NULL, 'x'},
|
||||
{"allowinterfaces", required_argument, NULL, 'z'},
|
||||
{"reboot", required_argument, NULL, 'y'},
|
||||
|
@ -507,6 +508,9 @@ parse_option(struct if_options *ifo, int opt, const char *arg)
|
|||
ifo->vendor[0] += s + 2;
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
ifo->options |= DHCPCD_WAITIP;
|
||||
break;
|
||||
case 'y':
|
||||
ifo->reboot = atoint(arg);
|
||||
if (ifo->reboot < 0) {
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
/* Don't set any optional arguments here so we retain POSIX
|
||||
* compatibility with getopt */
|
||||
#define IF_OPTS "bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:xy:z:ABC:DEF:GI:KLN:O:Q:TVW:X:Z:"
|
||||
#define IF_OPTS "bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:wxy:z:ABC:DEF:GI:KLN:O:Q:TVW:X:Z:"
|
||||
|
||||
#define DEFAULT_TIMEOUT 30
|
||||
#define DEFAULT_REBOOT 10
|
||||
|
@ -70,6 +70,8 @@
|
|||
#define DHCPCD_QUIET (1 << 21)
|
||||
#define DHCPCD_BACKGROUND (1 << 22)
|
||||
#define DHCPCD_VENDORRAW (1 << 23)
|
||||
#define DHCPCD_TIMEOUT_IPV4LL (1 << 24)
|
||||
#define DHCPCD_WAITIP (1 << 25)
|
||||
|
||||
extern const struct option cf_options[];
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@
|
|||
|
||||
static char hwaddr_buffer[(HWADDR_LEN * 3) + 1];
|
||||
|
||||
int socket_afnet = -1;
|
||||
|
||||
int
|
||||
inet_ntocidr(struct in_addr address)
|
||||
{
|
||||
|
@ -183,18 +185,12 @@ hwaddr_aton(unsigned char *buffer, const char *addr)
|
|||
struct interface *
|
||||
init_interface(const char *ifname)
|
||||
{
|
||||
int s;
|
||||
struct ifreq ifr;
|
||||
struct interface *iface = NULL;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return NULL;
|
||||
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1)
|
||||
if (ioctl(socket_afnet, SIOCGIFFLAGS, &ifr) == -1)
|
||||
goto eexit;
|
||||
|
||||
iface = xzalloc(sizeof(*iface));
|
||||
|
@ -208,13 +204,13 @@ init_interface(const char *ifname)
|
|||
iface->metric += 100;
|
||||
}
|
||||
|
||||
if (ioctl(s, SIOCGIFMTU, &ifr) == -1)
|
||||
if (ioctl(socket_afnet, SIOCGIFMTU, &ifr) == -1)
|
||||
goto eexit;
|
||||
/* Ensure that the MTU is big enough for DHCP */
|
||||
if (ifr.ifr_mtu < MTU_MIN) {
|
||||
ifr.ifr_mtu = MTU_MIN;
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
if (ioctl(s, SIOCSIFMTU, &ifr) == -1)
|
||||
if (ioctl(socket_afnet, SIOCSIFMTU, &ifr) == -1)
|
||||
goto eexit;
|
||||
}
|
||||
|
||||
|
@ -230,7 +226,6 @@ eexit:
|
|||
free(iface);
|
||||
iface = NULL;
|
||||
exit:
|
||||
close(s);
|
||||
return iface;
|
||||
}
|
||||
|
||||
|
@ -250,6 +245,72 @@ free_interface(struct interface *iface)
|
|||
free(iface);
|
||||
}
|
||||
|
||||
int
|
||||
carrier_status(struct interface *iface)
|
||||
{
|
||||
int ret;
|
||||
struct ifreq ifr;
|
||||
#ifdef SIOCGIFMEDIA
|
||||
struct ifmediareq ifmr;
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
char *p;
|
||||
#endif
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
|
||||
#ifdef __linux__
|
||||
/* We can only test the real interface up */
|
||||
if ((p = strchr(ifr.ifr_name, ':')))
|
||||
*p = '\0';
|
||||
#endif
|
||||
|
||||
if (ioctl(socket_afnet, SIOCGIFFLAGS, &ifr) == -1)
|
||||
return -1;
|
||||
iface->flags = ifr.ifr_flags;
|
||||
|
||||
ret = -1;
|
||||
#ifdef SIOCGIFMEDIA
|
||||
memset(&ifmr, 0, sizeof(ifmr));
|
||||
strlcpy(ifmr.ifm_name, iface->name, sizeof(ifmr.ifm_name));
|
||||
if (ioctl(socket_afnet, SIOCGIFMEDIA, &ifmr) != -1 &&
|
||||
ifmr.ifm_status & IFM_AVALID)
|
||||
ret = (ifmr.ifm_status & IFM_ACTIVE) ? 1 : 0;
|
||||
#endif
|
||||
if (ret == -1)
|
||||
ret = (ifr.ifr_flags & IFF_RUNNING) ? 1 : 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
up_interface(struct interface *iface)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int retval = -1;
|
||||
#ifdef __linux__
|
||||
char *p;
|
||||
#endif
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
|
||||
#ifdef __linux__
|
||||
/* We can only bring the real interface up */
|
||||
if ((p = strchr(ifr.ifr_name, ':')))
|
||||
*p = '\0';
|
||||
#endif
|
||||
if (ioctl(socket_afnet, SIOCGIFFLAGS, &ifr) == 0) {
|
||||
if ((ifr.ifr_flags & IFF_UP))
|
||||
retval = 0;
|
||||
else {
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(socket_afnet, SIOCSIFFLAGS, &ifr) == 0)
|
||||
retval = 0;
|
||||
}
|
||||
iface->flags = ifr.ifr_flags;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct interface *
|
||||
discover_interfaces(int argc, char * const *argv)
|
||||
{
|
||||
|
@ -327,13 +388,13 @@ discover_interfaces(int argc, char * const *argv)
|
|||
if ((ifp = init_interface(p)) == NULL)
|
||||
continue;
|
||||
|
||||
/* Bring the interface up */
|
||||
if (!(ifp->flags & IFF_UP) && up_interface(p) != 0)
|
||||
/* Some drivers return ENODEV here when they are disabled by a switch.
|
||||
* We just blunder on as the carrier will be down anyway.
|
||||
* When the switch is enabled, it should bring the interface up.
|
||||
* Then we'll spot the carrier and start working. */
|
||||
syslog(LOG_ERR, "%s: up_interface: %m", p);
|
||||
/* Bring the interface up if not already */
|
||||
if (!(ifp->flags & IFF_UP) &&
|
||||
#ifdef SIOCGIFMEDIA
|
||||
carrier_status(ifp) != -1 &&
|
||||
#endif
|
||||
up_interface(ifp) != 0)
|
||||
syslog(LOG_ERR, "%s: up_interface: %m", ifp->name);
|
||||
|
||||
/* Don't allow loopback unless explicit */
|
||||
if (ifp->flags & IFF_LOOPBACK) {
|
||||
|
@ -364,22 +425,19 @@ discover_interfaces(int argc, char * const *argv)
|
|||
if (ifp->hwlen != 0)
|
||||
memcpy(ifp->hwaddr, sll->sll_addr, ifp->hwlen);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (!(ifp->flags & IFF_POINTOPOINT)) {
|
||||
switch(ifp->family) {
|
||||
case ARPHRD_ETHER: /* FALLTHROUGH */
|
||||
case ARPHRD_IEEE1394:
|
||||
break;
|
||||
default:
|
||||
if (argc == 0 && ifac == 0) {
|
||||
free_interface(ifp);
|
||||
continue;
|
||||
}
|
||||
/* We only work on ethernet by default */
|
||||
if (!(ifp->flags & IFF_POINTOPOINT) &&
|
||||
ifp->family != ARPHRD_ETHER)
|
||||
{
|
||||
if (argc == 0 && ifac == 0) {
|
||||
free_interface(ifp);
|
||||
continue;
|
||||
}
|
||||
if (ifp->family != ARPHRD_IEEE1394)
|
||||
syslog(LOG_WARNING,
|
||||
"%s: unknown hardware family", p);
|
||||
}
|
||||
}
|
||||
if (ifl)
|
||||
ifl->next = ifp;
|
||||
|
@ -433,98 +491,17 @@ do_address(const char *ifname,
|
|||
freeifaddrs(ifaddrs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
up_interface(const char *ifname)
|
||||
{
|
||||
int s;
|
||||
struct ifreq ifr;
|
||||
int retval = -1;
|
||||
#ifdef __linux__
|
||||
char *p;
|
||||
#endif
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
#ifdef __linux__
|
||||
/* We can only bring the real interface up */
|
||||
if ((p = strchr(ifr.ifr_name, ':')))
|
||||
*p = '\0';
|
||||
#endif
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {
|
||||
if ((ifr.ifr_flags & IFF_UP))
|
||||
retval = 0;
|
||||
else {
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0)
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
close(s);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
carrier_status(const char *ifname)
|
||||
{
|
||||
int s;
|
||||
struct ifreq ifr;
|
||||
int retval = -1;
|
||||
#ifdef SIOCGIFMEDIA
|
||||
struct ifmediareq ifmr;
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
char *p;
|
||||
#endif
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
#ifdef __linux__
|
||||
/* We can only test the real interface up */
|
||||
if ((p = strchr(ifr.ifr_name, ':')))
|
||||
*p = '\0';
|
||||
#endif
|
||||
if ((retval = ioctl(s, SIOCGIFFLAGS, &ifr)) == 0) {
|
||||
if (ifr.ifr_flags & IFF_UP && ifr.ifr_flags & IFF_RUNNING)
|
||||
retval = 1;
|
||||
else
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
#ifdef SIOCGIFMEDIA
|
||||
if (retval == 1) {
|
||||
memset(&ifmr, 0, sizeof(ifmr));
|
||||
strlcpy(ifmr.ifm_name, ifr.ifr_name, sizeof(ifmr.ifm_name));
|
||||
retval = -1;
|
||||
if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 &&
|
||||
ifmr.ifm_status & IFM_AVALID)
|
||||
retval = (ifmr.ifm_status & IFM_ACTIVE) ? 1 : 0;
|
||||
}
|
||||
#endif
|
||||
close(s);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
do_mtu(const char *ifname, short int mtu)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int r;
|
||||
int s;
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_mtu = mtu;
|
||||
r = ioctl(s, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
|
||||
close(s);
|
||||
r = ioctl(socket_afnet, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
|
||||
if (r == -1)
|
||||
return -1;
|
||||
return ifr.ifr_mtu;
|
||||
|
|
|
@ -87,6 +87,8 @@ struct rt {
|
|||
struct rt *next;
|
||||
};
|
||||
|
||||
extern int socket_afnet;
|
||||
|
||||
uint32_t get_netmask(uint32_t);
|
||||
char *hwaddr_ntoa(const unsigned char *, size_t);
|
||||
size_t hwaddr_aton(unsigned char *, const char *);
|
||||
|
@ -102,7 +104,7 @@ int do_mtu(const char *, short int);
|
|||
int inet_ntocidr(struct in_addr);
|
||||
int inet_cidrtoaddr(int, struct in_addr *);
|
||||
|
||||
int up_interface(const char *);
|
||||
int up_interface(struct interface *);
|
||||
int do_address(const char *,
|
||||
struct in_addr *, struct in_addr *, struct in_addr *, int);
|
||||
int if_address(const struct interface *,
|
||||
|
@ -130,7 +132,7 @@ int if_route(const struct interface *, const struct in_addr *,
|
|||
void free_routes(struct rt *);
|
||||
|
||||
int open_udp_socket(struct interface *);
|
||||
const size_t udp_dhcp_len;
|
||||
extern const size_t udp_dhcp_len;
|
||||
ssize_t make_udp_packet(uint8_t **, const uint8_t *, size_t,
|
||||
struct in_addr, struct in_addr);
|
||||
ssize_t get_udp_data(const uint8_t **, const uint8_t *);
|
||||
|
@ -143,8 +145,8 @@ ssize_t send_raw_packet(const struct interface *, int,
|
|||
const void *, ssize_t);
|
||||
ssize_t get_raw_packet(struct interface *, int, void *, ssize_t);
|
||||
|
||||
int init_socket(void);
|
||||
int init_sockets(void);
|
||||
int open_link_socket(void);
|
||||
int manage_link(int);
|
||||
int carrier_status(const char *);
|
||||
int carrier_status(struct interface *);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue