mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-28 04:25:19 +08:00
Move ipv4 specific infos from interface to if_state.
This commit is contained in:
parent
875979f614
commit
5dc65f77b3
26
arp.c
26
arp.c
@ -91,7 +91,7 @@ arp_failure(struct interface *ifp)
|
||||
return;
|
||||
}
|
||||
|
||||
unlink(ifp->leasefile);
|
||||
unlink(ifp->state->leasefile);
|
||||
if (!ifp->state->lease.frominfo)
|
||||
dhcp_decline(ifp);
|
||||
dhcp_close(ifp);
|
||||
@ -180,10 +180,10 @@ arp_packet(void *arg)
|
||||
state->fail.s_addr = state->offer->yiaddr;
|
||||
|
||||
/* Handle IPv4LL conflicts */
|
||||
if (IN_LINKLOCAL(htonl(ifp->addr.s_addr)) &&
|
||||
(reply_s == ifp->addr.s_addr ||
|
||||
(reply_s == 0 && reply_t == ifp->addr.s_addr)))
|
||||
state->fail.s_addr = ifp->addr.s_addr;
|
||||
if (IN_LINKLOCAL(htonl(state->addr.s_addr)) &&
|
||||
(reply_s == state->addr.s_addr ||
|
||||
(reply_s == 0 && reply_t == state->addr.s_addr)))
|
||||
state->fail.s_addr = state->addr.s_addr;
|
||||
|
||||
if (state->fail.s_addr) {
|
||||
syslog(LOG_ERR, "%s: hardware address %s claims %s",
|
||||
@ -207,9 +207,9 @@ arp_announce(void *arg)
|
||||
|
||||
if (state->new == NULL)
|
||||
return;
|
||||
if (ifp->arp_fd == -1) {
|
||||
if (state->arp_fd == -1) {
|
||||
open_socket(ifp, ETHERTYPE_ARP);
|
||||
eloop_event_add(ifp->arp_fd, arp_packet, ifp);
|
||||
eloop_event_add(state->arp_fd, arp_packet, ifp);
|
||||
}
|
||||
if (++state->claims < ANNOUNCE_NUM)
|
||||
syslog(LOG_DEBUG,
|
||||
@ -239,9 +239,9 @@ arp_announce(void *arg)
|
||||
timernorm(&tv);
|
||||
eloop_timeout_add_tv(&tv, dhcp_discover, ifp);
|
||||
} else {
|
||||
eloop_event_delete(ifp->arp_fd);
|
||||
close(ifp->arp_fd);
|
||||
ifp->arp_fd = -1;
|
||||
eloop_event_delete(state->arp_fd);
|
||||
close(state->arp_fd);
|
||||
state->arp_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,11 +263,11 @@ arp_probe(void *arg)
|
||||
else
|
||||
addr.s_addr = state->offer->ciaddr;
|
||||
} else
|
||||
addr.s_addr = ifp->addr.s_addr;
|
||||
addr.s_addr = state->addr.s_addr;
|
||||
|
||||
if (ifp->arp_fd == -1) {
|
||||
if (state->arp_fd == -1) {
|
||||
open_socket(ifp, ETHERTYPE_ARP);
|
||||
eloop_event_add(ifp->arp_fd, arp_packet, ifp);
|
||||
eloop_event_add(state->arp_fd, arp_packet, ifp);
|
||||
}
|
||||
if (state->probes == 0) {
|
||||
if (arping)
|
||||
|
112
dhcp.c
112
dhcp.c
@ -819,14 +819,15 @@ make_message(struct dhcp_message **message,
|
||||
struct dhcp_message *dhcp;
|
||||
uint8_t *m, *lp, *p;
|
||||
uint8_t *n_params = NULL;
|
||||
time_t up = uptime() - iface->start_uptime;
|
||||
uint32_t ul;
|
||||
uint16_t sz;
|
||||
size_t len;
|
||||
const char *hp;
|
||||
const struct dhcp_opt *opt;
|
||||
const struct if_options *ifo = iface->options;
|
||||
const struct dhcp_lease *lease = &iface->state->lease;
|
||||
const struct if_state *ifs = iface->state;
|
||||
const struct dhcp_lease *lease = &ifs->lease;
|
||||
time_t up = uptime() - ifs->start_uptime;
|
||||
|
||||
dhcp = xzalloc(sizeof (*dhcp));
|
||||
m = (uint8_t *)dhcp;
|
||||
@ -834,13 +835,13 @@ make_message(struct dhcp_message **message,
|
||||
|
||||
if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
|
||||
(type == DHCP_REQUEST &&
|
||||
iface->net.s_addr == lease->net.s_addr &&
|
||||
(iface->state->new == NULL ||
|
||||
iface->state->new->cookie == htonl(MAGIC_COOKIE)))))
|
||||
ifs->net.s_addr == lease->net.s_addr &&
|
||||
(ifs->new == NULL ||
|
||||
ifs->new->cookie == htonl(MAGIC_COOKIE)))))
|
||||
{
|
||||
dhcp->ciaddr = iface->addr.s_addr;
|
||||
dhcp->ciaddr = ifs->addr.s_addr;
|
||||
/* In-case we haven't actually configured the address yet */
|
||||
if (type == DHCP_INFORM && iface->addr.s_addr == 0)
|
||||
if (type == DHCP_INFORM && ifs->addr.s_addr == 0)
|
||||
dhcp->ciaddr = lease->addr.s_addr;
|
||||
}
|
||||
|
||||
@ -866,23 +867,23 @@ make_message(struct dhcp_message **message,
|
||||
else
|
||||
dhcp->secs = htons(up);
|
||||
}
|
||||
dhcp->xid = htonl(iface->state->xid);
|
||||
dhcp->xid = htonl(ifs->xid);
|
||||
dhcp->cookie = htonl(MAGIC_COOKIE);
|
||||
|
||||
*p++ = DHO_MESSAGETYPE;
|
||||
*p++ = 1;
|
||||
*p++ = type;
|
||||
|
||||
if (iface->clientid) {
|
||||
if (ifs->clientid) {
|
||||
*p++ = DHO_CLIENTID;
|
||||
memcpy(p, iface->clientid, iface->clientid[0] + 1);
|
||||
p += iface->clientid[0] + 1;
|
||||
memcpy(p, ifs->clientid, ifs->clientid[0] + 1);
|
||||
p += ifs->clientid[0] + 1;
|
||||
}
|
||||
|
||||
if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
|
||||
if (type == DHCP_DECLINE ||
|
||||
(type == DHCP_REQUEST &&
|
||||
lease->addr.s_addr != iface->addr.s_addr))
|
||||
lease->addr.s_addr != ifs->addr.s_addr))
|
||||
{
|
||||
PUTADDR(DHO_IPADDRESS, lease->addr);
|
||||
if (lease->server.s_addr)
|
||||
@ -1036,14 +1037,14 @@ write_lease(const struct interface *iface, const struct dhcp_message *dhcp)
|
||||
|
||||
/* We don't write BOOTP leases */
|
||||
if (is_bootp(dhcp)) {
|
||||
unlink(iface->leasefile);
|
||||
unlink(iface->state->leasefile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, "%s: writing lease `%s'",
|
||||
iface->name, iface->leasefile);
|
||||
iface->name, iface->state->leasefile);
|
||||
|
||||
fd = open(iface->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0444);
|
||||
fd = open(iface->state->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0444);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
@ -1072,15 +1073,15 @@ read_lease(const struct interface *iface)
|
||||
struct dhcp_message *dhcp;
|
||||
ssize_t bytes;
|
||||
|
||||
fd = open(iface->leasefile, O_RDONLY);
|
||||
fd = open(iface->state->leasefile, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
if (errno != ENOENT)
|
||||
syslog(LOG_ERR, "%s: open `%s': %m",
|
||||
iface->name, iface->leasefile);
|
||||
iface->name, iface->state->leasefile);
|
||||
return NULL;
|
||||
}
|
||||
syslog(LOG_DEBUG, "%s: reading lease `%s'",
|
||||
iface->name, iface->leasefile);
|
||||
iface->name, iface->state->leasefile);
|
||||
dhcp = xmalloc(sizeof(*dhcp));
|
||||
memset(dhcp, 0, sizeof(*dhcp));
|
||||
bytes = read(fd, dhcp, sizeof(*dhcp));
|
||||
@ -1250,23 +1251,24 @@ dhcp_xid(const struct interface *ifp)
|
||||
}
|
||||
|
||||
void
|
||||
dhcp_close(struct interface *iface)
|
||||
dhcp_close(struct interface *ifp)
|
||||
{
|
||||
struct if_state *ifs = ifp->state;
|
||||
|
||||
if (iface->arp_fd != -1) {
|
||||
eloop_event_delete(iface->arp_fd);
|
||||
close(iface->arp_fd);
|
||||
iface->arp_fd = -1;
|
||||
if (ifs->arp_fd != -1) {
|
||||
eloop_event_delete(ifs->arp_fd);
|
||||
close(ifs->arp_fd);
|
||||
ifs->arp_fd = -1;
|
||||
}
|
||||
if (iface->raw_fd != -1) {
|
||||
eloop_event_delete(iface->raw_fd);
|
||||
close(iface->raw_fd);
|
||||
iface->raw_fd = -1;
|
||||
if (ifs->raw_fd != -1) {
|
||||
eloop_event_delete(ifs->raw_fd);
|
||||
close(ifs->raw_fd);
|
||||
ifs->raw_fd = -1;
|
||||
}
|
||||
if (iface->udp_fd != -1) {
|
||||
if (ifs->udp_fd != -1) {
|
||||
/* we don't listen to events on the udp */
|
||||
close(iface->udp_fd);
|
||||
iface->udp_fd = -1;
|
||||
close(ifs->udp_fd);
|
||||
ifs->udp_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1314,15 +1316,15 @@ send_message(struct interface *iface, int type,
|
||||
* then we cannot renew.
|
||||
* This could happen if our IP was pulled out from underneath us.
|
||||
* Also, we should not unicast from a BOOTP lease. */
|
||||
if (iface->udp_fd == -1 ||
|
||||
(!(ifo->options & DHCPCD_INFORM) && is_bootp(iface->state->new)))
|
||||
if (state->udp_fd == -1 ||
|
||||
(!(ifo->options & DHCPCD_INFORM) && is_bootp(state->new)))
|
||||
{
|
||||
a = iface->addr.s_addr;
|
||||
iface->addr.s_addr = 0;
|
||||
a = state->addr.s_addr;
|
||||
state->addr.s_addr = 0;
|
||||
}
|
||||
len = make_message(&dhcp, iface, type);
|
||||
if (a)
|
||||
iface->addr.s_addr = a;
|
||||
state->addr.s_addr = a;
|
||||
from.s_addr = dhcp->ciaddr;
|
||||
if (from.s_addr)
|
||||
to.s_addr = state->lease.server.s_addr;
|
||||
@ -1419,7 +1421,7 @@ dhcp_discover(void *arg)
|
||||
if (ifo->fallback)
|
||||
eloop_timeout_add_sec(timeout, dhcp_fallback, iface);
|
||||
else if (ifo->options & DHCPCD_IPV4LL &&
|
||||
!IN_LINKLOCAL(htonl(iface->addr.s_addr)))
|
||||
!IN_LINKLOCAL(htonl(iface->state->addr.s_addr)))
|
||||
{
|
||||
if (IN_LINKLOCAL(htonl(iface->state->fail.s_addr)))
|
||||
eloop_timeout_add_sec(RATE_LIMIT_INTERVAL,
|
||||
@ -1450,7 +1452,7 @@ dhcp_expire(void *arg)
|
||||
struct interface *iface = arg;
|
||||
|
||||
iface->state->interval = 0;
|
||||
if (iface->addr.s_addr == 0) {
|
||||
if (iface->state->addr.s_addr == 0) {
|
||||
/* We failed to reboot, so enter discovery. */
|
||||
iface->state->lease.addr.s_addr = 0;
|
||||
dhcp_discover(iface);
|
||||
@ -1460,7 +1462,7 @@ dhcp_expire(void *arg)
|
||||
syslog(LOG_ERR, "%s: lease expired", iface->name);
|
||||
eloop_timeout_delete(NULL, iface);
|
||||
dhcp_drop(iface, "EXPIRE");
|
||||
unlink(iface->leasefile);
|
||||
unlink(iface->state->leasefile);
|
||||
if (iface->carrier != LINK_DOWN)
|
||||
start_interface(iface);
|
||||
}
|
||||
@ -1483,7 +1485,7 @@ dhcp_release(struct interface *iface)
|
||||
nanosleep(&ts, NULL);
|
||||
dhcp_drop(iface, "RELEASE");
|
||||
}
|
||||
unlink(iface->leasefile);
|
||||
unlink(iface->state->leasefile);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1560,7 +1562,7 @@ dhcp_bind(void *arg)
|
||||
if (ifo->req_addr.s_addr != 0)
|
||||
lease->addr.s_addr = ifo->req_addr.s_addr;
|
||||
else
|
||||
lease->addr.s_addr = iface->addr.s_addr;
|
||||
lease->addr.s_addr = state->addr.s_addr;
|
||||
syslog(LOG_INFO, "%s: received approval for %s", iface->name,
|
||||
inet_ntoa(lease->addr));
|
||||
lease->leasetime = ~0U;
|
||||
@ -1717,8 +1719,8 @@ dhcp_inform(struct interface *iface)
|
||||
return;
|
||||
|
||||
if (options & DHCPCD_TEST) {
|
||||
iface->addr.s_addr = iface->options->req_addr.s_addr;
|
||||
iface->net.s_addr = iface->options->req_mask.s_addr;
|
||||
iface->state->addr.s_addr = iface->options->req_addr.s_addr;
|
||||
iface->state->net.s_addr = iface->options->req_mask.s_addr;
|
||||
} else {
|
||||
iface->options->options |= DHCPCD_STATIC;
|
||||
dhcp_static(iface);
|
||||
@ -1888,7 +1890,7 @@ dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp,
|
||||
log_dhcp(LOG_WARNING, "NAK:", iface, dhcp, from);
|
||||
if (!(options & DHCPCD_TEST)) {
|
||||
dhcp_drop(iface, "NAK");
|
||||
unlink(iface->leasefile);
|
||||
unlink(iface->state->leasefile);
|
||||
}
|
||||
dhcp_close(iface);
|
||||
/* If we constantly get NAKS then we should slowly back off */
|
||||
@ -2001,7 +2003,7 @@ dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp,
|
||||
dhcp_close(iface);
|
||||
|
||||
if (ifo->options & DHCPCD_ARP &&
|
||||
iface->addr.s_addr != state->offer->yiaddr)
|
||||
state->addr.s_addr != state->offer->yiaddr)
|
||||
{
|
||||
/* If the interface already has the address configured
|
||||
* then we can't ARP for duplicate detection. */
|
||||
@ -2059,7 +2061,7 @@ dhcp_handlepacket(void *arg)
|
||||
continue;
|
||||
}
|
||||
if (iface->flags & IFF_POINTOPOINT &&
|
||||
iface->dst.s_addr != from.s_addr)
|
||||
iface->state->dst.s_addr != from.s_addr)
|
||||
{
|
||||
syslog(LOG_WARNING,
|
||||
"%s: server %s is not destination",
|
||||
@ -2098,7 +2100,7 @@ dhcp_handlepacket(void *arg)
|
||||
continue;
|
||||
}
|
||||
dhcp_handle(iface, &dhcp, &from);
|
||||
if (iface->raw_fd == -1)
|
||||
if (iface->state->raw_fd == -1)
|
||||
break;
|
||||
}
|
||||
free(packet);
|
||||
@ -2110,17 +2112,19 @@ static int
|
||||
dhcp_open(struct interface *ifp)
|
||||
{
|
||||
int r = 0;
|
||||
struct if_state *ifs;
|
||||
|
||||
if (ifp->raw_fd == -1) {
|
||||
ifs = ifp->state;
|
||||
if (ifs->raw_fd == -1) {
|
||||
if ((r = open_socket(ifp, ETHERTYPE_IP)) == -1)
|
||||
syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name);
|
||||
else
|
||||
eloop_event_add(ifp->raw_fd, dhcp_handlepacket, ifp);
|
||||
eloop_event_add(ifs->raw_fd, dhcp_handlepacket, ifp);
|
||||
}
|
||||
if (ifp->udp_fd == -1 &&
|
||||
ifp->addr.s_addr != 0 &&
|
||||
ifp->state->new != NULL &&
|
||||
(ifp->state->new->cookie == htonl(MAGIC_COOKIE) ||
|
||||
if (ifs->udp_fd == -1 &&
|
||||
ifs->addr.s_addr != 0 &&
|
||||
ifs->new != NULL &&
|
||||
(ifs->new->cookie == htonl(MAGIC_COOKIE) ||
|
||||
ifp->options->options & DHCPCD_INFORM))
|
||||
{
|
||||
if (open_udp_socket(ifp) == -1 && errno != EADDRINUSE) {
|
||||
@ -2172,13 +2176,13 @@ dhcp_start(struct interface *ifp)
|
||||
ifp->state->lease.frominfo = 1;
|
||||
if (ifp->state->offer->cookie == 0) {
|
||||
if (ifp->state->offer->yiaddr ==
|
||||
ifp->addr.s_addr)
|
||||
ifp->state->addr.s_addr)
|
||||
{
|
||||
free(ifp->state->offer);
|
||||
ifp->state->offer = NULL;
|
||||
}
|
||||
} else if (ifp->state->lease.leasetime != ~0U &&
|
||||
stat(ifp->leasefile, &st) == 0)
|
||||
stat(ifp->state->leasefile, &st) == 0)
|
||||
{
|
||||
/* Offset lease times and check expiry */
|
||||
gettimeofday(&now, NULL);
|
||||
|
58
dhcpcd.c
58
dhcpcd.c
@ -299,6 +299,7 @@ stop_interface(struct interface *iface)
|
||||
static void
|
||||
configure_interface1(struct interface *ifp)
|
||||
{
|
||||
struct if_state *ifs = ifp->state;
|
||||
struct if_options *ifo = ifp->options;
|
||||
uint8_t *duid;
|
||||
size_t len, ifl;
|
||||
@ -340,14 +341,14 @@ configure_interface1(struct interface *ifp)
|
||||
break;
|
||||
}
|
||||
|
||||
free(ifp->clientid);
|
||||
ifp->clientid = NULL;
|
||||
free(ifs->clientid);
|
||||
ifs->clientid = NULL;
|
||||
if (!(ifo->options & DHCPCD_IPV4))
|
||||
return;
|
||||
|
||||
if (*ifo->clientid) {
|
||||
ifp->clientid = xmalloc(ifo->clientid[0] + 1);
|
||||
memcpy(ifp->clientid, ifo->clientid, ifo->clientid[0] + 1);
|
||||
ifs->clientid = xmalloc(ifo->clientid[0] + 1);
|
||||
memcpy(ifs->clientid, ifo->clientid, ifo->clientid[0] + 1);
|
||||
} else if (ifo->options & DHCPCD_CLIENTID) {
|
||||
len = 0;
|
||||
if (ifo->options & DHCPCD_DUID) {
|
||||
@ -357,33 +358,33 @@ configure_interface1(struct interface *ifp)
|
||||
} else
|
||||
duid = NULL;
|
||||
if (len > 0) {
|
||||
ifp->clientid = xmalloc(len + 6);
|
||||
ifp->clientid[0] = len + 5;
|
||||
ifp->clientid[1] = 255; /* RFC 4361 */
|
||||
ifs->clientid = xmalloc(len + 6);
|
||||
ifs->clientid[0] = len + 5;
|
||||
ifs->clientid[1] = 255; /* RFC 4361 */
|
||||
ifl = strlen(ifp->name);
|
||||
if (ifl < 5) {
|
||||
memcpy(ifp->clientid + 2, ifp->name, ifl);
|
||||
memcpy(ifs->clientid + 2, ifp->name, ifl);
|
||||
if (ifl < 4)
|
||||
memset(ifp->clientid + 2 + ifl,
|
||||
memset(ifs->clientid + 2 + ifl,
|
||||
0, 4 - ifl);
|
||||
} else {
|
||||
ifl = htonl(ifp->index);
|
||||
memcpy(ifp->clientid + 2, &ifl, 4);
|
||||
memcpy(ifs->clientid + 2, &ifl, 4);
|
||||
}
|
||||
memcpy(ifp->clientid + 6, duid, len);
|
||||
memcpy(ifs->clientid + 6, duid, len);
|
||||
} else if (len == 0) {
|
||||
len = ifp->hwlen + 1;
|
||||
ifp->clientid = xmalloc(len + 1);
|
||||
ifp->clientid[0] = len;
|
||||
ifp->clientid[1] = ifp->family;
|
||||
memcpy(ifp->clientid + 2, ifp->hwaddr,
|
||||
ifs->clientid = xmalloc(len + 1);
|
||||
ifs->clientid[0] = len;
|
||||
ifs->clientid[1] = ifp->family;
|
||||
memcpy(ifs->clientid + 2, ifp->hwaddr,
|
||||
ifp->hwlen);
|
||||
}
|
||||
free(duid);
|
||||
}
|
||||
if (ifo->options & DHCPCD_CLIENTID)
|
||||
syslog(LOG_DEBUG, "%s: using ClientID %s", ifp->name,
|
||||
hwaddr_ntoa(ifp->clientid + 1, *ifp->clientid));
|
||||
hwaddr_ntoa(ifs->clientid + 1, ifs->clientid[0]));
|
||||
else if (ifp->hwlen)
|
||||
syslog(LOG_DEBUG, "%s: using hwaddr %s", ifp->name,
|
||||
hwaddr_ntoa(ifp->hwaddr, ifp->hwlen));
|
||||
@ -491,7 +492,7 @@ start_interface(void *arg)
|
||||
return;
|
||||
}
|
||||
|
||||
ifp->start_uptime = uptime();
|
||||
ifp->state->start_uptime = uptime();
|
||||
free(ifp->state->offer);
|
||||
ifp->state->offer = NULL;
|
||||
|
||||
@ -532,13 +533,19 @@ init_state(struct interface *ifp, int argc, char **argv)
|
||||
ifs->state = DHS_INIT;
|
||||
ifs->reason = "PREINIT";
|
||||
ifs->nakoff = 0;
|
||||
snprintf(ifs->leasefile, sizeof(ifs->leasefile),
|
||||
LEASEFILE, ifp->name);
|
||||
/* 0 is a valid fd, so init to -1 */
|
||||
ifs->raw_fd = ifs->udp_fd = ifs->arp_fd = -1;
|
||||
|
||||
configure_interface(ifp, argc, argv);
|
||||
if (!(options & DHCPCD_TEST))
|
||||
script_run(ifp);
|
||||
|
||||
/* We need to drop the leasefile so that start_interface
|
||||
* doesn't load it. */
|
||||
if (ifp->options->options & DHCPCD_REQUEST)
|
||||
unlink(ifp->leasefile);
|
||||
unlink(ifs->leasefile);
|
||||
|
||||
if (ifp->options->options & DHCPCD_LINK) {
|
||||
switch (carrier_status(ifp)) {
|
||||
@ -668,7 +675,7 @@ if_reboot(struct interface *ifp, int argc, char **argv)
|
||||
ifo = ifp->options;
|
||||
ifp->state->interval = 0;
|
||||
if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) &&
|
||||
ifp->addr.s_addr != ifo->req_addr.s_addr) ||
|
||||
ifp->state->addr.s_addr != ifo->req_addr.s_addr) ||
|
||||
(opt & (DHCPCD_INFORM | DHCPCD_STATIC) &&
|
||||
!(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))))
|
||||
{
|
||||
@ -939,6 +946,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct interface *iface;
|
||||
struct if_state *ifs;
|
||||
uint16_t family = 0;
|
||||
int opt, oi = 0, sig = 0, i, control_fd;
|
||||
size_t len;
|
||||
@ -1072,17 +1080,17 @@ main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
ifaces = iface = xzalloc(sizeof(*iface));
|
||||
strlcpy(iface->name, argv[optind], sizeof(iface->name));
|
||||
snprintf(iface->leasefile, sizeof(iface->leasefile),
|
||||
LEASEFILE, iface->name);
|
||||
iface->state = xzalloc(sizeof(*iface->state));
|
||||
iface->state = ifs = xzalloc(sizeof(*iface->state));
|
||||
iface->options = xzalloc(sizeof(*iface->options));
|
||||
strlcpy(iface->name, argv[optind], sizeof(iface->name));
|
||||
snprintf(ifs->leasefile, sizeof(ifs->leasefile),
|
||||
LEASEFILE, iface->name);
|
||||
strlcpy(iface->options->script, if_options->script,
|
||||
sizeof(iface->options->script));
|
||||
iface->state->new = read_lease(iface);
|
||||
if (iface->state->new == NULL && errno == ENOENT) {
|
||||
strlcpy(iface->leasefile, argv[optind],
|
||||
sizeof(iface->leasefile));
|
||||
strlcpy(ifs->leasefile, argv[optind],
|
||||
sizeof(ifs->leasefile));
|
||||
iface->state->new = read_lease(iface);
|
||||
}
|
||||
if (iface->state->new == NULL) {
|
||||
|
29
dhcpcd.h
29
dhcpcd.h
@ -83,6 +83,21 @@ struct if_state {
|
||||
time_t defend;
|
||||
struct in_addr fail;
|
||||
size_t arping_index;
|
||||
|
||||
int raw_fd;
|
||||
int udp_fd;
|
||||
int arp_fd;
|
||||
size_t buffer_size, buffer_len, buffer_pos;
|
||||
unsigned char *buffer;
|
||||
|
||||
struct in_addr addr;
|
||||
struct in_addr net;
|
||||
struct in_addr dst;
|
||||
|
||||
char leasefile[PATH_MAX];
|
||||
time_t start_uptime;
|
||||
|
||||
unsigned char *clientid;
|
||||
};
|
||||
|
||||
struct interface {
|
||||
@ -100,21 +115,7 @@ struct interface {
|
||||
int wireless;
|
||||
char ssid[IF_SSIDSIZE];
|
||||
|
||||
int raw_fd;
|
||||
int udp_fd;
|
||||
int arp_fd;
|
||||
size_t buffer_size, buffer_len, buffer_pos;
|
||||
unsigned char *buffer;
|
||||
|
||||
struct in_addr addr;
|
||||
struct in_addr net;
|
||||
struct in_addr dst;
|
||||
|
||||
char leasefile[PATH_MAX];
|
||||
time_t start_uptime;
|
||||
|
||||
struct if_options *options;
|
||||
unsigned char *clientid;
|
||||
|
||||
struct interface *next;
|
||||
};
|
||||
|
@ -542,6 +542,7 @@ if_route(const struct rt *rt, int action)
|
||||
{
|
||||
struct nlmr *nlm;
|
||||
int retval = 0;
|
||||
struct if_state *ifs;
|
||||
|
||||
nlm = xzalloc(sizeof(*nlm));
|
||||
nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
||||
@ -556,14 +557,14 @@ if_route(const struct rt *rt, int action)
|
||||
nlm->rt.rtm_family = AF_INET;
|
||||
nlm->rt.rtm_table = RT_TABLE_MAIN;
|
||||
|
||||
ifs = rt->iface->state;
|
||||
if (action == -1 || action == -2)
|
||||
nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
|
||||
else {
|
||||
nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
|
||||
/* We only change route metrics for kernel routes */
|
||||
if (rt->dest.s_addr ==
|
||||
(rt->iface->addr.s_addr & rt->iface->net.s_addr) &&
|
||||
rt->net.s_addr == rt->iface->net.s_addr)
|
||||
if (rt->dest.s_addr == (ifs->addr.s_addr & ifs->net.s_addr) &&
|
||||
rt->net.s_addr == ifs->net.s_addr)
|
||||
nlm->rt.rtm_protocol = RTPROT_KERNEL;
|
||||
else
|
||||
nlm->rt.rtm_protocol = RTPROT_BOOT;
|
||||
@ -581,7 +582,7 @@ if_route(const struct rt *rt, int action)
|
||||
&rt->dest.s_addr, sizeof(rt->dest.s_addr));
|
||||
if (nlm->rt.rtm_protocol == RTPROT_KERNEL) {
|
||||
add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_PREFSRC,
|
||||
&rt->iface->addr.s_addr, sizeof(rt->iface->addr.s_addr));
|
||||
&ifs->addr.s_addr, sizeof(ifs->addr.s_addr));
|
||||
}
|
||||
/* If destination == gateway then don't add the gateway */
|
||||
if (rt->dest.s_addr != rt->gate.s_addr ||
|
||||
|
57
ipv4.c
57
ipv4.c
@ -118,6 +118,8 @@ ipv4_routedeleted(const struct rt *rt)
|
||||
static int
|
||||
n_route(struct rt *rt)
|
||||
{
|
||||
struct if_state *s;
|
||||
|
||||
/* Don't set default routes if not asked to */
|
||||
if (rt->dest.s_addr == 0 &&
|
||||
rt->net.s_addr == 0 &&
|
||||
@ -128,10 +130,10 @@ n_route(struct rt *rt)
|
||||
if (!add_route(rt))
|
||||
return 0;
|
||||
if (errno == EEXIST) {
|
||||
s = rt->iface->state;
|
||||
/* Pretend we added the subnet route */
|
||||
if (rt->dest.s_addr ==
|
||||
(rt->iface->addr.s_addr & rt->iface->net.s_addr) &&
|
||||
rt->net.s_addr == rt->iface->net.s_addr &&
|
||||
if (rt->dest.s_addr == (s->addr.s_addr & s->net.s_addr) &&
|
||||
rt->net.s_addr == s->net.s_addr &&
|
||||
rt->gate.s_addr == 0)
|
||||
return 0;
|
||||
else
|
||||
@ -199,17 +201,19 @@ static struct rt *
|
||||
add_subnet_route(struct rt *rt, const struct interface *iface)
|
||||
{
|
||||
struct rt *r;
|
||||
struct if_state *s;
|
||||
|
||||
if (iface->net.s_addr == INADDR_BROADCAST ||
|
||||
iface->net.s_addr == INADDR_ANY ||
|
||||
s = iface->state;
|
||||
if (s->net.s_addr == INADDR_BROADCAST ||
|
||||
s->net.s_addr == INADDR_ANY ||
|
||||
(iface->options->options &
|
||||
(DHCPCD_INFORM | DHCPCD_STATIC) &&
|
||||
iface->options->req_addr.s_addr == INADDR_ANY))
|
||||
return rt;
|
||||
|
||||
r = xmalloc(sizeof(*r));
|
||||
r->dest.s_addr = iface->addr.s_addr & iface->net.s_addr;
|
||||
r->net.s_addr = iface->net.s_addr;
|
||||
r->dest.s_addr = s->addr.s_addr & s->net.s_addr;
|
||||
r->net.s_addr = s->net.s_addr;
|
||||
r->gate.s_addr = 0;
|
||||
r->next = rt;
|
||||
return r;
|
||||
@ -246,14 +250,15 @@ get_routes(struct interface *ifp)
|
||||
* to the assinged IP address. This differs from our notion of a host route
|
||||
* where the gateway is the destination address, so we fix it. */
|
||||
static struct rt *
|
||||
massage_host_routes(struct rt *rt, const struct interface *iface)
|
||||
massage_host_routes(struct rt *rt, const struct interface *ifp)
|
||||
{
|
||||
struct rt *r;
|
||||
|
||||
for (r = rt; r; r = r->next)
|
||||
if (r->gate.s_addr == iface->addr.s_addr &&
|
||||
for (r = rt; r; r = r->next) {
|
||||
if (r->gate.s_addr == ifp->state->addr.s_addr &&
|
||||
r->net.s_addr == INADDR_BROADCAST)
|
||||
r->gate.s_addr = r->dest.s_addr;
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
@ -268,7 +273,7 @@ add_destination_route(struct rt *rt, const struct interface *iface)
|
||||
r = xmalloc(sizeof(*r));
|
||||
r->dest.s_addr = INADDR_ANY;
|
||||
r->net.s_addr = INADDR_ANY;
|
||||
r->gate.s_addr = iface->dst.s_addr;
|
||||
r->gate.s_addr = iface->state->dst.s_addr;
|
||||
r->next = rt;
|
||||
return r;
|
||||
}
|
||||
@ -347,11 +352,11 @@ ipv4_buildroutes(void)
|
||||
/* Is this route already in our table? */
|
||||
if ((find_route(nrs, rt, NULL, NULL)) != NULL)
|
||||
continue;
|
||||
rt->src.s_addr = ifp->addr.s_addr;
|
||||
rt->src.s_addr = ifp->state->addr.s_addr;
|
||||
/* Do we already manage it? */
|
||||
if ((or = find_route(routes, rt, &rtl, NULL))) {
|
||||
if (or->iface != ifp ||
|
||||
or->src.s_addr != ifp->addr.s_addr ||
|
||||
or->src.s_addr != ifp->state->addr.s_addr ||
|
||||
rt->gate.s_addr != or->gate.s_addr ||
|
||||
rt->metric != or->metric)
|
||||
{
|
||||
@ -400,13 +405,13 @@ delete_address(struct interface *iface)
|
||||
return 0;
|
||||
syslog(LOG_DEBUG, "%s: deleting IP address %s/%d",
|
||||
iface->name,
|
||||
inet_ntoa(iface->addr),
|
||||
inet_ntocidr(iface->net));
|
||||
retval = del_address(iface, &iface->addr, &iface->net);
|
||||
inet_ntoa(iface->state->addr),
|
||||
inet_ntocidr(iface->state->net));
|
||||
retval = del_address(iface, &iface->state->addr, &iface->state->net);
|
||||
if (retval == -1 && errno != EADDRNOTAVAIL)
|
||||
syslog(LOG_ERR, "del_address: %m");
|
||||
iface->addr.s_addr = 0;
|
||||
iface->net.s_addr = 0;
|
||||
iface->state->addr.s_addr = 0;
|
||||
iface->state->net.s_addr = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -426,7 +431,7 @@ ipv4_applyaddr(void *arg)
|
||||
if (dhcp == NULL) {
|
||||
if (!(ifo->options & DHCPCD_PERSISTENT)) {
|
||||
ipv4_buildroutes();
|
||||
if (iface->addr.s_addr != 0)
|
||||
if (iface->state->addr.s_addr != 0)
|
||||
delete_address(iface);
|
||||
script_run(iface);
|
||||
}
|
||||
@ -450,12 +455,12 @@ ipv4_applyaddr(void *arg)
|
||||
}
|
||||
|
||||
/* Now delete the old address if different */
|
||||
if (iface->addr.s_addr != lease->addr.s_addr &&
|
||||
iface->addr.s_addr != 0)
|
||||
if (iface->state->addr.s_addr != lease->addr.s_addr &&
|
||||
iface->state->addr.s_addr != 0)
|
||||
delete_address(iface);
|
||||
|
||||
iface->addr.s_addr = lease->addr.s_addr;
|
||||
iface->net.s_addr = lease->net.s_addr;
|
||||
iface->state->addr.s_addr = lease->addr.s_addr;
|
||||
iface->state->net.s_addr = lease->net.s_addr;
|
||||
|
||||
/* We need to delete the subnet route to have our metric or
|
||||
* prefer the interface. */
|
||||
@ -512,7 +517,7 @@ ipv4_handleifa(int type, const char *ifname,
|
||||
free(ifp->state->old);
|
||||
ifp->state->old = ifp->state->new;
|
||||
ifp->state->new = dhcp_message_new(addr, net);
|
||||
ifp->dst.s_addr = dst ? dst->s_addr : INADDR_ANY;
|
||||
ifp->state->dst.s_addr = dst ? dst->s_addr : INADDR_ANY;
|
||||
if (dst) {
|
||||
for (i = 1; i < 255; i++)
|
||||
if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i))
|
||||
@ -526,8 +531,8 @@ ipv4_handleifa(int type, const char *ifname,
|
||||
ifp->state->xid = dhcp_xid(ifp);
|
||||
ifp->state->lease.server.s_addr =
|
||||
dst ? dst->s_addr : INADDR_ANY;
|
||||
ifp->addr = *addr;
|
||||
ifp->net = *net;
|
||||
ifp->state->addr = *addr;
|
||||
ifp->state->net = *net;
|
||||
dhcp_inform(ifp);
|
||||
}
|
||||
}
|
||||
|
6
ipv4ll.c
6
ipv4ll.c
@ -91,9 +91,9 @@ ipv4ll_start(void *arg)
|
||||
eloop_timeout_delete(NULL, ifp);
|
||||
ifp->state->probes = 0;
|
||||
ifp->state->claims = 0;
|
||||
if (ifp->addr.s_addr) {
|
||||
if (ifp->state->addr.s_addr) {
|
||||
ifp->state->conflicts = 0;
|
||||
if (IN_LINKLOCAL(htonl(ifp->addr.s_addr))) {
|
||||
if (IN_LINKLOCAL(htonl(ifp->state->addr.s_addr))) {
|
||||
arp_announce(ifp);
|
||||
return;
|
||||
}
|
||||
@ -125,7 +125,7 @@ ipv4ll_handle_failure(void *arg)
|
||||
struct interface *ifp = arg;
|
||||
time_t up;
|
||||
|
||||
if (ifp->state->fail.s_addr == ifp->addr.s_addr) {
|
||||
if (ifp->state->fail.s_addr == ifp->state->addr.s_addr) {
|
||||
up = uptime();
|
||||
if (ifp->state->defend + DEFEND_INTERVAL > up) {
|
||||
syslog(LOG_DEBUG,
|
||||
|
12
lpf.c
12
lpf.c
@ -112,9 +112,9 @@ open_socket(struct interface *iface, int protocol)
|
||||
if (bind(s, &su.sa, sizeof(su)) == -1)
|
||||
goto eexit;
|
||||
if (protocol == ETHERTYPE_ARP)
|
||||
fd = &iface->arp_fd;
|
||||
fd = &iface->state->arp_fd;
|
||||
else
|
||||
fd = &iface->raw_fd;
|
||||
fd = &iface->state->raw_fd;
|
||||
if (*fd != -1)
|
||||
close(*fd);
|
||||
*fd = s;
|
||||
@ -148,9 +148,9 @@ send_raw_packet(const struct interface *iface, int protocol,
|
||||
else
|
||||
memset(&su.sll.sll_addr, 0xff, iface->hwlen);
|
||||
if (protocol == ETHERTYPE_ARP)
|
||||
fd = iface->arp_fd;
|
||||
fd = iface->state->arp_fd;
|
||||
else
|
||||
fd = iface->raw_fd;
|
||||
fd = iface->state->raw_fd;
|
||||
|
||||
return sendto(fd, data, len, 0, &su.sa, sizeof(su));
|
||||
}
|
||||
@ -182,9 +182,9 @@ get_raw_packet(struct interface *iface, int protocol,
|
||||
#endif
|
||||
|
||||
if (protocol == ETHERTYPE_ARP)
|
||||
fd = iface->arp_fd;
|
||||
fd = iface->state->arp_fd;
|
||||
else
|
||||
fd = iface->raw_fd;
|
||||
fd = iface->state->raw_fd;
|
||||
bytes = recvmsg(fd, &msg, 0);
|
||||
if (bytes == -1)
|
||||
return errno == EAGAIN ? 0 : -1;
|
||||
|
14
net.c
14
net.c
@ -196,10 +196,10 @@ free_interface(struct interface *ifp)
|
||||
free(ifp->state->old);
|
||||
free(ifp->state->new);
|
||||
free(ifp->state->offer);
|
||||
free(ifp->state->buffer);
|
||||
free(ifp->state->clientid);
|
||||
free(ifp->state);
|
||||
}
|
||||
free(ifp->buffer);
|
||||
free(ifp->clientid);
|
||||
free(ifp);
|
||||
}
|
||||
|
||||
@ -476,10 +476,6 @@ discover_interfaces(int argc, char * const *argv)
|
||||
ifp->wireless = 1;
|
||||
ifp->metric += 100;
|
||||
}
|
||||
snprintf(ifp->leasefile, sizeof(ifp->leasefile),
|
||||
LEASEFILE, ifp->name);
|
||||
/* 0 is a valid fd, so init to -1 */
|
||||
ifp->raw_fd = ifp->udp_fd = ifp->arp_fd = -1;
|
||||
|
||||
if (ifl)
|
||||
ifl->next = ifp;
|
||||
@ -606,11 +602,11 @@ open_udp_socket(struct interface *iface)
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(DHCP_CLIENT_PORT);
|
||||
sin.sin_addr.s_addr = iface->addr.s_addr;
|
||||
sin.sin_addr.s_addr = iface->state->addr.s_addr;
|
||||
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
|
||||
goto eexit;
|
||||
|
||||
iface->udp_fd = s;
|
||||
iface->state->udp_fd = s;
|
||||
set_cloexec(s);
|
||||
return 0;
|
||||
|
||||
@ -629,7 +625,7 @@ send_packet(const struct interface *iface, struct in_addr to,
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = to.s_addr;
|
||||
sin.sin_port = htons(DHCP_SERVER_PORT);
|
||||
return sendto(iface->udp_fd, data, len, 0,
|
||||
return sendto(iface->state->udp_fd, data, len, 0,
|
||||
(struct sockaddr *)&sin, sizeof(sin));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user