PUD: add plugin
[olsrd.git] / lib / pud / src / netTools.c
1 #include "netTools.h"
2
3 /* Plugin includes */
4 #include "pud.h"
5
6 /* OLSR includes */
7
8 /* System includes */
9 #include <assert.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <sys/ioctl.h>
13 #include <errno.h>
14 #include <unistd.h>
15
16 /**
17  Determine whether an IP address (v4 or v6) is a multicast address.
18
19  @param addressFamily
20  The address family (AF_INET or AF_INET6)
21  @param addr
22  An IP address (v4 or v6)
23
24  @return
25  - true when the address is a multicast address
26  - false otherwise
27  */
28 bool isMulticast(int addressFamily, union olsr_sockaddr *addr) {
29         assert(addr != NULL);
30         assert((addressFamily == AF_INET) || (addressFamily == AF_INET6));
31
32         if (addressFamily == AF_INET) {
33                 return IN_MULTICAST(ntohl(addr->in4.sin_addr.s_addr));
34         }
35
36         return IN6_IS_ADDR_MULTICAST(&addr->in6.sin6_addr);
37 }
38
39 /**
40  Get the hardware address (MAC) of an interface
41
42  @param ifName
43  the name of the interface
44  @param family
45  the protocol family (AF_INET or AF_INET6)
46  @param ifr
47  the buffer in which to write the hardware address (MAC)
48
49  @return
50  - the pointer to the hardware address (inside ifr)
51  - NULL on failure
52  */
53 unsigned char * getHardwareAddress(const char * ifName, int family,
54                 struct ifreq *ifr) {
55         int fd;
56         int cpySize;
57
58         assert(ifName != NULL);
59         assert(strlen(ifName) < IFHWADDRLEN);
60         assert((family == AF_INET) || (family == AF_INET6));
61         assert(ifr != NULL);
62
63         fd = socket(family, SOCK_DGRAM, 0);
64
65         ifr->ifr_addr.sa_family = family;
66         memset(ifr->ifr_name, 0, sizeof(ifr->ifr_name));
67         cpySize = (strlen(ifName) < sizeof(ifr->ifr_name)) ? strlen(ifName)
68                         : sizeof(ifr->ifr_name);
69         strncpy(ifr->ifr_name, ifName, cpySize);
70
71         errno = 0;
72         if (ioctl(fd, SIOCGIFHWADDR, ifr) < 0) {
73                 pudError(true, "%s@%u: ioctl(SIOCGIFHWADDR) error", __FILE__, __LINE__);
74                 close(fd);
75                 return NULL;
76         }
77
78         close(fd);
79
80         return (unsigned char *) &ifr->ifr_hwaddr.sa_data[0];
81 }