{
int s;
struct ifreq ifr;
- interface_t *iface;
- unsigned char hwaddr[20];
+ interface_t *iface = NULL;
+ unsigned char *hwaddr = NULL;
int hwlen = 0;
sa_family_t family = 0;
unsigned short mtu;
strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl (s, SIOCGIFHWADDR, &ifr) == -1) {
logger (LOG_ERR, "ioctl SIOCGIFHWADDR: %s", strerror (errno));
- close (s);
- return NULL;
+ goto exit;
}
switch (ifr.ifr_hwaddr.sa_family) {
break;
default:
logger (LOG_ERR, "interface is not Ethernet, FireWire, InfiniBand or Token Ring");
- close (s);
- return NULL;
+ goto exit;
}
+ hwaddr = xmalloc (sizeof (unsigned char *) * HWADDR_LEN);
memcpy (hwaddr, ifr.ifr_hwaddr.sa_data, hwlen);
family = ifr.ifr_hwaddr.sa_family;
#else
strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl (s, SIOCSIFMETRIC, &ifr) == -1) {
logger (LOG_ERR, "ioctl SIOCSIFMETRIC: %s", strerror (errno));
- close (s);
- return NULL;
+ goto exit;
}
-
+
+ hwaddr = xmalloc (sizeof (unsigned char *) * HWADDR_LEN);
if (_do_interface (ifname, hwaddr, &hwlen, NULL, false, false) != 1) {
logger (LOG_ERR, "could not find interface %s", ifname);
- close (s);
- return NULL;
+ goto exit;
}
family = ARPHRD_ETHER;
strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl (s, SIOCGIFMTU, &ifr) == -1) {
logger (LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror (errno));
- close (s);
- return NULL;
+ goto exit;
}
if (ifr.ifr_mtu < MTU_MIN) {
strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl (s, SIOCSIFMTU, &ifr) == -1) {
logger (LOG_ERR, "ioctl SIOCSIFMTU,: %s", strerror (errno));
- close (s);
- return NULL;
+ goto exit;
}
}
mtu = ifr.ifr_mtu;
#endif
if (ioctl (s, SIOCGIFFLAGS, &ifr) == -1) {
logger (LOG_ERR, "ioctl SIOCGIFFLAGS: %s", strerror (errno));
- close (s);
- return NULL;
+ goto exit;
}
if (! (ifr.ifr_flags & IFF_UP) || ! (ifr.ifr_flags & IFF_RUNNING)) {
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
if (ioctl (s, SIOCSIFFLAGS, &ifr) == -1) {
logger (LOG_ERR, "ioctl SIOCSIFFLAGS: %s", strerror (errno));
- close (s);
- return NULL;
+ goto exit;
}
}
- close (s);
-
iface = xmalloc (sizeof (interface_t));
memset (iface, 0, sizeof (interface_t));
strlcpy (iface->name, ifname, IF_NAMESIZE);
/* 0 is a valid fd, so init to -1 */
iface->fd = -1;
+exit:
+ close (s);
+ free (hwaddr);
return iface;
}
gateway.s_addr == INADDR_ANY)
{
/* Make us a link layer socket */
- unsigned char hwaddr[HWADDR_LEN];
+ unsigned char *hwaddr;
int hwlen = 0;
if (netmask.s_addr == INADDR_BROADCAST)
rtm.hdr.rtm_flags |= RTF_HOST;
+ hwaddr = xmalloc (sizeof (unsigned char *) * HWADDR_LEN);
_do_interface (ifname, hwaddr, &hwlen, NULL, false, false);
memset (&su, 0, sizeof (struct sockaddr_storage));
su.sdl.sdl_len = sizeof (struct sockaddr_dl);
l = SA_SIZE (&(su.sa));
memcpy (bp, &su, l);
bp += l;
+ free (hwaddr);
} else {
rtm.hdr.rtm_flags |= RTF_GATEWAY;
ADDADDR (gateway);
This blatently taken from libnetlink.c from the iproute2 package
which is the only good source of netlink code.
*/
+#define BUFFERLEN 256
static int send_netlink(struct nlmsghdr *hdr)
{
int s;
struct iovec iov;
struct msghdr msg;
static unsigned int seq;
- char buffer[256];
+ char *buffer;
int bytes;
union
{
return -1;
}
- memset (buffer, 0, sizeof (buffer));
+ buffer = xmalloc (sizeof (char *) * BUFFERLEN);
+ memset (buffer, 0, BUFFERLEN);
iov.iov_base = buffer;
while (1) {
- iov.iov_len = sizeof (buffer);
+ iov.iov_len = BUFFERLEN;
bytes = recvmsg (s, &msg, 0);
if (bytes == -1) {
errno = -err->error;
if (errno == 0) {
close (s);
+ free (buffer);
return 0;
}
eexit:
close (s);
+ free (buffer);
return -1;
}
return 0;
}
+struct nlma
+{
+ struct nlmsghdr hdr;
+ struct ifaddrmsg ifa;
+ char buffer[64];
+};
+
+struct nlmr
+{
+ struct nlmsghdr hdr;
+ struct rtmsg rt;
+ char buffer[256];
+};
+
static int do_address(const char *ifname,
struct in_addr address, struct in_addr netmask,
struct in_addr broadcast, int del)
{
- struct
- {
- struct nlmsghdr hdr;
- struct ifaddrmsg ifa;
- char buffer[64];
- }
- nlm;
+ struct nlma *nlm;
+ int retval;
if (!ifname)
return -1;
- memset (&nlm, 0, sizeof (nlm));
+ nlm = xmalloc (sizeof (struct nlma));
+ memset (nlm, 0, sizeof (struct nlma));
- nlm.hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
- nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
+ nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
+ nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
if (! del)
- nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
- nlm.hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
- if (! (nlm.ifa.ifa_index = if_nametoindex (ifname))) {
+ nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
+ nlm->hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
+ if (! (nlm->ifa.ifa_index = if_nametoindex (ifname))) {
logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
ifname);
+ free (nlm);
return -1;
}
- nlm.ifa.ifa_family = AF_INET;
+ nlm->ifa.ifa_family = AF_INET;
- nlm.ifa.ifa_prefixlen = inet_ntocidr (netmask);
+ nlm->ifa.ifa_prefixlen = inet_ntocidr (netmask);
/* This creates the aliased interface */
- add_attr_l (&nlm.hdr, sizeof (nlm), IFA_LABEL, ifname, strlen (ifname) + 1);
+ add_attr_l (&nlm->hdr, sizeof (struct nlma), IFA_LABEL,
+ ifname, strlen (ifname) + 1);
- add_attr_l (&nlm.hdr, sizeof (nlm), IFA_LOCAL, &address.s_addr,
- sizeof (address.s_addr));
+ add_attr_l (&nlm->hdr, sizeof (struct nlma), IFA_LOCAL,
+ &address.s_addr, sizeof (address.s_addr));
if (! del)
- add_attr_l (&nlm.hdr, sizeof (nlm), IFA_BROADCAST, &broadcast.s_addr,
- sizeof (broadcast.s_addr));
+ add_attr_l (&nlm->hdr, sizeof (struct nlma), IFA_BROADCAST,
+ &broadcast.s_addr, sizeof (broadcast.s_addr));
- return send_netlink (&nlm.hdr);
+ retval = send_netlink (&nlm->hdr);
+ free (nlm);
+ return retval;
}
static int do_route (const char *ifname,
struct in_addr gateway,
int metric, int change, int del)
{
+ struct nlmr *nlm;
unsigned int ifindex;
- struct
- {
- struct nlmsghdr hdr;
- struct rtmsg rt;
- char buffer[256];
- }
- nlm;
+ int retval;
if (! ifname)
return -1;
log_route (destination, netmask, gateway, metric, change, del);
- memset (&nlm, 0, sizeof (nlm));
+ if (! (ifindex = if_nametoindex (ifname))) {
+ logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
+ ifname);
+ return -1;
+ }
+
+ nlm = xmalloc (sizeof (struct nlmr));
+ memset (nlm, 0, sizeof (struct nlmr));
- nlm.hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
+ nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
if (change)
- nlm.hdr.nlmsg_flags = NLM_F_REPLACE;
+ nlm->hdr.nlmsg_flags = NLM_F_REPLACE;
else if (! del)
- nlm.hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
- nlm.hdr.nlmsg_flags |= NLM_F_REQUEST;
- nlm.hdr.nlmsg_type = del ? RTM_DELROUTE : RTM_NEWROUTE;
- nlm.rt.rtm_family = AF_INET;
- nlm.rt.rtm_table = RT_TABLE_MAIN;
+ nlm->hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
+ nlm->hdr.nlmsg_flags |= NLM_F_REQUEST;
+ nlm->hdr.nlmsg_type = del ? RTM_DELROUTE : RTM_NEWROUTE;
+ nlm->rt.rtm_family = AF_INET;
+ nlm->rt.rtm_table = RT_TABLE_MAIN;
if (del)
- nlm.rt.rtm_scope = RT_SCOPE_NOWHERE;
+ nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
else {
- nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
- nlm.rt.rtm_protocol = RTPROT_BOOT;
+ nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
+ nlm->rt.rtm_protocol = RTPROT_BOOT;
if (netmask.s_addr == INADDR_BROADCAST ||
gateway.s_addr == INADDR_ANY)
- nlm.rt.rtm_scope = RT_SCOPE_LINK;
+ nlm->rt.rtm_scope = RT_SCOPE_LINK;
else
- nlm.rt.rtm_scope = RT_SCOPE_UNIVERSE;
- nlm.rt.rtm_type = RTN_UNICAST;
+ nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
+ nlm->rt.rtm_type = RTN_UNICAST;
}
- nlm.rt.rtm_dst_len = inet_ntocidr (netmask);
- add_attr_l (&nlm.hdr, sizeof (nlm), RTA_DST, &destination.s_addr,
- sizeof (destination.s_addr));
+ nlm->rt.rtm_dst_len = inet_ntocidr (netmask);
+ add_attr_l (&nlm->hdr, sizeof (struct nlmr), RTA_DST,
+ &destination.s_addr, sizeof (destination.s_addr));
if (netmask.s_addr != INADDR_BROADCAST &&
destination.s_addr != gateway.s_addr)
- add_attr_l (&nlm.hdr, sizeof (nlm), RTA_GATEWAY, &gateway.s_addr,
- sizeof (gateway.s_addr));
+ add_attr_l (&nlm->hdr, sizeof (struct nlmr), RTA_GATEWAY,
+ &gateway.s_addr, sizeof (gateway.s_addr));
- if (! (ifindex = if_nametoindex (ifname))) {
- logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
- ifname);
- return -1;
- }
+ add_attr_32 (&nlm->hdr, sizeof (struct nlmr), RTA_OIF, ifindex);
+ add_attr_32 (&nlm->hdr, sizeof (struct nlmr), RTA_PRIORITY, metric);
- add_attr_32 (&nlm.hdr, sizeof (nlm), RTA_OIF, ifindex);
- add_attr_32 (&nlm.hdr, sizeof (nlm), RTA_PRIORITY, metric);
-
- return send_netlink (&nlm.hdr);
+ retval = send_netlink (&nlm->hdr);
+ free (nlm);
+ return retval;
}
#else