/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2011 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "config.h"
#include "common.h"
#include "dhcp.h"
-#include "net.h"
+#include "ipv4.h"
#include "bpf-filter.h"
int
-open_socket(struct interface *iface, int protocol)
+ipv4_opensocket(struct interface *ifp, int protocol)
{
+ struct dhcp_state *state;
int fd = -1;
int *fdp = NULL;
struct ifreq ifr;
if (fd == -1)
return -1;
+ state = D_STATE(ifp);
+
if (ioctl(fd, BIOCVERSION, &pv) == -1)
goto eexit;
if (pv.bv_major != BPF_MAJOR_VERSION ||
}
memset(&ifr, 0, sizeof(ifr));
- strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
if (ioctl(fd, BIOCSETIF, &ifr) == -1)
goto eexit;
/* Get the required BPF buffer length from the kernel. */
if (ioctl(fd, BIOCGBLEN, &buf_len) == -1)
goto eexit;
- if (iface->buffer_size != (size_t)buf_len) {
- free(iface->buffer);
- iface->buffer_size = buf_len;
- iface->buffer = xmalloc(buf_len);
- iface->buffer_len = iface->buffer_pos = 0;
+ if (state->buffer_size != (size_t)buf_len) {
+ free(state->buffer);
+ state->buffer = malloc(buf_len);
+ if (state->buffer == NULL)
+ goto eexit;
+ state->buffer_size = buf_len;
+ state->buffer_len = state->buffer_pos = 0;
}
#ifdef BIOCIMMEDIATE
if (protocol == ETHERTYPE_ARP) {
pf.bf_insns = UNCONST(arp_bpf_filter);
pf.bf_len = arp_bpf_filter_len;
- fdp = &iface->arp_fd;
+ fdp = &state->arp_fd;
} else {
pf.bf_insns = UNCONST(dhcp_bpf_filter);
pf.bf_len = dhcp_bpf_filter_len;
- fdp = &iface->raw_fd;
+ fdp = &state->raw_fd;
}
if (ioctl(fd, BIOCSETF, &pf) == -1)
goto eexit;
return fd;
eexit:
- free(iface->buffer);
- iface->buffer = NULL;
+ free(state->buffer);
+ state->buffer = NULL;
close(fd);
return -1;
}
ssize_t
-send_raw_packet(const struct interface *iface, int protocol,
+ipv4_sendrawpacket(const struct interface *ifp, int protocol,
const void *data, ssize_t len)
{
struct iovec iov[2];
struct ether_header hw;
int fd;
+ const struct dhcp_state *state;
memset(&hw, 0, ETHER_HDR_LEN);
memset(&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
iov[0].iov_len = ETHER_HDR_LEN;
iov[1].iov_base = UNCONST(data);
iov[1].iov_len = len;
+ state = D_CSTATE(ifp);
if (protocol == ETHERTYPE_ARP)
- fd = iface->arp_fd;
+ fd = state->arp_fd;
else
- fd = iface->raw_fd;
+ fd = state->raw_fd;
return writev(fd, iov, 2);
}
/* BPF requires that we read the entire buffer.
* So we pass the buffer in the API so we can loop on >1 packet. */
ssize_t
-get_raw_packet(struct interface *iface, int protocol,
+ipv4_getrawpacket(struct interface *ifp, int protocol,
void *data, ssize_t len, int *partialcsum)
{
int fd = -1;
struct bpf_hdr packet;
ssize_t bytes;
const unsigned char *payload;
+ struct dhcp_state *state;
+ state = D_STATE(ifp);
if (protocol == ETHERTYPE_ARP)
- fd = iface->arp_fd;
+ fd = state->arp_fd;
else
- fd = iface->raw_fd;
+ fd = state->raw_fd;
if (partialcsum != NULL)
*partialcsum = 0; /* Not supported on BSD */
for (;;) {
- if (iface->buffer_len == 0) {
- bytes = read(fd, iface->buffer, iface->buffer_size);
+ if (state->buffer_len == 0) {
+ bytes = read(fd, state->buffer, state->buffer_size);
if (bytes == -1)
return errno == EAGAIN ? 0 : -1;
else if ((size_t)bytes < sizeof(packet))
return -1;
- iface->buffer_len = bytes;
- iface->buffer_pos = 0;
+ state->buffer_len = bytes;
+ state->buffer_pos = 0;
}
bytes = -1;
- memcpy(&packet, iface->buffer + iface->buffer_pos,
+ memcpy(&packet, state->buffer + state->buffer_pos,
sizeof(packet));
if (packet.bh_caplen != packet.bh_datalen)
goto next; /* Incomplete packet, drop. */
- if (iface->buffer_pos + packet.bh_caplen + packet.bh_hdrlen >
- iface->buffer_len)
+ if (state->buffer_pos + packet.bh_caplen + packet.bh_hdrlen >
+ state->buffer_len)
goto next; /* Packet beyond buffer, drop. */
- payload = iface->buffer + packet.bh_hdrlen + ETHER_HDR_LEN;
+ payload = state->buffer + packet.bh_hdrlen + ETHER_HDR_LEN;
bytes = packet.bh_caplen - ETHER_HDR_LEN;
if (bytes > len)
bytes = len;
memcpy(data, payload, bytes);
next:
- iface->buffer_pos += BPF_WORDALIGN(packet.bh_hdrlen +
+ state->buffer_pos += BPF_WORDALIGN(packet.bh_hdrlen +
packet.bh_caplen);
- if (iface->buffer_pos >= iface->buffer_len)
- iface->buffer_len = iface->buffer_pos = 0;
+ if (state->buffer_pos >= state->buffer_len)
+ state->buffer_len = state->buffer_pos = 0;
if (bytes != -1)
return bytes;
}
#include <sys/uio.h>
#include <sys/utsname.h>
+#include <net/route.h> /* For RTM_CHGADDR */
+
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
{
struct interface *ifp;
struct if_options *ifo;
+ struct dhcp_state *state;
for (ifp = ifaces; ifp; ifp = ifp->next)
if (strcmp(ifp->name, ifname) == 0 && ifp->hwlen <= hwlen) {
- ifo = ifp->state->options;
+ state = D_STATE(ifp);
+ if (state == NULL)
+ continue;
+ ifo = ifp->options;
if (!(ifo->options &
(DHCPCD_INFORM | DHCPCD_STATIC | DHCPCD_CLIENTID))
- && ifp->state->new != NULL &&
- ifp->state->new->cookie == htonl(MAGIC_COOKIE))
+ && state->new != NULL &&
+ state->new->cookie == htonl(MAGIC_COOKIE))
{
syslog(LOG_INFO,
"%s: expiring for new hardware address",
ifp->name);
- drop_dhcp(ifp, "EXPIRE");
+ dhcp_drop(ifp, "EXPIRE");
}
memcpy(ifp->hwaddr, hwaddr, hwlen);
ifp->hwlen = hwlen;
syslog(LOG_DEBUG, "%s: using hwaddr %s",
ifp->name,
hwaddr_ntoa(ifp->hwaddr, ifp->hwlen));
- ifp->state->interval = 0;
- ifp->state->nakoff = 0;
+ state->interval = 0;
+ state->nakoff = 0;
start_interface(ifp);
}
}
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2012 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
#include "config.h"
#include "common.h"
-#include "configure.h"
#include "dhcp.h"
#include "if-options.h"
+#include "ipv4.h"
#include "ipv6.h"
-#include "net.h"
#ifndef RT_ROUNDUP
#define RT_ROUNDUP(a) \
#endif
int
-init_sockets(void)
+open_sockets(void)
{
if ((socket_afnet = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
return -1;
return 0;
}
+int
+open_link_socket(void)
+{
+ int fd;
+
+#ifdef DEBUG_MEMORY
+ if (link_buf == NULL)
+ atexit(cleanup);
+#endif
+
+ fd = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (fd != -1) {
+ set_cloexec(fd);
+ set_nonblock(fd);
+ }
+ return fd;
+}
+
int
getifssid(const char *ifname, char *ssid)
{
return retval;
}
+#ifdef INET
int
if_address(const struct interface *iface, const struct in_addr *address,
const struct in_addr *netmask, const struct in_addr *broadcast,
int
if_route(const struct rt *rt, int action)
{
+ const struct dhcp_state *state;
union sockunion {
struct sockaddr sa;
struct sockaddr_in sin;
ADDSU; \
}
+ state = D_CSTATE(rt->iface);
memset(&rtm, 0, sizeof(rtm));
rtm.hdr.rtm_version = RTM_VERSION;
rtm.hdr.rtm_seq = 1;
rtm.hdr.rtm_flags = RTF_UP;
/* None interface subnet routes are static. */
if (rt->gate.s_addr != INADDR_ANY ||
- rt->net.s_addr != rt->iface->net.s_addr ||
- rt->dest.s_addr != (rt->iface->addr.s_addr & rt->iface->net.s_addr))
+ rt->net.s_addr != state->net.s_addr ||
+ rt->dest.s_addr != (state->addr.s_addr & state->net.s_addr))
rtm.hdr.rtm_flags |= RTF_STATIC;
rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
if (rt->dest.s_addr == rt->gate.s_addr &&
/* IFP here if we need it */
if (rtm.hdr.rtm_addrs & RTA_IFA)
- ADDADDR(&rt->iface->addr);
+ ADDADDR(&state->addr);
#undef ADDADDR
#undef ADDSU
retval = -1;
return retval;
}
+#endif
+#ifdef INET6
int
if_address6(const struct interface *ifp, const struct ipv6_addr *a, int action)
{
retval = -1;
return retval;
}
-
-int
-open_link_socket(void)
-{
- int fd;
-
-#ifdef DEBUG_MEMORY
- if (link_buf == NULL)
- atexit(cleanup);
#endif
- fd = socket(PF_ROUTE, SOCK_RAW, 0);
- if (fd != -1) {
- set_cloexec(fd);
- set_nonblock(fd);
- }
- return fd;
-}
-
static void
get_addrs(int type, char *cp, struct sockaddr **sa)
{
sa = (struct sockaddr *)(void *)cp;
if (sa->sa_family != AF_INET)
break;
+#ifdef INET
get_addrs(rtm->rtm_addrs, cp, rti_info);
rt.iface = NULL;
rt.next = NULL;
COPYOUT(rt.dest, rti_info[RTAX_DST]);
COPYOUT(rt.net, rti_info[RTAX_NETMASK]);
COPYOUT(rt.gate, rti_info[RTAX_GATEWAY]);
- route_deleted(&rt);
+ ipv4_routedeleted(&rt);
+#endif
break;
#ifdef RTM_CHGADDR
case RTM_CHGADDR: /* FALLTHROUGH */
sdl.sdl_alen);
break;
#endif
+#ifdef INET
case AF_INET:
case 255: /* FIXME: Why 255? */
COPYOUT(rt.dest, rti_info[RTAX_IFA]);
COPYOUT(rt.net, rti_info[RTAX_NETMASK]);
COPYOUT(rt.gate, rti_info[RTAX_BRD]);
- handle_ifa(rtm->rtm_type, ifname,
+ ipv4_handleifa(rtm->rtm_type, ifname,
&rt.dest, &rt.net, &rt.gate);
break;
+#endif
}
break;
}