5 #include "ns3/assert.h"
7 #include "ns3/ipv4-address.h"
12 #include <netinet/in.h>
13 #include <sys/types.h>
15 #include <linux/netlink.h>
16 #include <linux/rtnetlink.h>
29 static struct hostent host;
31 static char *alias_end = 0;
32 static char *addr_list[2];
35 Ipv4Address ipv4 = Ipv4Address (name);
36 addr = htonl (ipv4.Get ());
41 host.h_name = (
char *)name;
42 host.h_addrtype = AF_INET;
43 host.h_aliases = &alias_end;
45 host.h_addr_list = addr_list;
46 addr_list[0] = (
char *)&addr;
52 NS_ASSERT (af == AF_INET);
56 const struct addrinfo *hints,
57 struct addrinfo **res)
59 NS_LOG_FUNCTION (
Current () <<
UtilsGetNodeId () << ((NULL == node) ?
"" : node) << ((NULL == service) ?
"" : service) << hints << res);
61 struct addrinfo *tmp = 0;
62 int status = ::getaddrinfo (node, service, hints, &tmp);
64 struct addrinfo *cur, *prev, *head;
67 for (cur = tmp; cur != 0; cur = cur->ai_next)
69 struct addrinfo *copy = (
struct addrinfo*)
dce_malloc (
sizeof(
struct addrinfo));
70 memcpy (copy, cur,
sizeof (
struct addrinfo));
71 copy->ai_addr = (
struct sockaddr*)
dce_malloc (cur->ai_addrlen);
72 if (cur->ai_canonname != 0)
74 copy->ai_canonname =
dce_strdup (cur->ai_canonname);
78 copy->ai_canonname = 0;
80 memcpy (copy->ai_addr, cur->ai_addr, cur->ai_addrlen);
103 ::freeaddrinfo (tmp);
110 struct addrinfo *cur, *next;
111 for (cur = res; cur != 0; cur = next)
115 if (cur->ai_canonname != 0)
126 return ::gai_strerror (errcode);
129 socklen_t hostlen,
char *serv, socklen_t servlen,
unsigned int flags)
133 if ((0 == sa) || (0 == salen))
139 switch (sa->sa_family)
143 if (salen <
sizeof (
struct sockaddr_in))
148 const struct sockaddr_in *inAddr = (
const struct sockaddr_in *) sa;
152 int r =
snprintf (serv, servlen,
"%d", htons (inAddr->sin_port));
154 if (r > (
int)servlen)
166 Ipv4Address ipv4 = Ipv4Address (htonl (inAddr->sin_addr.s_addr));
167 std::ostringstream oss;
170 int r =
snprintf (host, hostlen,
"%s", oss.str ().c_str ());
172 if (r > (
int)hostlen)
198 fprintf (*
Current ()->process->pstderr,
"%s : %s\n",
string,
"ERROR");
226 unsigned char sll_addr[24];
237 struct sockaddr_in s4;
238 struct sockaddr_in6 s6;
239 } addr, netmask, broadaddr;
240 char name[IF_NAMESIZE + 1];
242 #define PAGE_SIZE 4096
247 struct sockaddr_nl snl;
249 struct sockaddr_nl nladdr;
250 struct nlmsghdr *nlmh;
260 memset (&snl, 0,
sizeof snl);
261 snl.nl_family = AF_NETLINK;
263 memset (&req, 0,
sizeof req);
264 req.nlh.nlmsg_len =
sizeof req;
265 req.nlh.nlmsg_type = type;
266 req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
267 req.nlh.nlmsg_pid = h->
pid;
268 req.nlh.nlmsg_seq = ++h->
seq;
269 req.g.rtgen_family = AF_UNSPEC;
272 (
struct sockaddr *) &snl,
sizeof snl);
294 (
void *) &nladdr,
sizeof (nladdr),
306 if (nladdr.nl_pid != 0)
311 if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
317 size_t remaining_len = read_len;
318 for (nlmh = (
struct nlmsghdr *) buf;
319 NLMSG_OK (nlmh, remaining_len);
320 nlmh = (
struct nlmsghdr *) NLMSG_NEXT (nlmh, remaining_len))
322 if ((pid_t) nlmh->nlmsg_pid != h->
pid
323 || nlmh->nlmsg_seq != h->
seq)
329 if (nlmh->nlmsg_type == NLMSG_DONE)
335 if (nlmh->nlmsg_type == NLMSG_ERROR)
337 struct nlmsgerr *nlerr = (
struct nlmsgerr *) NLMSG_DATA (nlmh);
338 if (nlmh->nlmsg_len < NLMSG_LENGTH (
sizeof (
struct nlmsgerr)))
344 errno = -nlerr->error;
359 if (nlm_next == NULL)
363 nlm_next->
next = NULL;
364 nlm_next->
nlh = (
struct nlmsghdr *)memcpy (nlm_next + 1, buf, read_len);
365 nlm_next->
size = read_len;
391 for (i = 0; i < max; i++)
398 ifas[i - 1].
ifa.ifa_next = &ifas[i].
ifa;
402 else if (map[i] == index)
416 int saved_errno =
errno;
442 struct sockaddr_nl nladdr;
445 unsigned int i, newlink, newaddr, newaddr_idx;
446 int *map_newlink_data;
447 size_t ifa_data_size = 0;
452 nh.
fd =
dce_socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
459 memset (&nladdr, 0,
sizeof (nladdr));
460 nladdr.nl_family = AF_NETLINK;
461 if (
dce_bind (nh.
fd, (
struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
467 socklen_t addr_len =
sizeof (nladdr);
474 nh.
pid = nladdr.nl_pid;
494 newlink = newaddr = 0;
497 struct nlmsghdr *nlh;
498 size_t size = nlp->
size;
500 if (nlp->
nlh == NULL)
507 for (nlh = nlp->
nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
510 if ((pid_t) nlh->nlmsg_pid != nh.
pid || nlh->nlmsg_seq != nlp->
seq)
515 if (nlh->nlmsg_type == NLMSG_DONE)
520 if (nlh->nlmsg_type == RTM_NEWLINK)
525 struct ifinfomsg *ifim = (
struct ifinfomsg *) NLMSG_DATA (nlh);
526 struct rtattr *rta = IFLA_RTA (ifim);
527 size_t rtasize = IFLA_PAYLOAD (nlh);
529 while (RTA_OK (rta, rtasize))
531 size_t rta_payload = RTA_PAYLOAD (rta);
533 if (rta->rta_type == IFLA_STATS)
535 ifa_data_size += rta_payload;
540 rta = RTA_NEXT (rta, rtasize);
545 else if (nlh->nlmsg_type == RTM_NEWADDR)
553 if ((newlink + newaddr) == 0)
571 map_newlink_data = (
int *)alloca (newlink *
sizeof (
int));
572 memset (map_newlink_data,
'\xff', newlink *
sizeof (
int));
574 ifa_data_ptr = (
char *) &ifas[newlink + newaddr];
580 struct nlmsghdr *nlh;
581 size_t size = nlp->
size;
583 if (nlp->
nlh == NULL)
592 for (nlh = nlp->
nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
597 if ((pid_t) nlh->nlmsg_pid != nh.
pid || nlh->nlmsg_seq != nlp->
seq)
602 if (nlh->nlmsg_type == NLMSG_DONE)
607 if (nlh->nlmsg_type == RTM_NEWLINK)
611 struct ifinfomsg *ifim = (
struct ifinfomsg *) NLMSG_DATA (nlh);
612 struct rtattr *rta = IFLA_RTA (ifim);
613 size_t rtasize = IFLA_PAYLOAD (nlh);
618 ifa_index =
map_newlink (ifim->ifi_index - 1, ifas,
619 map_newlink_data, newlink);
620 ifas[ifa_index].
ifa.ifa_flags = ifim->ifi_flags;
622 while (RTA_OK (rta, rtasize))
624 char *rta_data = (
char *)RTA_DATA (rta);
625 size_t rta_payload = RTA_PAYLOAD (rta);
627 switch (rta->rta_type)
630 if (rta_payload <=
sizeof (ifas[ifa_index].addr))
634 (
char *) rta_data, rta_payload);
640 ifas[ifa_index].
ifa.ifa_addr
641 = &ifas[ifa_index].
addr.
sa;
646 if (rta_payload <=
sizeof (ifas[ifa_index].broadaddr))
649 memcpy (ifas[ifa_index].broadaddr.
sl.
sll_addr,
650 (
char *) rta_data, rta_payload);
657 ifas[ifa_index].
ifa.ifa_broadaddr
663 if ((rta_payload + 1) <=
sizeof (ifas[ifa_index].name))
665 ifas[ifa_index].
ifa.ifa_name = ifas[ifa_index].
name;
666 *(
char *) __mempcpy (ifas[ifa_index].name, rta_data,
672 ifas[ifa_index].
ifa.ifa_data = ifa_data_ptr;
673 ifa_data_ptr += rta_payload;
674 memcpy (ifas[ifa_index].ifa.ifa_data, rta_data,
690 rta = RTA_NEXT (rta, rtasize);
693 else if (nlh->nlmsg_type == RTM_NEWADDR)
695 struct ifaddrmsg *ifam = (
struct ifaddrmsg *) NLMSG_DATA (nlh);
696 struct rtattr *rta = IFA_RTA (ifam);
697 size_t rtasize = IFA_PAYLOAD (nlh);
703 ifa_index = newlink + newaddr_idx;
704 ifas[ifa_index].
ifa.ifa_flags
706 map_newlink_data, newlink)].
ifa.ifa_flags;
709 ifas[ifa_index - 1].
ifa.ifa_next = &ifas[ifa_index].
ifa;
713 while (RTA_OK (rta, rtasize))
715 char *rta_data = (
char *)RTA_DATA (rta);
716 size_t rta_payload = RTA_PAYLOAD (rta);
718 switch (rta->rta_type)
724 if (ifas[ifa_index].ifa.ifa_addr != NULL)
732 ifas[ifa_index].
ifa.ifa_broadaddr
738 ifas[ifa_index].
ifa.ifa_addr
739 = &ifas[ifa_index].
addr.
sa;
740 sa = &ifas[ifa_index].
addr.
sa;
743 sa->sa_family = ifam->ifa_family;
745 switch (ifam->ifa_family)
749 if (rta_payload == 4)
751 memcpy (&((
struct sockaddr_in *) sa)->sin_addr,
752 rta_data, rta_payload);
758 if (rta_payload == 16)
760 memcpy (&((
struct sockaddr_in6 *) sa)->sin6_addr,
761 rta_data, rta_payload);
762 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
763 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
765 ((
struct sockaddr_in6 *) sa)->sin6_scope_id
772 if (rta_payload <=
sizeof (ifas[ifa_index].addr))
774 memcpy (sa->sa_data, rta_data, rta_payload);
782 if (ifas[ifa_index].ifa.ifa_addr != NULL)
788 ifas[ifa_index].
ifa.ifa_broadaddr
790 memset (&ifas[ifa_index].addr,
'\0',
791 sizeof (ifas[ifa_index].addr));
794 ifas[ifa_index].
ifa.ifa_addr = &ifas[ifa_index].
addr.
sa;
795 ifas[ifa_index].
ifa.ifa_addr->sa_family
798 switch (ifam->ifa_family)
802 if (rta_payload == 4)
804 memcpy (&ifas[ifa_index].addr.
s4.sin_addr,
805 rta_data, rta_payload);
811 if (rta_payload == 16)
813 memcpy (&ifas[ifa_index].addr.
s6.sin6_addr,
814 rta_data, rta_payload);
815 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
816 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
818 ifas[ifa_index].
addr.
s6.sin6_scope_id =
825 if (rta_payload <=
sizeof (ifas[ifa_index].addr))
827 memcpy (ifas[ifa_index].addr.
sa.sa_data,
828 rta_data, rta_payload);
836 if (ifas[ifa_index].ifa.ifa_broadaddr != NULL)
838 memset (&ifas[ifa_index].broadaddr,
'\0',
839 sizeof (ifas[ifa_index].broadaddr));
842 ifas[ifa_index].
ifa.ifa_broadaddr
844 ifas[ifa_index].
ifa.ifa_broadaddr->sa_family
847 switch (ifam->ifa_family)
851 if (rta_payload == 4)
853 memcpy (&ifas[ifa_index].broadaddr.
s4.sin_addr,
854 rta_data, rta_payload);
860 if (rta_payload == 16)
862 memcpy (&ifas[ifa_index].broadaddr.
s6.sin6_addr,
863 rta_data, rta_payload);
864 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
865 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
874 if (rta_payload <=
sizeof (ifas[ifa_index].addr))
876 memcpy (&ifas[ifa_index].broadaddr.
sa.sa_data,
877 rta_data, rta_payload);
884 if (rta_payload + 1 <=
sizeof (ifas[ifa_index].name))
886 ifas[ifa_index].
ifa.ifa_name = ifas[ifa_index].
name;
887 *(
char *) __mempcpy (ifas[ifa_index].name, rta_data,
904 rta = RTA_NEXT (rta, rtasize);
909 if (ifas[ifa_index].ifa.ifa_name == NULL)
911 ifas[ifa_index].
ifa.ifa_name
913 map_newlink_data, newlink)].
ifa.ifa_name;
917 if (ifas[ifa_index].ifa.ifa_addr
918 && ifas[ifa_index].
ifa.ifa_addr->sa_family != AF_UNSPEC
919 && ifas[ifa_index].
ifa.ifa_addr->sa_family != AF_PACKET)
921 uint32_t max_prefixlen = 0;
924 ifas[ifa_index].
ifa.ifa_netmask
927 switch (ifas[ifa_index].ifa.ifa_addr->sa_family)
930 cp = (
char *) &ifas[ifa_index].netmask.
s4.sin_addr;
935 cp = (
char *) &ifas[ifa_index].
netmask.
s6.sin6_addr;
940 ifas[ifa_index].
ifa.ifa_netmask->sa_family
941 = ifas[ifa_index].
ifa.ifa_addr->sa_family;
946 unsigned int preflen;
948 if ((max_prefixlen > 0)
949 && (ifam->ifa_prefixlen > max_prefixlen))
951 preflen = max_prefixlen;
955 preflen = ifam->ifa_prefixlen;
958 for (i = 0; i < (preflen / 8); i++)
963 c <<= (8 - (preflen % 8));
971 NS_ASSERT (ifa_data_ptr <= (
char *) &ifas[newlink + newaddr] + ifa_data_size);
975 for (i = 0; i < newlink; ++i)
977 if (map_newlink_data[i] == -1)
981 ifas[i - 1].
ifa.ifa_next = &ifas[newlink].
ifa;
985 if (i == 0 && newlink > 0)
993 *ifap = &ifas[0].
ifa;