xref: /aosp_15_r20/external/webrtc/rtc_base/mac_ifaddrs_converter.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include <net/if.h>
12*d9f75844SAndroid Build Coastguard Worker #include <sys/ioctl.h>
13*d9f75844SAndroid Build Coastguard Worker #include <unistd.h>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ifaddrs_converter.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker #if !defined(WEBRTC_IOS)
22*d9f75844SAndroid Build Coastguard Worker #include <net/if_media.h>
23*d9f75844SAndroid Build Coastguard Worker #include <netinet/in_var.h>
24*d9f75844SAndroid Build Coastguard Worker #else  // WEBRTC_IOS
25*d9f75844SAndroid Build Coastguard Worker #define SCOPE6_ID_MAX 16
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker struct in6_addrlifetime {
28*d9f75844SAndroid Build Coastguard Worker   time_t ia6t_expire;    /* valid lifetime expiration time */
29*d9f75844SAndroid Build Coastguard Worker   time_t ia6t_preferred; /* preferred lifetime expiration time */
30*d9f75844SAndroid Build Coastguard Worker   u_int32_t ia6t_vltime; /* valid lifetime */
31*d9f75844SAndroid Build Coastguard Worker   u_int32_t ia6t_pltime; /* prefix lifetime */
32*d9f75844SAndroid Build Coastguard Worker };
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker struct in6_ifstat {
35*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_receive;      /* # of total input datagram */
36*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_hdrerr;       /* # of datagrams with invalid hdr */
37*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_toobig;       /* # of datagrams exceeded MTU */
38*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_noroute;      /* # of datagrams with no route */
39*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_addrerr;      /* # of datagrams with invalid dst */
40*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_protounknown; /* # of datagrams with unknown proto */
41*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: increment on final dst if */
42*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_truncated;    /* # of truncated datagrams */
43*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_discard;      /* # of discarded datagrams */
44*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: fragment timeout is not here */
45*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_deliver;      /* # of datagrams delivered to ULP */
46*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: increment on final dst if */
47*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_forward;     /* # of datagrams forwarded */
48*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: increment on outgoing if */
49*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_request;     /* # of outgoing datagrams from ULP */
50*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: does not include forwrads */
51*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_discard;     /* # of discarded datagrams */
52*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_fragok;      /* # of datagrams fragmented */
53*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_fragfail;    /* # of datagrams failed on fragment */
54*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_fragcreat;   /* # of fragment datagrams */
55*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: this is # after fragment */
56*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_reass_reqd;      /* # of incoming fragmented packets */
57*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: increment on final dst if */
58*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_reass_ok;        /* # of reassembled packets */
59*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: this is # after reass */
60*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: increment on final dst if */
61*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_reass_fail;      /* # of reass failures */
62*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: may not be packet count */
63*d9f75844SAndroid Build Coastguard Worker                                  /* NOTE: increment on final dst if */
64*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_mcast;        /* # of inbound multicast datagrams */
65*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_mcast;       /* # of outbound multicast datagrams */
66*d9f75844SAndroid Build Coastguard Worker };
67*d9f75844SAndroid Build Coastguard Worker struct icmp6_ifstat {
68*d9f75844SAndroid Build Coastguard Worker   /*
69*d9f75844SAndroid Build Coastguard Worker    * Input statistics
70*d9f75844SAndroid Build Coastguard Worker    */
71*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInMsgs, total # of input messages */
72*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_msg;
73*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInErrors, # of input error messages */
74*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_error;
75*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */
76*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_dstunreach;
77*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInAdminProhibs, # of input admin. prohibited errs */
78*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_adminprohib;
79*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */
80*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_timeexceed;
81*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInParmProblems, # of input parameter problem errors */
82*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_paramprob;
83*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */
84*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_pkttoobig;
85*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInEchos, # of input echo requests */
86*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_echo;
87*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInEchoReplies, # of input echo replies */
88*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_echoreply;
89*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInRouterSolicits, # of input router solicitations */
90*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_routersolicit;
91*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */
92*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_routeradvert;
93*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */
94*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_neighborsolicit;
95*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advs. */
96*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_neighboradvert;
97*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInRedirects, # of input redirects */
98*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_redirect;
99*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */
100*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_mldquery;
101*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */
102*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_mldreport;
103*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpInGroupMembReductions, # of input MLD done */
104*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_in_mlddone;
105*d9f75844SAndroid Build Coastguard Worker 
106*d9f75844SAndroid Build Coastguard Worker   /*
107*d9f75844SAndroid Build Coastguard Worker    * Output statistics. We should solve unresolved routing problem...
108*d9f75844SAndroid Build Coastguard Worker    */
109*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutMsgs, total # of output messages */
110*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_msg;
111*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutErrors, # of output error messages */
112*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_error;
113*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */
114*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_dstunreach;
115*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutAdminProhibs, # of output admin. prohibited errs */
116*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_adminprohib;
117*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */
118*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_timeexceed;
119*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */
120*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_paramprob;
121*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */
122*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_pkttoobig;
123*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutEchos, # of output echo requests */
124*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_echo;
125*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutEchoReplies, # of output echo replies */
126*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_echoreply;
127*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */
128*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_routersolicit;
129*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutRouterAdvertisements, # of output router advs. */
130*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_routeradvert;
131*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */
132*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_neighborsolicit;
133*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advs. */
134*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_neighboradvert;
135*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutRedirects, # of output redirects */
136*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_redirect;
137*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */
138*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_mldquery;
139*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */
140*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_mldreport;
141*d9f75844SAndroid Build Coastguard Worker   /* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */
142*d9f75844SAndroid Build Coastguard Worker   u_quad_t ifs6_out_mlddone;
143*d9f75844SAndroid Build Coastguard Worker };
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker struct in6_ifreq {
146*d9f75844SAndroid Build Coastguard Worker   char ifr_name[IFNAMSIZ];
147*d9f75844SAndroid Build Coastguard Worker   union {
148*d9f75844SAndroid Build Coastguard Worker     struct sockaddr_in6 ifru_addr;
149*d9f75844SAndroid Build Coastguard Worker     struct sockaddr_in6 ifru_dstaddr;
150*d9f75844SAndroid Build Coastguard Worker     int ifru_flags;
151*d9f75844SAndroid Build Coastguard Worker     int ifru_flags6;
152*d9f75844SAndroid Build Coastguard Worker     int ifru_metric;
153*d9f75844SAndroid Build Coastguard Worker     int ifru_intval;
154*d9f75844SAndroid Build Coastguard Worker     caddr_t ifru_data;
155*d9f75844SAndroid Build Coastguard Worker     struct in6_addrlifetime ifru_lifetime;
156*d9f75844SAndroid Build Coastguard Worker     struct in6_ifstat ifru_stat;
157*d9f75844SAndroid Build Coastguard Worker     struct icmp6_ifstat ifru_icmp6stat;
158*d9f75844SAndroid Build Coastguard Worker     u_int32_t ifru_scope_id[SCOPE6_ID_MAX];
159*d9f75844SAndroid Build Coastguard Worker   } ifr_ifru;
160*d9f75844SAndroid Build Coastguard Worker };
161*d9f75844SAndroid Build Coastguard Worker 
162*d9f75844SAndroid Build Coastguard Worker #define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq)
163*d9f75844SAndroid Build Coastguard Worker 
164*d9f75844SAndroid Build Coastguard Worker #define IN6_IFF_ANYCAST 0x0001    /* anycast address */
165*d9f75844SAndroid Build Coastguard Worker #define IN6_IFF_TENTATIVE 0x0002  /* tentative address */
166*d9f75844SAndroid Build Coastguard Worker #define IN6_IFF_DUPLICATED 0x0004 /* DAD detected duplicate */
167*d9f75844SAndroid Build Coastguard Worker #define IN6_IFF_DETACHED 0x0008   /* may be detached from the link */
168*d9f75844SAndroid Build Coastguard Worker #define IN6_IFF_DEPRECATED 0x0010 /* deprecated address */
169*d9f75844SAndroid Build Coastguard Worker #define IN6_IFF_TEMPORARY 0x0080  /* temporary (anonymous) address. */
170*d9f75844SAndroid Build Coastguard Worker 
171*d9f75844SAndroid Build Coastguard Worker #endif  // WEBRTC_IOS
172*d9f75844SAndroid Build Coastguard Worker 
173*d9f75844SAndroid Build Coastguard Worker namespace rtc {
174*d9f75844SAndroid Build Coastguard Worker 
175*d9f75844SAndroid Build Coastguard Worker namespace {
176*d9f75844SAndroid Build Coastguard Worker 
177*d9f75844SAndroid Build Coastguard Worker class IPv6AttributesGetter {
178*d9f75844SAndroid Build Coastguard Worker  public:
179*d9f75844SAndroid Build Coastguard Worker   IPv6AttributesGetter();
180*d9f75844SAndroid Build Coastguard Worker   virtual ~IPv6AttributesGetter();
181*d9f75844SAndroid Build Coastguard Worker   bool IsInitialized() const;
182*d9f75844SAndroid Build Coastguard Worker   bool GetIPAttributes(const char* ifname,
183*d9f75844SAndroid Build Coastguard Worker                        const sockaddr* sock_addr,
184*d9f75844SAndroid Build Coastguard Worker                        int* native_attributes);
185*d9f75844SAndroid Build Coastguard Worker 
186*d9f75844SAndroid Build Coastguard Worker  private:
187*d9f75844SAndroid Build Coastguard Worker   // on MAC or IOS, we have to use ioctl with a socket to query an IPv6
188*d9f75844SAndroid Build Coastguard Worker   // interface's attribute.
189*d9f75844SAndroid Build Coastguard Worker   int ioctl_socket_;
190*d9f75844SAndroid Build Coastguard Worker };
191*d9f75844SAndroid Build Coastguard Worker 
IPv6AttributesGetter()192*d9f75844SAndroid Build Coastguard Worker IPv6AttributesGetter::IPv6AttributesGetter()
193*d9f75844SAndroid Build Coastguard Worker     : ioctl_socket_(
194*d9f75844SAndroid Build Coastguard Worker           socket(AF_INET6, SOCK_DGRAM, 0 /* unspecified protocol */)) {
195*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_GE(ioctl_socket_, 0);
196*d9f75844SAndroid Build Coastguard Worker }
197*d9f75844SAndroid Build Coastguard Worker 
IsInitialized() const198*d9f75844SAndroid Build Coastguard Worker bool IPv6AttributesGetter::IsInitialized() const {
199*d9f75844SAndroid Build Coastguard Worker   return ioctl_socket_ >= 0;
200*d9f75844SAndroid Build Coastguard Worker }
201*d9f75844SAndroid Build Coastguard Worker 
~IPv6AttributesGetter()202*d9f75844SAndroid Build Coastguard Worker IPv6AttributesGetter::~IPv6AttributesGetter() {
203*d9f75844SAndroid Build Coastguard Worker   if (!IsInitialized()) {
204*d9f75844SAndroid Build Coastguard Worker     return;
205*d9f75844SAndroid Build Coastguard Worker   }
206*d9f75844SAndroid Build Coastguard Worker   close(ioctl_socket_);
207*d9f75844SAndroid Build Coastguard Worker }
208*d9f75844SAndroid Build Coastguard Worker 
GetIPAttributes(const char * ifname,const sockaddr * sock_addr,int * native_attributes)209*d9f75844SAndroid Build Coastguard Worker bool IPv6AttributesGetter::GetIPAttributes(const char* ifname,
210*d9f75844SAndroid Build Coastguard Worker                                            const sockaddr* sock_addr,
211*d9f75844SAndroid Build Coastguard Worker                                            int* native_attributes) {
212*d9f75844SAndroid Build Coastguard Worker   if (!IsInitialized()) {
213*d9f75844SAndroid Build Coastguard Worker     return false;
214*d9f75844SAndroid Build Coastguard Worker   }
215*d9f75844SAndroid Build Coastguard Worker 
216*d9f75844SAndroid Build Coastguard Worker   struct in6_ifreq ifr = {};
217*d9f75844SAndroid Build Coastguard Worker   strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
218*d9f75844SAndroid Build Coastguard Worker   memcpy(&ifr.ifr_ifru.ifru_addr, sock_addr, sock_addr->sa_len);
219*d9f75844SAndroid Build Coastguard Worker   int rv = ioctl(ioctl_socket_, SIOCGIFAFLAG_IN6, &ifr);
220*d9f75844SAndroid Build Coastguard Worker   if (rv >= 0) {
221*d9f75844SAndroid Build Coastguard Worker     *native_attributes = ifr.ifr_ifru.ifru_flags;
222*d9f75844SAndroid Build Coastguard Worker   } else {
223*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_ERROR) << "ioctl returns " << errno;
224*d9f75844SAndroid Build Coastguard Worker   }
225*d9f75844SAndroid Build Coastguard Worker   return (rv >= 0);
226*d9f75844SAndroid Build Coastguard Worker }
227*d9f75844SAndroid Build Coastguard Worker 
228*d9f75844SAndroid Build Coastguard Worker // Converts native IPv6 address attributes to net IPv6 address attributes.  If
229*d9f75844SAndroid Build Coastguard Worker // it returns false, the IP address isn't suitable for one-to-one communications
230*d9f75844SAndroid Build Coastguard Worker // applications and should be ignored.
ConvertNativeToIPAttributes(int native_attributes,int * net_attributes)231*d9f75844SAndroid Build Coastguard Worker bool ConvertNativeToIPAttributes(int native_attributes, int* net_attributes) {
232*d9f75844SAndroid Build Coastguard Worker   // For MacOSX, we disallow addresses with attributes IN6_IFF_ANYCASE,
233*d9f75844SAndroid Build Coastguard Worker   // IN6_IFF_DUPLICATED, IN6_IFF_TENTATIVE, and IN6_IFF_DETACHED as these are
234*d9f75844SAndroid Build Coastguard Worker   // still progressing through duplicated address detection (DAD) or are not
235*d9f75844SAndroid Build Coastguard Worker   // suitable for one-to-one communication applications.
236*d9f75844SAndroid Build Coastguard Worker   if (native_attributes & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED |
237*d9f75844SAndroid Build Coastguard Worker                            IN6_IFF_TENTATIVE | IN6_IFF_DETACHED)) {
238*d9f75844SAndroid Build Coastguard Worker     return false;
239*d9f75844SAndroid Build Coastguard Worker   }
240*d9f75844SAndroid Build Coastguard Worker 
241*d9f75844SAndroid Build Coastguard Worker   if (native_attributes & IN6_IFF_TEMPORARY) {
242*d9f75844SAndroid Build Coastguard Worker     *net_attributes |= IPV6_ADDRESS_FLAG_TEMPORARY;
243*d9f75844SAndroid Build Coastguard Worker   }
244*d9f75844SAndroid Build Coastguard Worker 
245*d9f75844SAndroid Build Coastguard Worker   if (native_attributes & IN6_IFF_DEPRECATED) {
246*d9f75844SAndroid Build Coastguard Worker     *net_attributes |= IPV6_ADDRESS_FLAG_DEPRECATED;
247*d9f75844SAndroid Build Coastguard Worker   }
248*d9f75844SAndroid Build Coastguard Worker 
249*d9f75844SAndroid Build Coastguard Worker   return true;
250*d9f75844SAndroid Build Coastguard Worker }
251*d9f75844SAndroid Build Coastguard Worker 
252*d9f75844SAndroid Build Coastguard Worker class MacIfAddrsConverter : public IfAddrsConverter {
253*d9f75844SAndroid Build Coastguard Worker  public:
MacIfAddrsConverter()254*d9f75844SAndroid Build Coastguard Worker   MacIfAddrsConverter() : ip_attribute_getter_(new IPv6AttributesGetter()) {}
~MacIfAddrsConverter()255*d9f75844SAndroid Build Coastguard Worker   ~MacIfAddrsConverter() override {}
256*d9f75844SAndroid Build Coastguard Worker 
ConvertNativeAttributesToIPAttributes(const struct ifaddrs * interface,int * ip_attributes)257*d9f75844SAndroid Build Coastguard Worker   bool ConvertNativeAttributesToIPAttributes(const struct ifaddrs* interface,
258*d9f75844SAndroid Build Coastguard Worker                                              int* ip_attributes) override {
259*d9f75844SAndroid Build Coastguard Worker     int native_attributes;
260*d9f75844SAndroid Build Coastguard Worker     if (!ip_attribute_getter_->GetIPAttributes(
261*d9f75844SAndroid Build Coastguard Worker             interface->ifa_name, interface->ifa_addr, &native_attributes)) {
262*d9f75844SAndroid Build Coastguard Worker       return false;
263*d9f75844SAndroid Build Coastguard Worker     }
264*d9f75844SAndroid Build Coastguard Worker 
265*d9f75844SAndroid Build Coastguard Worker     if (!ConvertNativeToIPAttributes(native_attributes, ip_attributes)) {
266*d9f75844SAndroid Build Coastguard Worker       return false;
267*d9f75844SAndroid Build Coastguard Worker     }
268*d9f75844SAndroid Build Coastguard Worker 
269*d9f75844SAndroid Build Coastguard Worker     return true;
270*d9f75844SAndroid Build Coastguard Worker   }
271*d9f75844SAndroid Build Coastguard Worker 
272*d9f75844SAndroid Build Coastguard Worker  private:
273*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<IPv6AttributesGetter> ip_attribute_getter_;
274*d9f75844SAndroid Build Coastguard Worker };
275*d9f75844SAndroid Build Coastguard Worker 
276*d9f75844SAndroid Build Coastguard Worker }  // namespace
277*d9f75844SAndroid Build Coastguard Worker 
CreateIfAddrsConverter()278*d9f75844SAndroid Build Coastguard Worker IfAddrsConverter* CreateIfAddrsConverter() {
279*d9f75844SAndroid Build Coastguard Worker   return new MacIfAddrsConverter();
280*d9f75844SAndroid Build Coastguard Worker }
281*d9f75844SAndroid Build Coastguard Worker 
282*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
283