RDK Documentation (Open Sourced RDK Components)
Device_IP_Interface_IPv6Address.cpp
Go to the documentation of this file.
1 /**
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 *
19 
20  * @file Device_IP_Interface_IPv6Address.cpp
21  *
22  * @brief Device_IP_Interface_IPv6Address API Implementation.
23  *
24  * This is the implementation of the Device_IP_Interface_IPv6Address API.
25  *
26  * @par Document
27  * TBD Relevant design or API documentation.
28  *
29  */
30 
31 /*****************************************************************************
32  * STANDARD INCLUDE FILES
33  *****************************************************************************/
34 
35 #include <sys/sysinfo.h>
36 #include <sys/ioctl.h>
37 #include <sys/socket.h>
38 #include <sys/types.h>
39 #include <arpa/inet.h>
40 #include <ifaddrs.h>
41 
44 #include "Device_IP_Interface.h"
45 #include "hostIf_utils.h"
46 #include "Device_IP.h"
47 #include "safec_lib.h"
48 
49 /**
50  * @struct in6_ifreq
51  * @brief The structure holds the required parameters such as IPv6 address,interface index etc..
52  * for the IPv6 interface address.
53  */
54 struct in6_ifreq {
55  struct in6_addr ifr6_addr;
56  long ifr6_prefixlen;
57  unsigned int ifr6_ifindex;
58 };
59 
60 GMutex* hostIf_IPv6Address::m_mutex = NULL;
61 GHashTable *hostIf_IPv6Address::ifHash = NULL;
62 
63 const char* hostIf_IPv6Address::PREFERRED = "Preferred";
64 const char* hostIf_IPv6Address::DEPRECATED = "Deprecated";
65 const char* hostIf_IPv6Address::INVALID = "Invalid";
66 const char* hostIf_IPv6Address::INACCESSIBLE = "Inaccessible";
67 const char* hostIf_IPv6Address::UNKNOWN = "Unknown";
68 const char* hostIf_IPv6Address::TENTATIVE = "Tentative";
69 const char* hostIf_IPv6Address::DUPLICATE = "Duplicate";
70 const char* hostIf_IPv6Address::OPTIMISTIC = "Optimistic";
71 
72 const char* hostIf_IPv6Address::AUTOCONFIGURED = "AutoConfigured";
73 const char* hostIf_IPv6Address::DHCPv6 = "DHCPv6";
74 const char* hostIf_IPv6Address::WELLKNOWN = "WellKnown";
75 const char* hostIf_IPv6Address::STATIC = "Static";
76 const char* hostIf_IPv6Address::PREFIXDELEGATION = "PrefixDelegation";
77 const char* hostIf_IPv6Address::ROUTERADVERTISEMENT = "RouterAdvertisement";
78 const char* hostIf_IPv6Address::CHILD = "Child";
79 const char* hostIf_IPv6Address::INAPPLICABLE = "Inapplicable";
80 
81 hostIf_IPv6Address::hostIf_IPv6Address(int dev_id):
82  dev_id(dev_id),
83  bCalledEnable(0),
84  bCalledStatus(0),
85  bCalledIPAddress(0),
86  bCalledOrigin(0),
87  backupIPv6AddressEnable (false),
88  backupIPv6PrefixEnable (false)
89 {
90  errno_t rc = -1;
91  rc=strcpy_s (backupIPv6AddressStatus,sizeof(backupIPv6AddressStatus), "Disabled");
92  if(rc!=EOK)
93  {
94  ERR_CHK(rc);
95  }
96  backupIPv6AddressIPAddress[0]='\0';
97  rc=strcpy_s (backupIPv6AddressOrigin,sizeof(backupIPv6AddressOrigin), STATIC);
98  if(rc!=EOK)
99  {
100  ERR_CHK(rc);
101  }
102  rc=strcpy_s (backupIPv6PrefixStatus,sizeof(backupIPv6PrefixStatus), "Disabled");
103  if(rc!=EOK)
104  {
105  ERR_CHK(rc);
106  }
107  backupIPv6PrefixPrefix[0]='\0';
108  rc=strcpy_s (backupIPv6PrefixOrigin,sizeof(backupIPv6PrefixOrigin), STATIC);
109  if(rc!=EOK)
110  {
111  ERR_CHK(rc);
112  }
113 }
114 
115 hostIf_IPv6Address::~hostIf_IPv6Address()
116 {
117 }
118 
119 void hostIf_IPv6Address::refreshInterfaceName ()
120 {
121  nameOfInterface[0] = 0;
122  if (NULL == hostIf_IP::getInterfaceName (dev_id, nameOfInterface))
123  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: error getting interface name for Device.IP.Interface.%d\n", __FUNCTION__, dev_id);
124 }
125 
126 hostIf_IPv6Address* hostIf_IPv6Address::getInstance(int dev_id)
127 {
128  LOG_ENTRY_EXIT;
129 
130  hostIf_IPv6Address* pRet = NULL;
131 
132  if(ifHash)
133  {
134  pRet = (hostIf_IPv6Address *)g_hash_table_lookup(ifHash,(gpointer) dev_id);
135  }
136  else
137  {
138  ifHash = g_hash_table_new(NULL,NULL);
139  }
140 
141  if(!pRet)
142  {
143  try {
144  pRet = new hostIf_IPv6Address(dev_id);
145  g_hash_table_insert(ifHash, (gpointer)dev_id, pRet);
146  } catch(int e)
147  {
148  RDK_LOG(RDK_LOG_WARN,LOG_TR69HOSTIF,"Caught exception, not able create MoCA Interface instance..\n");
149  }
150  }
151 
152  // make sure returned instance has interface name set
153  if (pRet)
154  pRet->refreshInterfaceName ();
155 
156  return pRet;
157 }
158 
159 GList* hostIf_IPv6Address::getAllInstances()
160 {
161  LOG_ENTRY_EXIT;
162 
163  if(ifHash)
164  return g_hash_table_get_keys(ifHash);
165  return NULL;
166 }
167 
168 void hostIf_IPv6Address::closeInstance(hostIf_IPv6Address *pDev)
169 {
170  LOG_ENTRY_EXIT;
171 
172  if(pDev)
173  {
174  g_hash_table_remove(ifHash, (gconstpointer)pDev->dev_id);
175  delete pDev;
176  }
177 }
178 
179 void hostIf_IPv6Address::closeAllInstances()
180 {
181  LOG_ENTRY_EXIT;
182 
183  if(ifHash)
184  {
185  GList* tmp_list = g_hash_table_get_values (ifHash);
186 
187  while(tmp_list)
188  {
189  hostIf_IPv6Address* pDev = (hostIf_IPv6Address *)tmp_list->data;
190  tmp_list = tmp_list->next;
191  closeInstance(pDev);
192  }
193  }
194 }
195 
196 int hostIf_IPv6Address::handleGetMsg (const char* pSubSetting, int subInstanceNumber, HOSTIF_MsgData_t* stMsgData, bool isAddress)
197 {
198  LOG_ENTRY_EXIT;
199 
200  int ret = NOT_HANDLED;
201 
202  if (isAddress)
203  {
204  if (!strcasecmp (pSubSetting, "Enable"))
205  {
206  ret = get_IPv6Address_Enable (stMsgData, subInstanceNumber);
207  }
208  else if (!strcasecmp (pSubSetting, "Status"))
209  {
210  ret = get_IPv6Address_Status (stMsgData, subInstanceNumber);
211  }
212  else if (!strcasecmp (pSubSetting, "IPAddressStatus"))
213  {
214  ret = get_IPv6Address_IPAddressStatus (stMsgData, subInstanceNumber);
215  }
216  else if (!strcasecmp (pSubSetting, "Alias"))
217  {
218  ret = get_IPv6Address_Alias (stMsgData, subInstanceNumber);
219  }
220  else if (!strcasecmp (pSubSetting, "IPAddress"))
221  {
222  ret = get_IPv6Address_IPAddress (stMsgData, subInstanceNumber);
223  }
224  else if (!strcasecmp (pSubSetting, "Origin"))
225  {
226  ret = get_IPv6Address_Origin (stMsgData, subInstanceNumber);
227  }
228  else if (!strcasecmp (pSubSetting, "Prefix"))
229  {
230  ret = get_IPv6Address_Prefix (stMsgData, subInstanceNumber);
231  }
232  else if (!strcasecmp (pSubSetting, "PreferredLifetime"))
233  {
234  ret = get_IPv6Address_PreferredLifetime (stMsgData, subInstanceNumber);
235  }
236  else if (!strcasecmp (pSubSetting, "ValidLifetime"))
237  {
238  ret = get_IPv6Address_ValidLifetime (stMsgData, subInstanceNumber);
239  }
240  else if (!strcasecmp (pSubSetting, "Anycast"))
241  {
242  ret = get_IPv6Address_Anycast (stMsgData, subInstanceNumber);
243  }
244  else
245  {
246  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%d]Device.IPv6: Parameter \'%s\' is Not Supported \n", __FUNCTION__, __LINE__, stMsgData->paramName);
247  stMsgData->faultCode = fcInvalidParameterName;
248  ret = NOK;
249  }
250  }
251  else
252  {
253  if (!strcasecmp (pSubSetting, "Enable"))
254  {
255  ret = get_IPv6Prefix_Enable (stMsgData, subInstanceNumber);
256  }
257  else if (!strcasecmp (pSubSetting, "Status"))
258  {
259  ret = get_IPv6Prefix_Status (stMsgData, subInstanceNumber);
260  }
261  else if (!strcasecmp (pSubSetting, "PrefixStatus"))
262  {
263  ret = get_IPv6Prefix_PrefixStatus (stMsgData, subInstanceNumber);
264  }
265  else if (!strcasecmp (pSubSetting, "Alias"))
266  {
267  ret = get_IPv6Prefix_Alias (stMsgData, subInstanceNumber);
268  }
269  else if (!strcasecmp (pSubSetting, "Prefix"))
270  {
271  ret = get_IPv6Prefix_Prefix (stMsgData, subInstanceNumber);
272  }
273  else if (!strcasecmp (pSubSetting, "Origin"))
274  {
275  ret = get_IPv6Prefix_Origin (stMsgData, subInstanceNumber);
276  }
277  else if (!strcasecmp (pSubSetting, "StaticType"))
278  {
279  ret = get_IPv6Prefix_StaticType (stMsgData, subInstanceNumber);
280  }
281  else if (!strcasecmp (pSubSetting, "ParentPrefix"))
282  {
283  ret = get_IPv6Prefix_ParentPrefix (stMsgData, subInstanceNumber);
284  }
285  else if (!strcasecmp (pSubSetting, "ChildPrefixBits"))
286  {
287  ret = get_IPv6Prefix_ChildPrefixBits (stMsgData, subInstanceNumber);
288  }
289  else if (!strcasecmp (pSubSetting, "OnLink"))
290  {
291  ret = get_IPv6Prefix_OnLink (stMsgData, subInstanceNumber);
292  }
293  else if (!strcasecmp (pSubSetting, "Autonomous"))
294  {
295  ret = get_IPv6Prefix_Autonomous (stMsgData, subInstanceNumber);
296  }
297  else if (!strcasecmp (pSubSetting, "PreferredLifetime"))
298  {
299  ret = get_IPv6Prefix_PreferredLifetime (stMsgData, subInstanceNumber);
300  }
301  else if (!strcasecmp (pSubSetting, "ValidLifetime"))
302  {
303  ret = get_IPv6Prefix_ValidLifetime (stMsgData, subInstanceNumber);
304  }
305  else
306  {
307  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%d]xBlueTooth: Parameter \'%s\' is Not Supported \n", __FUNCTION__, __LINE__, stMsgData->paramName);
308  stMsgData->faultCode = fcInvalidParameterName;
309  ret = NOK;
310  }
311  }
312 
313  return ret;
314 }
315 
316 int hostIf_IPv6Address::handleSetMsg (const char* pSubSetting, int subInstanceNumber, HOSTIF_MsgData_t* stMsgData, bool isAddress)
317 {
318  LOG_ENTRY_EXIT;
319 
320  int ret = NOT_HANDLED;
321 
322  if (isAddress)
323  {
324  if (!strcasecmp (pSubSetting, "Enable"))
325  {
326  ret = set_IPv6Address_Enable (stMsgData, subInstanceNumber);
327  }
328  else if (!strcasecmp (pSubSetting, "Alias"))
329  {
330  ret = set_IPv6Address_Alias (stMsgData, subInstanceNumber);
331  }
332  else if (!strcasecmp (pSubSetting, "IPAddress"))
333  {
334  ret = set_IPv6Address_IPAddress (stMsgData, subInstanceNumber);
335  }
336  else if (!strcasecmp (pSubSetting, "Prefix"))
337  {
338  ret = set_IPv6Address_Prefix (stMsgData, subInstanceNumber);
339  }
340  else if (!strcasecmp (pSubSetting, "PreferredLifetime"))
341  {
342  ret = set_IPv6Address_PreferredLifetime (stMsgData, subInstanceNumber);
343  }
344  else if (!strcasecmp (pSubSetting, "ValidLifetime"))
345  {
346  ret = set_IPv6Address_ValidLifetime (stMsgData, subInstanceNumber);
347  }
348  else if (!strcasecmp (pSubSetting, "Anycast"))
349  {
350  ret = set_IPv6Address_Anycast (stMsgData, subInstanceNumber);
351  }
352  else
353  {
354  stMsgData->faultCode = fcInvalidParameterName;
355  ret = NOT_HANDLED;
356  }
357  }
358  else
359  {
360  if (!strcasecmp (pSubSetting, "Enable"))
361  {
362  ret = set_IPv6Prefix_Enable (stMsgData, subInstanceNumber);
363  }
364  else if (!strcasecmp (pSubSetting, "Alias"))
365  {
366  ret = set_IPv6Prefix_Alias (stMsgData, subInstanceNumber);
367  }
368  else if (!strcasecmp (pSubSetting, "Prefix"))
369  {
370  ret = set_IPv6Prefix_Prefix (stMsgData, subInstanceNumber);
371  }
372  else if (!strcasecmp (pSubSetting, "StaticType"))
373  {
374  ret = set_IPv6Prefix_StaticType (stMsgData, subInstanceNumber);
375  }
376  else if (!strcasecmp (pSubSetting, "ParentPrefix"))
377  {
378  ret = set_IPv6Prefix_ParentPrefix (stMsgData, subInstanceNumber);
379  }
380  else if (!strcasecmp (pSubSetting, "ChildPrefixBits"))
381  {
382  ret = set_IPv6Prefix_ChildPrefixBits (stMsgData, subInstanceNumber);
383  }
384  else if (!strcasecmp (pSubSetting, "OnLink"))
385  {
386  ret = set_IPv6Prefix_OnLink (stMsgData, subInstanceNumber);
387  }
388  else if (!strcasecmp (pSubSetting, "Autonomous"))
389  {
390  ret = set_IPv6Prefix_Autonomous (stMsgData, subInstanceNumber);
391  }
392  else if (!strcasecmp (pSubSetting, "PreferredLifetime"))
393  {
394  ret = set_IPv6Prefix_PreferredLifetime (stMsgData, subInstanceNumber);
395  }
396  else if (!strcasecmp (pSubSetting, "ValidLifetime"))
397  {
398  ret = set_IPv6Prefix_ValidLifetime (stMsgData, subInstanceNumber);
399  }
400  else
401  {
402  stMsgData->faultCode = fcInvalidParameterName;
403  ret = NOT_HANDLED;
404  }
405 
406  }
407 
408  return ret;
409 }
410 
411 int hostIf_IPv6Address::getIPv6AddressAndMask (int instance, struct in6_addr& in6_address, struct in6_addr& in6_mask)
412 {
413  LOG_ENTRY_EXIT;
414 
415  int rc = NOK;
416  struct ifaddrs *ifa;
417  if (getifaddrs (&ifa))
418  return rc;
419 
420  int current_instance = 0;
421  for (struct ifaddrs *ifa_node = ifa; ifa_node; ifa_node = ifa_node->ifa_next)
422  {
423  if (ifa_node->ifa_addr->sa_family == AF_INET6 && !strcmp (ifa_node->ifa_name, nameOfInterface) && (++current_instance == instance))
424  {
425  in6_address = ((struct sockaddr_in6 *) ifa_node->ifa_addr)->sin6_addr;
426  in6_mask = ((struct sockaddr_in6 *) ifa_node->ifa_netmask)->sin6_addr;
427  rc = OK;
428  break;
429  }
430  }
431 
432  freeifaddrs (ifa);
433 
434  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s]: rc=%d, if=%s, instance=%d\n", __FUNCTION__, rc, nameOfInterface, instance);
435 
436  return rc;
437 }
438 
439 // TODO: check implementation.
440 // If an interface can have a prefix that is not tied to an IPv6 address, this logic cannot
441 // retrieve it. This logic only retrieves prefixes for IPv6 addresses assigned to an interface.
442 int hostIf_IPv6Address::getIPv6Prefix (int instance, struct in6_addr& in6_prefix_address, unsigned int& prefix_length)
443 {
444  LOG_ENTRY_EXIT;
445 
446  struct in6_addr in6_address;
447  struct in6_addr in6_mask;
448  if (OK != getIPv6AddressAndMask (instance, in6_address, in6_mask))
449  return NOK;
450 
451  // prefix address = ipv6 address & netmask (bitwise AND)
452  for (int i = 3 ; i >= 0 ; i--)
453  {
454  in6_prefix_address.s6_addr32[i] = in6_address.s6_addr32[i] & in6_mask.s6_addr32[i];
455  }
456 
457  // prefix length = number of 1 bits in netmask
458  prefix_length = 0;
459  // start iterating over netmask bytes (16 in all)
460  // for each byte with all 1 bits (0xFF) that is encountered, add 8 to prefix_length
461  for (uint8_t i = 0, number_of_1bits = 8, bitPattern = 0xFF; i < 16 && number_of_1bits == 8; i++)
462  {
463  // if byte is not 0xFF, find number of 1-bits in that byte, add that (instead of 8) to prefix_length, and stop iterating
464  while (in6_mask.s6_addr[i] != bitPattern && number_of_1bits != 0)
465  {
466  bitPattern = bitPattern << 1; // shift in 0 into LSB to generate the new bit pattern to match against
467  number_of_1bits--;
468  }
469  prefix_length += number_of_1bits;
470  }
471 
472  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s]: prefix_length =%u\n", __FUNCTION__, prefix_length);
473 
474  return OK;
475 }
476 
477 /**
478  * @brief tests if an IPv6 address is link-local.
479  *
480  * @param[in] in6_address the IPv6 address to test.
481  *
482  * @retval true if the IPv6 address is link-local.
483  * @retval false otherwise.
484  */
485 bool hostIf_IPv6Address::isLinkLocalAddress (const struct in6_addr& in6_address)
486 {
487  LOG_ENTRY_EXIT;
488 
489  // check if the given IPv6 address falls in the IPv6 link-scope address range (fe80/10)
490 
491  RDK_LOG (RDK_LOG_TRACE1, LOG_TR69HOSTIF, "[%s]: ntohs(in6_address.s6_addr16[0]) = %x, (ntohs(in6_address.s6_addr16[0]) & 0xffc0) = %x\n",
492  __FUNCTION__, ntohs(in6_address.s6_addr16[0]), (ntohs(in6_address.s6_addr16[0]) & 0xffc0));
493  return (ntohs(in6_address.s6_addr16[0]) & 0xffc0) == 0xfe80;
494 }
495 
496 //Function to remove the IP Address for the Interface
497 int hostIf_IPv6Address::removeIp(int interfaceNo, char *value)
498 {
499  LOG_ENTRY_EXIT;
500  errno_t safec_rc = -1;
501  int rc = OK;
502  struct ifreq ifr;
503  struct sockaddr_in6 sai6;
504  struct in6_ifreq ifr6;
505  int sockfd;
506 
507  if(0 == strcasecmp(backupIPv6AddressOrigin, STATIC))
508  {
509  /*
510  * Creating INET6 socket Here.
511  */
512  sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
513  if( sockfd != -1)
514  {
515  /*
516  * Socket Creation is successful.
517  * Format the supplied IP address into INET6 protocol format
518  */
519  memset(&sai6, 0, sizeof(sockaddr_in6)); //CID:18430 - sizeofmismatch
520  sai6.sin6_family = AF_INET6;
521  sai6.sin6_port = 0;
522 
523  if(inet_pton(AF_INET6, value, (void *)&sai6.sin6_addr) <= 0)
524  {
525  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"Error Formatting IP Address");
526  rc = NOK;
527  }
528  else
529  {
530  /*
531  * Got the supplied IP address in INET6 protocol format
532  * Set the interface number, address, prefix into ifr (interface request) variable
533  * Call the IOCTL command for remove IP.
534  */
535  ifr6.ifr6_ifindex = interfaceNo;
536  safec_rc=memcpy_s( (char *) &ifr6.ifr6_addr, sizeof(struct in6_addr), (char *) &sai6.sin6_addr, sizeof(struct in6_addr));
537  if(safec_rc!=EOK)
538  {
539  ERR_CHK(safec_rc);
540  }
541  ifr6.ifr6_prefixlen = 64;
542 
543  if (ioctl(sockfd, SIOCDIFADDR, &ifr6) < 0)
544  {
545  perror("SIOCDIFADDR: Error Deleting Existing IPAddress");
546  rc = NOK;
547  }
548  }
549  close(sockfd);
550  }
551  else
552  {
553  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"Error Creating Socket; Not Removing IP Address");
554  rc = NOK;
555  }
556 
557  }
558  else
559  {
560  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"The interface is not static; Cannot Remove IP Address\n");
561  rc = NOK;
562  }
563 
564  return rc;
565 }
566 //Function to set the IP Address for the Interface
567 int hostIf_IPv6Address::setIp(int interfaceNo, char *value)
568 {
569  LOG_ENTRY_EXIT;
570  errno_t safec_rc = -1;
571  int rc = OK;
572  struct ifreq ifr;
573  struct sockaddr_in6 sai6;
574  struct in6_ifreq ifr6;
575  int sockfd;
576 
577  if(0 == strcasecmp(backupIPv6AddressOrigin, STATIC))
578  {
579  /*
580  * Creating INET6 socket Here to assign the IP address in interface.
581  */
582  sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
583  if( sockfd != -1)
584  {
585  /*
586  * Socket Creation is successful.
587  * Format the supplied IP address into INET6 protocol format
588  */
589  memset(&sai6, 0, sizeof(sockaddr_in6)); //CID:18189 - sizeofmismatch
590  sai6.sin6_family = AF_INET6;
591  sai6.sin6_port = 0;
592 
593  if(inet_pton(AF_INET6, value, (void *)&sai6.sin6_addr) <= 0)
594  {
595  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"Error Formatting IP Address");
596  rc = NOK;
597  }
598  else
599  {
600  /*
601  * Got the supplied IP address in INET6 protocol format
602  * Set the interface number, address, prefix into ifr (interface request) variable
603  * Call the IOCTL command for adding IP.
604  */
605  ifr6.ifr6_ifindex = interfaceNo;
606  safec_rc=memcpy_s( (char *) &ifr6.ifr6_addr, sizeof(struct in6_addr), (char *) &sai6.sin6_addr, sizeof(struct in6_addr));
607  if(safec_rc!=EOK)
608  {
609  ERR_CHK(safec_rc);
610  }
611  ifr6.ifr6_prefixlen = 64;
612 
613  if (ioctl(sockfd, SIOCSIFADDR, &ifr6) < 0)
614  {
615  perror("SIOCDIFADDR: Error Assigning IPAddress");
616  rc = NOK;
617  }
618  }
619  close(sockfd);
620  }
621  else
622  {
623  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"Error Creating Socket; Not Assigning IP Address");
624  rc = NOK;
625  }
626  }
627  else
628  {
629  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"The interface is not static; Cannot Assign IP Address\n");
630  rc = NOK;
631  }
632 
633  return rc;
634 }
635 
636 /****************************************************************************************************************************************************/
637 // Device_IP_Interface_IPv6Address Profile. Getters:
638 /****************************************************************************************************************************************************/
639 
640 /**
641  * @brief This function provides the value 'true' or 'false' for Enable status of IPv6 address.
642  *
643  * @param[out] stMsgData TR-069 Host interface message request.
644  * @param[in] subInstanceNo SubInstance number.
645  * @param[in] pChanged Status of the operation.
646  *
647  * @return Returns the status of the operation.
648  *
649  * @retval OK if it successfully fetch the data from the device.
650  * @retval ERR_INTERNAL_ERROR if not able to fetch the data.
651  * @ingroup TR69_HOSTIF_DEVICE_IPv6_INTERFACE_ADDRESS_API
652  */
653 int hostIf_IPv6Address::get_IPv6Address_Enable(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
654 {
655  LOG_ENTRY_EXIT;
656 
657  struct in6_addr in6_address;
658  struct in6_addr in6_mask;
659  bool enable = (OK == getIPv6AddressAndMask (subInstanceNo, in6_address, in6_mask));
660 
661  if(bCalledEnable && pChanged && (backupIPv6AddressEnable != enable))
662  {
663  *pChanged = true;
664  }
665  bCalledEnable = true;
666  backupIPv6AddressEnable = enable;
667  put_int(stMsgData->paramValue,enable);
668  stMsgData->paramtype = hostIf_BooleanType;
669  stMsgData->paramLen = sizeof(bool);
670 
671  return OK;
672 }
673 
674 /**
675  * @brief This function provides the status of this IPv6Address table entry. Possible values
676  * - Disabled
677  * - Enabled
678  * - Error_Misconfigured
679  * - Error (OPTIONAL)
680  * @note - The "Error_Misconfigured" value indicates that a necessary
681  * configuration value is undefined or invalid.
682  * - The "Error" value MAY be used by the CPE to indicate a
683  * locally defined error condition.
684  *
685  * @param[out] stMsgData TR-069 Host interface message request.
686  * @param[in] subInstanceNo SubInstance number.
687  * @param[in] pChanged Status of the operation.
688  *
689  * @return Returns the status of the operation.
690  *
691  * @retval OK if it successfully fetch the data from the device.
692  * @retval ERR_INTERNAL_ERROR if not able to fetch the data.
693  * @ingroup TR69_HOSTIF_DEVICE_IPv6_INTERFACE_ADDRESS_API
694  */
695 int hostIf_IPv6Address::get_IPv6Address_Status(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
696 {
697  LOG_ENTRY_EXIT;
698  errno_t rc = -1;
699  char status[BUFF_LENGTH_16];
700  struct in6_addr in6_address;
701  struct in6_addr in6_mask;
702  //rc=strcpy_s (status,sizeof(status), (OK == getIPv6AddressAndMask (subInstanceNo, in6_address, in6_mask)) ? "Enabled" : "Disabled");
703  if(OK == getIPv6AddressAndMask (subInstanceNo, in6_address, in6_mask))
704  {
705  rc=strcpy_s (status,sizeof(status),"Enabled");
706  }
707  else
708  {
709  rc=strcpy_s (status,sizeof(status),"Disabled");
710  }
711  if(rc!=EOK)
712  {
713  ERR_CHK(rc);
714  }
715  if (bCalledStatus && pChanged && strncmp (status, backupIPv6AddressStatus, BUFF_LENGTH_16))
716  {
717  *pChanged = true;
718  }
719  bCalledStatus = true;
720  strncpy (backupIPv6AddressStatus, status, sizeof(backupIPv6AddressStatus) -1); //CID:136468 - Buffer size warning
721  backupIPv6AddressStatus[sizeof(backupIPv6AddressStatus) -1] = '\0';
722  strncpy (stMsgData->paramValue, status, BUFF_LENGTH_16);
723  stMsgData->paramtype = hostIf_StringType;
724  stMsgData->paramLen = strlen (status);
725 
726  return OK;
727 }
728 
729 int hostIf_IPv6Address::get_IPv6Address_IPAddressStatus (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
730 {
731  LOG_ENTRY_EXIT;
732 
733 /*
734  About IPAddressStatus, from the spec:
735 
736  The status of IPAddress, indicating whether it can be used for communication. See also PreferredLifetime and
737  ValidLifetime. Enumeration of:
738 
739  Preferred (Valid address that can appear as the destination or source address of a packet)
740 
741  Deprecated (Valid but deprecated address that is not intended to be used as a source address)
742 
743  Invalid (Invalid address that is not intended to appear as the destination or source address of a packet)
744 
745  Inaccessible (Valid address that is not accessible because the interface to which it is assigned is not operational)
746 
747  Unknown (Address status cannot be determined for some reason)
748 
749  Tentative (The uniqueness of the address on the link is being verified)
750 
751  Duplicate (Invalid address that has been determined to be non-unique on the link)
752 
753  Optimistic (Valid address that is available for use, subject to restrictions, while its uniqueness on a link is being verified)
754 
755  This parameter is based on ipAddressStatus and ipAddressStatusTC from [RFC4293].
756 */
757 
758  errno_t rc = -1;
759  long int valid_lft;
760  if (false == get_ipv6address_valid_lifetime (subInstanceNo, valid_lft))
761  return NOK;
762 
763  long int preferred_lft;
764  if (false == get_ipv6address_preferred_lifetime (subInstanceNo, preferred_lft))
765  return NOK;
766 
767  char interfaceOperationalState[BUFF_LENGTH_16];
768  hostIf_IPInterface::getInstance (dev_id)->getInterfaceOperationalState (interfaceOperationalState);
769 
770  char ipaddressStatus[BUFF_LENGTH_16];
771  if (valid_lft == 0)
772  {
773  rc=strcpy_s (ipaddressStatus,BUFF_LENGTH_16, INVALID);
774  if(rc!=EOK)
775  {
776  ERR_CHK(rc);
777  }
778  }
779  else if (strcasecmp (interfaceOperationalState, STATE_DOWN) == 0)
780  {
781  rc=strcpy_s (ipaddressStatus,BUFF_LENGTH_16, INACCESSIBLE);
782  if(rc!=EOK)
783  {
784  ERR_CHK(rc);
785  }
786  }
787  else if (preferred_lft == 0)
788  {
789  rc=strcpy_s (ipaddressStatus,BUFF_LENGTH_16, DEPRECATED);
790  if(rc!=EOK)
791  {
792  ERR_CHK(rc);
793  }
794  }
795  else
796  {
797 
798  rc=strcpy_s (ipaddressStatus,BUFF_LENGTH_16, PREFERRED);
799  if(rc!=EOK)
800  {
801  ERR_CHK(rc);
802  }
803  }
804  // TODO: Unknown, Tentative, Duplicate, Optimistic
805 
806  // TODO:
807  strncpy (stMsgData->paramValue, ipaddressStatus, BUFF_LENGTH_16);
808  stMsgData->paramtype = hostIf_StringType;
809  stMsgData->paramLen = strlen (ipaddressStatus);
810 
811  return OK;
812 }
813 
814 /**
815  * @brief This function provides a non-volatile handle used to reference this IPv6 address
816  * instance of this IP interface. Alias provides a mechanism for an ACS to label this
817  * instance for future reference. Currently not implemented.
818  *
819  * @note If the CPE supports the Alias-based Addressing feature as defined
820  * in [Section 3.6.1/TR-069 Amendment 4] and described in [Appendix II/TR-069 Amendment 4],
821  * the following mandatory constraints MUST be enforced:
822  * - Its value MUST NOT be empty.
823  * - Its value MUST start with a letter.
824  *
825  * If its instance object is created by the CPE, the initial value MUST start with a "cpe-" prefix.
826  * The CPE MUST NOT change the parameter value. This parameter can only be modified if "Origin"
827  * is "Static".
828  *
829  * @param[out] stMsgData TR-069 Host interface message request.
830  * @param[in] subInstanceNo SubInstance number currently not in use.
831  * @param[in] pChanged Status of the operation.
832  *
833  * @return Returns the status of the operation.
834  *
835  * @retval OK if it is successfully fetch the data from the device.
836  * @retval ERR_INTERNAL_ERROR if not able to fetch the data.
837  * @retval NOK if not handle.
838  * @ingroup TR69_HOSTIF_DEVICE_IPv6_INTERFACE_ADDRESS_API
839  */
840 int hostIf_IPv6Address::get_IPv6Address_Alias(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
841 {
842  LOG_ENTRY_EXIT;
843  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
844  return NOK;
845 }
846 
847 /**
848  * @brief This function provides the IPv6 address.
849  * @note This parameter can only be modified if "Origin" is
850  * "Static".
851  *
852  * @param[out] stMsgData TR-069 Host interface message request.
853  * @param[in] subInstanceNo SubInstance number.
854  * @param[in] pChanged Status of the operation.
855  *
856  * @return Returns the status of the operation.
857  *
858  * @retval OK if it is successfully fetch the data from the device.
859  * @retval ERR_INTERNAL_ERROR if not able to fetch the data.
860  * @retval NOK if not handle.
861  * @ingroup TR69_HOSTIF_DEVICE_IPv6_INTERFACE_ADDRESS_API
862  */
863 int hostIf_IPv6Address::get_IPv6Address_IPAddress(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
864 {
865  LOG_ENTRY_EXIT;
866 
867  struct in6_addr in6_address;
868  struct in6_addr in6_mask;
869  if (OK != getIPv6AddressAndMask (subInstanceNo, in6_address, in6_mask))
870  return NOK;
871 
872  char ipv6Address[BUFF_LENGTH_64];
873  inet_ntop (AF_INET6, &in6_address, ipv6Address, BUFF_LENGTH_64);
874  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s,%d]: if = %s, instance = %d, ipv6address = %s\n",
875  __FUNCTION__, __LINE__, nameOfInterface, subInstanceNo, ipv6Address);
876 
877  if (bCalledIPAddress && pChanged && strncmp (ipv6Address, backupIPv6AddressIPAddress, BUFF_LENGTH_64))
878  {
879  *pChanged = true;
880  }
881  bCalledIPAddress = true;
882  strncpy (backupIPv6AddressIPAddress, ipv6Address, sizeof(backupIPv6AddressIPAddress) -1); //CID:136333 - Buffer size warning
883  backupIPv6AddressIPAddress[sizeof(backupIPv6AddressIPAddress) -1] = '\0';
884  strncpy (stMsgData->paramValue, ipv6Address, BUFF_LENGTH_64);
885  stMsgData->paramtype = hostIf_StringType;
886  stMsgData->paramLen = strlen (ipv6Address);
887 
888  return OK;
889 }
890 
891 /**
892  * @brief This function provides the addressing method used to assign the IP address.
893  * The Possible enum vlaues
894  *
895  * - DHCP
896  * - AutoIP
897  * - IPCP
898  * - Static
899  *
900  * @param[out] stMsgData TR-069 Host interface message request.
901  * @param[in] subInstanceNo SubInstance number currently not in use.
902  * @param[in] pChanged Status of the operation.
903  *
904  * @return Returns the status of the operation.
905  *
906  * @retval OK if successfully fetch the data from the device.
907  * @retval ERR_INTERNAL_ERROR if not able to fetch the data.
908  * @retval NOK if it is not handle.
909  * @ingroup TR69_HOSTIF_DEVICE_IPv6_INTERFACE_ADDRESS_API
910  */
911 int hostIf_IPv6Address::get_IPv6Address_Origin(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
912 {
913  LOG_ENTRY_EXIT;
914 
915 /*
916  From the spec:
917 
918  Mechanism via which the IP address was assigned. Enumeration of:
919 
920  AutoConfigured (Automatically generated. For example, a link-local address as specified by SLAAC [Section 5.3/RFC4862],
921  a global address as specified by SLAAC [Section 5.5/RFC4862], or generated via CPE logic (e.g. from delegated prefix
922  as specified by [RFC3633]), or from ULA /48 prefix as specified by [RFC4193])
923 
924  DHCPv6 (Assigned by DHCPv6 [RFC3315])
925 
926  IKEv2 (Assigned by IKEv2 [RFC5996])
927 
928  MAP (Assigned by MAP [RFC7597], i.e. is this interface's MAP IPv6 address)
929 
930  WellKnown (Specified by a standards organization, e.g. the ::1 loopback address, which is defined in [RFC4291])
931 
932  Static (For example, present in the factory default configuration (but not WellKnown), created by the ACS, or created
933  by some other management entity (e.g. via a GUI))
934 
935  This parameter is based on ipOrigin from [RFC4293].
936 */
937 
938  // verify we have an IPv6 address for the given instance
939  struct in6_addr in6_address;
940  struct in6_addr in6_mask;
941  if (OK != getIPv6AddressAndMask (subInstanceNo, in6_address, in6_mask))
942  return NOK;
943  errno_t rc = -1;
944  char origin[BUFF_LENGTH_32];
945  if (hostIf_IPInterface::isLoopback (nameOfInterface))
946  {
947  rc=strcpy_s (origin,BUFF_LENGTH_32, WELLKNOWN);
948  if(rc!=EOK)
949  {
950  ERR_CHK(rc);
951  }
952  }
953  else if (isLinkLocalAddress (in6_address))
954  {
955  rc=strcpy_s (origin,BUFF_LENGTH_32, AUTOCONFIGURED);
956  if(rc!=EOK)
957  {
958  ERR_CHK(rc);
959  }
960  }
961  else
962  {
963  rc=strcpy_s (origin,BUFF_LENGTH_32, AUTOCONFIGURED); // otherwise assume "AutoConfigured" (even for sit0's IPv4-compatible address "::127.0.0.1"/96 ?)
964  if(rc!=EOK)
965  {
966  ERR_CHK(rc);
967  }
968  }
969 
970  if (bCalledOrigin && pChanged && strncmp (origin, backupIPv6AddressOrigin, BUFF_LENGTH_32))
971  {
972  *pChanged = true;
973  }
974  bCalledOrigin = true;
975  strncpy (backupIPv6AddressOrigin, origin, sizeof(backupIPv6AddressOrigin) -1); //CID:136548 - Buffer size warning
976  backupIPv6AddressOrigin[sizeof(backupIPv6AddressOrigin) -1] = '\0';
977  strncpy (stMsgData->paramValue, origin, BUFF_LENGTH_32);
978  stMsgData->paramtype = hostIf_StringType;
979  stMsgData->paramLen = strlen (origin);
980 
981  return OK;
982 }
983 
984 int hostIf_IPv6Address::get_IPv6Address_Prefix (HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
985 {
986  LOG_ENTRY_EXIT;
987 
988 /*
989  From the spec:
990 
991  The value MUST be the path name of a row in the IPv6Prefix table. If the referenced object is deleted,
992  the parameter value MUST be set to an empty string. IPv6 address prefix.
993 
994  Some addresses, e.g. addresses assigned via the DHCPv6 IA_NA option, are not associated with a prefix,
995  and some WellKnown prefixes might not be modeled. In both of these cases Prefix will be an empty string.
996 
997  This parameter can only be modified if the Origin is Static.
998 
999  This parameter is based on ipAddressPrefix from [RFC4293].
1000 */
1001 
1002  // if an IPv6 address exists for this instance #, then a prefix exists as well.
1003  // so proceed only if an IPv6 address exists, else error.
1004  struct in6_addr in6_address;
1005  struct in6_addr in6_mask;
1006  errno_t rc = -1;
1007  if (OK != getIPv6AddressAndMask (subInstanceNo, in6_address, in6_mask))
1008  return NOK;
1009 
1010  // path name of corresponding row in IPv6Prefix table can be generated from this TR069 parameter's name:
1011  // Device.IP.Interface.{i}.IPv6Address.{j}.Prefix (where j is 'subInstanceNo' parameter (2nd parameter) passed to this method
1012  // as
1013  // Device.IP.Interface.{i}.IPv6Prefix.{j}.
1014 
1015  char pathnameOfRowInIPv6PrefixTable[TR69HOSTIFMGR_MAX_PARAM_LEN];
1016  rc=strcpy_s (pathnameOfRowInIPv6PrefixTable,TR69HOSTIFMGR_MAX_PARAM_LEN, stMsgData->paramName);
1017  if(rc!=EOK)
1018  {
1019  ERR_CHK(rc);
1020  }
1021  const char *positionAfterInstanceNumber = 0;
1022  int instanceNumber = 0;
1023  if(!matchComponent (pathnameOfRowInIPv6PrefixTable, "Device.IP.Interface", &positionAfterInstanceNumber, instanceNumber))
1024  {
1025  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"hostIf_IPv6Address : matchComponent error \n");
1026  } //CID:31038 - Checked return
1027  sprintf ((char*) positionAfterInstanceNumber, "%s%d.", "IPv6Prefix.", subInstanceNo);
1028 
1029  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s,%d] pathnameOfRowInIPv6PrefixTable = %s",
1030  __FUNCTION__, __LINE__, pathnameOfRowInIPv6PrefixTable);
1031 
1032  strncpy (stMsgData->paramValue, pathnameOfRowInIPv6PrefixTable, sizeof(stMsgData->paramValue) -1); //CID:136393 - Buffer size warning
1033  stMsgData->paramValue [sizeof(stMsgData->paramValue) -1] = '\0';
1034  stMsgData->paramtype = hostIf_StringType;
1035  stMsgData->paramLen = strlen (pathnameOfRowInIPv6PrefixTable);
1036 
1037  return OK;
1038 }
1039 
1040 int hostIf_IPv6Address::get_IPv6Address_PreferredLifetime (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1041 {
1042  LOG_ENTRY_EXIT;
1043 
1044  long int lifetime;
1045  if (false == get_ipv6address_preferred_lifetime (subInstanceNo, lifetime))
1046  return NOK;
1047 
1048  char preferredLifetime[BUFF_LENGTH_32];
1049  convert_lifetime_to_string (lifetime, preferredLifetime);
1050 
1051  // TODO:
1052  strncpy (stMsgData->paramValue, preferredLifetime, BUFF_LENGTH_32);
1053  stMsgData->paramtype = hostIf_StringType;
1054  stMsgData->paramLen = strlen (preferredLifetime);
1055 
1056  return OK;
1057 }
1058 
1059 int hostIf_IPv6Address::get_IPv6Address_ValidLifetime (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1060 {
1061  LOG_ENTRY_EXIT;
1062 
1063  long int lifetime;
1064  if (false == get_ipv6address_valid_lifetime (subInstanceNo, lifetime))
1065  return NOK;
1066 
1067  char validLifetime[BUFF_LENGTH_32];
1068  convert_lifetime_to_string (lifetime, validLifetime);
1069 
1070  // TODO:
1071  strncpy (stMsgData->paramValue, validLifetime, BUFF_LENGTH_32);
1072  stMsgData->paramtype = hostIf_StringType;
1073  stMsgData->paramLen = strlen (validLifetime);
1074 
1075  return OK;
1076 }
1077 
1078 int hostIf_IPv6Address::get_IPv6Address_Anycast (HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
1079 {
1080  LOG_ENTRY_EXIT;
1081 
1082  // from the spec:
1083  // Indicates whether this is an anycast address [Section 2.6/RFC4291]. Anycast
1084  // addresses are syntactically identical to unicast addresses and so need to be
1085  // configured explicitly.
1086 
1087  // Assuming anycast IPv6 addresses are not used on STBs, so returning false
1088  put_int (stMsgData->paramValue, false);
1089  stMsgData->paramtype = hostIf_BooleanType;
1090  stMsgData->paramLen = sizeof(bool);
1091 
1092  return OK;
1093 }
1094 
1095 /**
1096  * returns:
1097  * false if there was an error while trying to determine the specified lifetime
1098  * true otherwise
1099  *
1100  * below are possible values for the output parameter 'lifetime':
1101  * -1 if lifetime cannot be determined
1102  * -2 if lifetime is forever
1103  * a non-negative value otherwise
1104  */
1105 bool hostIf_IPv6Address::get_ipv6address_lifetime (unsigned int instance, char* search_string, long int& lifetime)
1106 {
1107  LOG_ENTRY_EXIT;
1108 
1109  // https://www.broadband-forum.org/cwmp/tr-181-2-11-0.html#D.Device:2.Device.IP.Interface.{i}.IPv6Address.{i}.
1110  //
1111  // PreferredLifetime:
1112  // The time at which this address will cease to be preferred (i.e. will become
1113  // deprecated), or 0001-01-01T00:00:00Z if not known. For an infinite lifetime, the
1114  // parameter value MUST be 9999-12-31T23:59:59Z.
1115  //
1116  // ValidLifetime:
1117  // The time at which this address will cease to be valid (i.e. will become invalid), or
1118  // 0001-01-01T00:00:00Z if unknown. For an infinite lifetime, the parameter value
1119  // MUST be 9999-12-31T23:59:59Z.
1120 
1121  char cmd[BUFF_LENGTH_64] = { 0 };
1122  char resultBuff[BUFF_LENGTH_128] = { 0 };
1123  snprintf (cmd, BUFF_LENGTH_64, "ip -6 -o addr show %s | awk '{i++;if(i==%d){print}}'", nameOfInterface, instance);
1124  if (read_command_output (cmd, resultBuff, BUFF_LENGTH_128) != OK)
1125  return false;
1126  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s,%d] resultBuff = %s", __FUNCTION__, __LINE__, resultBuff);
1127 
1128  char *str = strstr (resultBuff, search_string);
1129  if (str == NULL)
1130  {
1131  lifetime = -1;
1132  return true;
1133  }
1134 
1135  str += strlen (search_string);
1136  while (isspace (*str))
1137  str++;
1138 
1139  char strLifetime[BUFF_LENGTH_64];
1140  int count = sscanf (str, "%s", strLifetime);
1141 
1142  if (strcmp (strLifetime, "forever") == 0)
1143  {
1144  lifetime = -2;
1145  return true;
1146  }
1147 
1148  char *time_units;
1149  long int time_remaining = strtol (strLifetime, &time_units, 10);
1150  long int seconds_remaining = (strncasecmp (time_units, "s", 1) == 0) ? time_remaining :
1151  (strncasecmp (time_units, "m", 1) == 0) ? time_remaining * 60 : -1;
1152  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s,%d] time_remaining = %ld, time_units = %s, seconds_remaining = %ld\n",
1153  __FUNCTION__, __LINE__, time_remaining, time_units, seconds_remaining);
1154 
1155  if (seconds_remaining == -1) // invalid time = unknown
1156  {
1157  lifetime = -1;
1158  return true;
1159  }
1160 
1161  // lifetime = (current time + seconds_remaining) as spec calls for a time value
1162  lifetime = time (0) + seconds_remaining;
1163  return true;
1164 }
1165 
1166 /**
1167  * returns:
1168  * false if there was an error while trying to determine the preferred lifetime
1169  * true otherwise
1170  *
1171  * below are possible values for the output parameter 'preferred_lifetime':
1172  * -1 if preferred lifetime cannot be determined
1173  * -2 if preferred lifetime is forever
1174  * a non-negative value otherwise
1175  */
1176 bool hostIf_IPv6Address::get_ipv6address_preferred_lifetime (unsigned int instance, long int& preferred_lifetime)
1177 {
1178  return hostIf_IPv6Address::get_ipv6address_lifetime (instance, "preferred_lft", preferred_lifetime);
1179 }
1180 
1181 /**
1182  * returns:
1183  * false if there was an error while trying to determine the valid lifetime
1184  * true otherwise
1185  *
1186  * below are possible values for the output parameter 'valid_lifetime':
1187  * -1 if valid lifetime cannot be determined
1188  * -2 if valid lifetime is forever
1189  * a non-negative value otherwise
1190  */
1191 bool hostIf_IPv6Address::get_ipv6address_valid_lifetime (unsigned int instance, long int& valid_lifetime)
1192 {
1193  return hostIf_IPv6Address::get_ipv6address_lifetime (instance, "valid_lft", valid_lifetime);
1194 }
1195 
1196 void hostIf_IPv6Address::convert_lifetime_to_string (long int t, char* lifetime)
1197 {
1198  LOG_ENTRY_EXIT;
1199 
1200  errno_t rc = -1;
1201  lifetime[0] = 0;
1202 
1203  if (t == -1) // // -1 = unknown
1204  {
1205  rc=strcpy_s (lifetime,BUFF_LENGTH_32, TIME_UNKNOWN); // "0001-01-01T00:00:00Z"
1206  if(rc!=EOK)
1207  {
1208  ERR_CHK(rc);
1209  }
1210  }
1211  else if (t == -2) // -2 = forever
1212  {
1213  rc=strcpy_s (lifetime,BUFF_LENGTH_32, TIME_INFINITY); // "9999-12-31T23:59:59Z"
1214  if(rc!=EOK)
1215  {
1216  ERR_CHK(rc);
1217  }
1218  }
1219  else
1220  {
1221  tm tmp;
1222  gmtime_r (&t, &tmp);
1223  strftime (lifetime, BUFF_LENGTH_128, "%Y-%m-%dT%H:%M:%SZ", &tmp);
1224  }
1225 }
1226 
1227 
1228 int hostIf_IPv6Address::get_IPv6Prefix_Enable(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
1229 {
1230  LOG_ENTRY_EXIT;
1231 
1232  struct in6_addr in6_prefix_address;
1233  unsigned int prefix_length;
1234  bool enable = (OK == getIPv6Prefix (subInstanceNo, in6_prefix_address, prefix_length));
1235 
1236  // TODO: use a variable other than bCalledEnable which is for IPv6Address profile
1237  if (bCalledEnable && pChanged && (backupIPv6PrefixEnable != enable))
1238  {
1239  *pChanged = true;
1240  }
1241  bCalledEnable = true;
1242  backupIPv6PrefixEnable = enable;
1243  put_int (stMsgData->paramValue, enable);
1244  stMsgData->paramtype = hostIf_BooleanType;
1245  stMsgData->paramLen = sizeof(bool);
1246 
1247  return OK;
1248 }
1249 
1250 int hostIf_IPv6Address::get_IPv6Prefix_Status(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
1251 {
1252  LOG_ENTRY_EXIT;
1253 
1254  errno_t rc = -1;
1255  char status[BUFF_LENGTH_16];
1256  struct in6_addr in6_prefix_address;
1257  unsigned int prefix_length;
1258  // rc=strcpy_s (status,sizeof(status), (OK == getIPv6Prefix (subInstanceNo, in6_prefix_address, prefix_length)) ? "Enabled" : "Disabled");
1259  if(OK == getIPv6Prefix (subInstanceNo, in6_prefix_address, prefix_length))
1260  {
1261  rc=strcpy_s (status,sizeof(status),"Enabled");
1262  if(rc!=EOK)
1263  {
1264  ERR_CHK(rc);
1265  }
1266  }
1267  else
1268  {
1269  rc=strcpy_s (status,sizeof(status),"Disabled");
1270  if(rc!=EOK)
1271  {
1272  ERR_CHK(rc);
1273  }
1274  }
1275  // TODO: use a variable other than bCalledStatus which is for IPv6Address profile
1276  if (bCalledStatus && pChanged && strncmp (status, backupIPv6PrefixStatus, BUFF_LENGTH_16))
1277  {
1278  *pChanged = true;
1279  }
1280  bCalledStatus = true;
1281  strncpy (backupIPv6PrefixStatus, status, sizeof(backupIPv6PrefixStatus) -1); //CID:136608 - Buffer size warning
1282  backupIPv6PrefixStatus[sizeof(backupIPv6PrefixStatus) -1] = '\0';
1283  strncpy (stMsgData->paramValue, status, BUFF_LENGTH_16);
1284  stMsgData->paramtype = hostIf_StringType;
1285  stMsgData->paramLen = strlen (status);
1286 
1287  return OK;
1288 }
1289 
1290 int hostIf_IPv6Address::get_IPv6Prefix_PrefixStatus (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1291 {
1292  LOG_ENTRY_EXIT;
1293 
1294 /*
1295  About PrefixStatus, from the spec:
1296 
1297  The status of Prefix, indicating whether it can be used for communication. See also PreferredLifetime and
1298  ValidLifetime. Enumeration of:
1299 
1300  Preferred (Valid prefix)
1301 
1302  Deprecated (Valid but deprecated prefix)
1303 
1304  Invalid (Invalid prefix)
1305 
1306  Inaccessible (Valid prefix that is not accessible because the interface to which it is assigned is not
1307  operational)
1308 
1309  Unknown (Prefix status cannot be determined for some reason)
1310 
1311  This parameter is based on ipAddressStatus and ipAddressStatusTC from [RFC4293].
1312 */
1313 
1314  // TODO: Where do we look to find information about the valid and preferred lifetimes of a prefix ?
1315  // For now, valid/preferred lifetimes of the IPv6 address associated with this prefix are used
1316  // as the basis for deriving prefix status
1317 
1318  errno_t rc = -1;
1319  long int valid_lft;
1320  if (false == get_ipv6address_valid_lifetime (subInstanceNo, valid_lft))
1321  return NOK;
1322 
1323  long int preferred_lft;
1324  if (false == get_ipv6address_preferred_lifetime (subInstanceNo, preferred_lft))
1325  return NOK;
1326 
1327  char interfaceOperationalState[BUFF_LENGTH_16];
1328  hostIf_IPInterface::getInstance (dev_id)->getInterfaceOperationalState (interfaceOperationalState);
1329 
1330  char prefixStatus[BUFF_LENGTH_16];
1331  if (valid_lft == 0)
1332  {
1333  rc=strcpy_s (prefixStatus,BUFF_LENGTH_16, INVALID);
1334  if(rc!=EOK)
1335  {
1336  ERR_CHK(rc);
1337  }
1338  }
1339  else if (strcasecmp (interfaceOperationalState, STATE_DOWN) == 0)
1340  {
1341  rc=strcpy_s (prefixStatus,BUFF_LENGTH_16, INACCESSIBLE);
1342  if(rc!=EOK)
1343  {
1344  ERR_CHK(rc);
1345  }
1346  }
1347  else if (preferred_lft == 0)
1348  {
1349  rc=strcpy_s (prefixStatus,BUFF_LENGTH_16, DEPRECATED);
1350  if(rc!=EOK)
1351  {
1352  ERR_CHK(rc);
1353  }
1354  }
1355  else
1356  {
1357  rc=strcpy_s (prefixStatus,BUFF_LENGTH_16, PREFERRED);
1358  if(rc!=EOK)
1359  {
1360  ERR_CHK(rc);
1361  }
1362  }
1363  // TODO: Unknown
1364 
1365  // TODO:
1366  strncpy (stMsgData->paramValue, prefixStatus, BUFF_LENGTH_16);
1367  stMsgData->paramtype = hostIf_StringType;
1368  stMsgData->paramLen = strlen (prefixStatus);
1369 
1370  return OK;
1371 }
1372 
1373 int hostIf_IPv6Address::get_IPv6Prefix_Alias(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
1374 {
1375  LOG_ENTRY_EXIT;
1376  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1377  return NOK;
1378 }
1379 
1380 int hostIf_IPv6Address::get_IPv6Prefix_Prefix(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
1381 {
1382  LOG_ENTRY_EXIT;
1383 
1384  struct in6_addr in6_prefix_address;
1385  unsigned int prefix_length;
1386  if (OK != getIPv6Prefix (subInstanceNo, in6_prefix_address, prefix_length))
1387  return NOK;
1388 
1389  char prefix_address[BUFF_LENGTH_64];
1390  inet_ntop (AF_INET6, &in6_prefix_address, prefix_address, 64);
1391 
1392  char prefix[BUFF_LENGTH_64];
1393  sprintf (prefix, "%s/%u", prefix_address, prefix_length);
1394  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s]: if=%s, instance=%d, prefix=%s\n",
1395  __FUNCTION__, nameOfInterface, subInstanceNo, prefix);
1396 
1397  // TODO: use a variable other than bCalledIPAddress which is for IPv6Address profile
1398  if (bCalledIPAddress && pChanged && strncmp (prefix, backupIPv6PrefixPrefix, BUFF_LENGTH_64))
1399  {
1400  *pChanged = true;
1401  }
1402  bCalledIPAddress = true;
1403  strncpy (backupIPv6PrefixPrefix, prefix, sizeof(backupIPv6PrefixPrefix) -1); //CID:136410 - Buffer size warning
1404  backupIPv6PrefixPrefix[sizeof(backupIPv6PrefixPrefix) -1] = '\0';
1405  strncpy (stMsgData->paramValue, prefix, BUFF_LENGTH_64);
1406  stMsgData->paramtype = hostIf_StringType;
1407  stMsgData->paramLen = strlen (prefix);
1408 
1409  return OK;
1410 }
1411 
1412 int hostIf_IPv6Address::get_IPv6Prefix_Origin (int instance, char* origin)
1413 {
1414  LOG_ENTRY_EXIT;
1415 
1416 /*
1417  Mechanism via which the prefix was assigned or most recently updated. Enumeration of:
1418  AutoConfigured (Generated via internal CPE logic (e.g. the ULA /48 prefix) or derived from
1419  an internal prefix that is not modeled in any IPv6Prefix table)
1420 
1421  PrefixDelegation (Delegated via DHCPv6 [RFC3633] or some other protocol, e.g. IPv6rd
1422  [RFC5969]. Also see StaticType)
1423 
1424  RouterAdvertisement (Discovered via router advertisement [RFC4861] Prefix Information
1425  Option)
1426 
1427  WellKnown (Specified by a standards organization, e.g. fe80::/10 for link-local addresses,
1428  or ::1/128 for the loopback address, both of which are defined in [RFC4291])
1429 
1430  Static (Created by the ACS, by some other management entity (e.g. via a GUI), or present in
1431  the factory default configuration (but not WellKnown). Unrelated to any shorter length
1432  prefix that might exist on the CPE. Also see StaticType. Can be used for RA (Prefix
1433  Information), DHCPv6 address assignment (IA_NA) or DHCPv6 prefix delegation (IA_PD))
1434 
1435  Child (Derived from an associated AutoConfigured or PrefixDelegation parent prefix. Also
1436  see StaticType, ParentPrefix and ChildPrefixBits. Can be used for RA (Prefix Information),
1437  DHCPv6 address assignment (IA_NA) or DHCPv6 prefix delegation (IA_PD))
1438 
1439  Note that:
1440  PrefixDelegation and RouterAdvertisement prefixes can exist only on upstream interfaces
1441  (i.e. interfaces for which the physical layer interface object has Upstream = true),
1442  AutoConfigured and WellKnown prefixes can exist on any interface, and
1443  Static and Child prefixes can exist only on downstream interfaces (i.e. interfaces for
1444  which the physical layer interface object has Upstream = false).
1445 
1446  Also note that a Child prefix's ParentPrefix will always be an AutoConfigured, PrefixDelegation,
1447  or RouterAdvertisement prefix.
1448 
1449  This parameter is based on ipAddressOrigin from [RFC4293].
1450 */
1451 
1452  // verify we have an IPv6 address for the given instance
1453  struct in6_addr in6_address;
1454  struct in6_addr in6_mask;
1455  errno_t rc = -1;
1456  if (OK != getIPv6AddressAndMask (instance, in6_address, in6_mask))
1457  return NOK;
1458 
1459  if (hostIf_IPInterface::isLoopback (nameOfInterface) || isLinkLocalAddress (in6_address))
1460  {
1461  rc=strcpy_s (origin,BUFF_LENGTH_32, WELLKNOWN); // "WellKnown" for loopback and link-local addresses
1462  if(rc!=EOK)
1463  {
1464  ERR_CHK(rc);
1465  }
1466  }
1467  else
1468  {
1469  rc=strcpy_s (origin,BUFF_LENGTH_32, AUTOCONFIGURED); // "AutoConfigured" - otherwise (assume)
1470  if(rc!=EOK)
1471  {
1472  ERR_CHK(rc);
1473  }
1474  // TODO: for a gateway, this should be "PrefixDelegation" (Delegated via DHCPv6)
1475  }
1476  return OK;
1477 }
1478 
1479 int hostIf_IPv6Address::get_IPv6Prefix_Origin(HOSTIF_MsgData_t *stMsgData,int subInstanceNo, bool *pChanged)
1480 {
1481  LOG_ENTRY_EXIT;
1482 
1483  char origin[BUFF_LENGTH_32];
1484  if (OK != get_IPv6Prefix_Origin (subInstanceNo, origin))
1485  return NOK;
1486 
1487  // TODO: use a variable other than bCalledOrigin which is for IPv6Address profile
1488  if (bCalledOrigin && pChanged && strncmp (origin, backupIPv6PrefixOrigin, BUFF_LENGTH_32))
1489  {
1490  *pChanged = true;
1491  }
1492  bCalledOrigin = true;
1493  strncpy (backupIPv6PrefixOrigin, origin, sizeof(backupIPv6PrefixOrigin) -1); //CID:136504 - Buffer size warning
1494  backupIPv6PrefixOrigin[sizeof(backupIPv6PrefixOrigin) -1] = '\0';
1495  strncpy (stMsgData->paramValue, origin, BUFF_LENGTH_32);
1496  stMsgData->paramtype = hostIf_StringType;
1497  stMsgData->paramLen = strlen (origin);
1498 
1499  return OK;
1500 }
1501 
1502 int hostIf_IPv6Address::get_IPv6Prefix_StaticType (int instance, char* staticType)
1503 {
1504  LOG_ENTRY_EXIT;
1505 
1506 /*
1507  Static prefix sub-type. For a Static prefix, this can be set to PrefixDelegation or Child, thereby creating an
1508  unconfigured prefix of the specified type that will be populated in preference to creating a new instance. This
1509  allows the ACS to pre-create "prefix slots" with known path names that can be referenced from elsewhere in the data
1510  model before they have been populated. Enumeration of:
1511 
1512  Static (Prefix is a "normal" Static prefix)
1513 
1514  Inapplicable (Prefix is not Static, so this parameter does not apply, READONLY)
1515 
1516  PrefixDelegation (Prefix will be populated when a PrefixDelegation prefix needs to be created)
1517 
1518  Child (Prefix will be populated when a Child prefix needs to be created. In this case, the ACS needs also to set
1519  ParentPrefix and might want to set ChildPrefixBits (if parent prefix is not set, or goes away, then the child
1520  prefix will become operationally disabled))
1521 
1522  This mechanism works as follows:
1523 
1524  When this parameter is set to PrefixDelegation or Child, the instance becomes a "prefix slot" of the specified
1525  type.
1526  Such an instance can be administratively enabled (Enable = true) but will remain operationally disabled (Status
1527  = Disabled) until it has been populated.
1528  When a new prefix of of type T is needed, the CPE will look for a matching unpopulated instance, i.e. an
1529  instance with (Origin,StaticType,Prefix) = (Static,T,""). If the CPE finds at least one such instance it will
1530  choose one and populate it. If already administratively enabled it will immediately become operationally
1531  enabled. If the CPE finds no such instances, it will create and populate a new instance with (Origin,StaticType)
1532  = (T,T). If the CPE finds more than one such instance, the algorithm via which it chooses which instance to
1533  populate is implementation-specific.
1534  When a prefix that was populated via this mechanism becomes invalid, the CPE will reset Prefix to an empty
1535  string. This does not affect the value of the Enable parameter.
1536 
1537  The prefix StaticType can only be modified if Origin is Static.
1538 */
1539 
1540  // first check if the StaticType parameter is relevant
1541 
1542  char origin[BUFF_LENGTH_32];
1543  errno_t rc = -1;
1544  if (OK != get_IPv6Prefix_Origin (instance, origin))
1545  {
1546  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Error retrieving IPv6Prefix Origin\n", __FUNCTION__);
1547  return NOK;
1548  }
1549 
1550  // if Prefix is not Static, this parameter does not apply and StaticType should be set to "Inapplicable"
1551  if (strcasecmp (origin, STATIC) != 0)
1552  {
1553  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "%s: StaticType = Inapplicable (IPv6Prefix origin not Static)\n", __FUNCTION__);
1554  rc=strcpy_s (staticType,BUFF_LENGTH_32, INAPPLICABLE);
1555  if(rc!=EOK)
1556  {
1557  ERR_CHK(rc);
1558  }
1559  return OK;
1560  }
1561 
1562  // TODO: Implement StaticType
1563  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1564  rc=strcpy_s (staticType,BUFF_LENGTH_32, NOT_IMPLEMENTED);
1565  if(rc!=EOK)
1566  {
1567  ERR_CHK(rc);
1568  }
1569  return OK;
1570 }
1571 
1572 int hostIf_IPv6Address::get_IPv6Prefix_StaticType (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1573 {
1574  LOG_ENTRY_EXIT;
1575  errno_t rc = -1;
1576 
1577  char staticType[BUFF_LENGTH_32];
1578  if (OK != get_IPv6Prefix_StaticType (subInstanceNo, staticType))
1579  {
1580  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Error retrieving IPv6Prefix StaticType\n", __FUNCTION__);
1581  return NOK;
1582  }
1583 
1584  rc=strcpy_s (stMsgData->paramValue,sizeof(stMsgData->paramValue), staticType);
1585  if(rc!=EOK)
1586  {
1587  ERR_CHK(rc);
1588  }
1589  stMsgData->paramtype = hostIf_StringType;
1590  stMsgData->paramLen = strlen (staticType);
1591 
1592  return OK;
1593 }
1594 
1595 int hostIf_IPv6Address::get_IPv6Prefix_ParentPrefix (int instance, char* parentPrefix)
1596 {
1597  LOG_ENTRY_EXIT;
1598 
1599 /*
1600  The value MUST be the path name of a row in the IP.Interface.{i}.IPv6Prefix table. If the referenced object is
1601  deleted, the parameter value MUST be set to an empty string. Indicates the parent prefix from which this prefix was
1602  derived. The parent prefix is relevant only for Child prefixes and for Static Child prefixes (both of which will
1603  always be on downstream interfaces), i.e. for Origin=Child and for (Origin,StaticType) = (Static,Child) prefixes.
1604 
1605  This parameter can only be modified if Origin is Static (which makes sense only for a prefix whose StaticType is
1606  already or will be changed to Child).
1607 */
1608 
1609  // first check if the ParentPrefix parameter is relevant
1610 
1611  errno_t rc = -1;
1612  char origin[BUFF_LENGTH_32];
1613  if (OK != get_IPv6Prefix_Origin (instance, origin))
1614  return NOK;
1615 
1616  bool relevant = false;
1617  if (strcasecmp (origin, CHILD) == 0)
1618  {
1619  relevant = true;
1620  }
1621  else
1622  {
1623  char staticType[BUFF_LENGTH_32];
1624  if (OK != get_IPv6Prefix_StaticType (instance, staticType))
1625  return NOK;
1626  if (strcasecmp (staticType, CHILD) == 0)
1627  relevant = true;
1628  }
1629 
1630  if (!relevant)
1631  {
1632  parentPrefix[0]='\0';
1633  return OK;
1634  }
1635 
1636  // TODO: Implement ParentPrefix
1637  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1638  rc=strcpy_s (parentPrefix,BUFF_LENGTH_64, NOT_IMPLEMENTED);
1639  if(rc!=EOK)
1640  {
1641  ERR_CHK(rc);
1642  }
1643 
1644 
1645  return OK;
1646 }
1647 
1648 int hostIf_IPv6Address::get_IPv6Prefix_ParentPrefix (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1649 {
1650  LOG_ENTRY_EXIT;
1651 
1652  errno_t rc = -1;
1653  char parentPrefix[BUFF_LENGTH_64];
1654  if (OK != get_IPv6Prefix_ParentPrefix (subInstanceNo, parentPrefix))
1655  return NOK;
1656 
1657  rc=strcpy_s (stMsgData->paramValue,sizeof(stMsgData->paramValue), parentPrefix);
1658  if(rc!=EOK)
1659  {
1660  ERR_CHK(rc);
1661  }
1662  stMsgData->paramtype = hostIf_StringType;
1663  stMsgData->paramLen = strlen (parentPrefix);
1664 
1665  return OK;
1666 }
1667 
1668 int hostIf_IPv6Address::get_IPv6Prefix_ChildPrefixBits (int instance, char* childPrefixBits)
1669 {
1670  LOG_ENTRY_EXIT;
1671 
1672 /*
1673  [IPv6Prefix] A prefix that specifies the length of Static Child prefixes and how they are derived from their
1674  ParentPrefix. It will be used if and only if it is not an empty string and is longer than the parent prefix (if it
1675  is not used, derivation of such prefixes is implementation-specific). Any bits to the right of the parent prefix
1676  are set to the bits in this prefix.
1677 
1678  For example, for a parent prefix of fedc::/56, if this parameter had the value 123:4567:89ab:cdef::/64, the child
1679  /64 would be fedc:0:0:ef::/64. For a parent prefix of fedc::/60, the child /64 would be fedc:0:0:f::/64.
1680 
1681  This parameter can only be modified if Origin is Static.
1682 */
1683 
1684  errno_t rc = -1;
1685  char staticType[BUFF_LENGTH_32];
1686  if (OK != get_IPv6Prefix_StaticType (instance, staticType))
1687  return NOK;
1688 
1689  if (strcasecmp (staticType, CHILD) != 0)
1690  {
1691  childPrefixBits[0]='\0';
1692  return OK;
1693  }
1694 
1695  // TODO: Implement ChildPrefixBits
1696  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1697  rc=strcpy_s (childPrefixBits,BUFF_LENGTH_64, NOT_IMPLEMENTED);
1698  if(rc!=EOK)
1699  {
1700  ERR_CHK(rc);
1701  }
1702  return OK;
1703 }
1704 
1705 int hostIf_IPv6Address::get_IPv6Prefix_ChildPrefixBits (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1706 {
1707  LOG_ENTRY_EXIT;
1708 
1709  errno_t rc = -1;
1710  char childPrefixBits[BUFF_LENGTH_64];
1711  if (OK != get_IPv6Prefix_ChildPrefixBits (subInstanceNo, childPrefixBits))
1712  return NOK;
1713 
1714  rc=strcpy_s (stMsgData->paramValue,sizeof(stMsgData->paramValue), childPrefixBits);
1715  if(rc!=EOK)
1716  {
1717  ERR_CHK(rc);
1718  }
1719  stMsgData->paramtype = hostIf_StringType;
1720  stMsgData->paramLen = strlen (childPrefixBits);
1721 
1722  return OK;
1723 }
1724 
1725 int hostIf_IPv6Address::get_IPv6Prefix_OnLink (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1726 {
1727 /*
1728  On-link flag [Section 4.6.2/RFC4861] as received (in the RA) for RouterAdvertisement. Indicates whether this prefix
1729  can be used for on-link determination.
1730 
1731  This parameter can only be modified if Origin is Static.
1732 
1733  This parameter is based on ipAddressPrefixOnLinkFlag from [RFC4293].
1734 */
1735 
1736  LOG_ENTRY_EXIT;
1737 
1738  put_int(stMsgData->paramValue, false);
1739  stMsgData->paramtype = hostIf_BooleanType;
1740  stMsgData->paramLen = sizeof(bool);
1741 
1742  return OK;
1743 }
1744 
1745 int hostIf_IPv6Address::get_IPv6Prefix_Autonomous (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1746 {
1747 /*
1748  Autonomous address configuration flag [Section 4.6.2/RFC4861] as received (in the RA) for RouterAdvertisement.
1749  Indicates whether this prefix can be used for generating global addresses as specified by SLAAC [RFC4862].
1750 
1751  This parameter can only be modified if Origin is Static.
1752 
1753  This parameter is based on ipAddressPrefixAutonomousFlag from [RFC4293].
1754 */
1755 
1756  LOG_ENTRY_EXIT;
1757 
1758  put_int(stMsgData->paramValue, false);
1759  stMsgData->paramtype = hostIf_BooleanType;
1760  stMsgData->paramLen = sizeof(bool);
1761 
1762  return OK;
1763 }
1764 
1765 int hostIf_IPv6Address::get_IPv6Prefix_PreferredLifetime (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1766 {
1767 /*
1768  This parameter is based on ipAddressPrefixAdvPreferredLifetime from [RFC4293]. The time at which this prefix will
1769  cease to be preferred (i.e. will become deprecated), or 0001-01-01T00:00:00Z if not known. For an infinite lifetime,
1770  the parameter value MUST be 9999-12-31T23:59:59Z.
1771 
1772  This parameter can only be modified if Origin is Static.
1773 */
1774 
1775  LOG_ENTRY_EXIT;
1776 
1777  return get_IPv6Address_PreferredLifetime (stMsgData, subInstanceNo, pChanged);
1778 }
1779 
1780 int hostIf_IPv6Address::get_IPv6Prefix_ValidLifetime (HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged)
1781 {
1782 /*
1783  This parameter is based on ipAddressPrefixAdvValidLifetime from [RFC4293]. The time at which this prefix will cease
1784  to be valid (i.e. will become invalid), or 0001-01-01T00:00:00Z if not known. For an infinite lifetime, the
1785  parameter value MUST be 9999-12-31T23:59:59Z.
1786 
1787  This parameter can only be modified if Origin is Static.
1788 */
1789  LOG_ENTRY_EXIT;
1790 
1791  return get_IPv6Address_ValidLifetime (stMsgData, subInstanceNo, pChanged);
1792 }
1793 
1794 
1795 /****************************************************************************************************************************************************/
1796 // Device_IP_Interface_IPv6Address Profile. Setters:
1797 /****************************************************************************************************************************************************/
1798 
1799 /**
1800  * @brief This function enables or disables this IPv6 address. Currently not
1801  * implemented.
1802  *
1803  * @param[out] stMsgData TR-069 Host interface message request.
1804  * @param[in] subInstanceNo SubInstance number currently not in use.
1805  *
1806  * @return Returns the status of the operation.
1807  *
1808  * @retval OK if successfully fetch the data from the device.
1809  * @retval ERR_INTERNAL_ERROR if not able to fetch the data.
1810  * @retval NOK if it is not handle.
1811  * @ingroup TR69_HOSTIF_DEVICE_IPv6_INTERFACE_ADDRESS_API
1812  */
1814 {
1815  LOG_ENTRY_EXIT;
1816  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1817  return NOK;
1818 }
1819 
1820 /**
1821  * @brief This function sets a non-volatile handle used to reference this IPv6 address
1822  * instance of this IP interface. Alias provides a mechanism for an ACS to label this
1823  * instance for future reference.
1824  *
1825  * @note If the CPE supports the Alias-based Addressing feature as defined in
1826  * [Section 3.6.1/TR-069 Amendment 4] and described in [Appendix II/TR-069
1827  * Amendment 4], the following mandatory constraints MUST be enforced:
1828  * - Its value MUST NOT be empty.
1829  * - Its value MUST start with a letter.
1830  * - If its instance object is created by the CPE, the initial
1831  * value MUST start with a "cpe-" prefix.
1832  * - The CPE MUST NOT change the parameter value.
1833  *
1834  * @param[out] stMsgData TR-069 Host interface message request.
1835  * @param[in] subInstanceNo SubInstance number currently not in use.
1836  *
1837  * @return Returns the status of the operation.
1838  *
1839  * @retval OK if successfully fetch the data from the device.
1840  * @retval ERR_INTERNAL_ERROR if not able to fetch the data.
1841  * @retval NOK if it is not handle.
1842  * @ingroup TR69_HOSTIF_DEVICE_IPv6_INTERFACE_ADDRESS_API
1843  */
1845 {
1846  LOG_ENTRY_EXIT;
1847  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1848  return NOK;
1849 }
1850 
1851 /**
1852  * @brief This function sets the IPv6 address.
1853  *
1854  * @note This parameter can only be modified if the Origin is <tt>Static</tt>.
1855  *
1856  * @param[out] stMsgData TR-069 Host interface message request.
1857  * @param[in] subInstanceNo SubInstance number currently not in use.
1858  *
1859  * @return Returns the status of the operation.
1860  *
1861  * @retval OK if successfully fetch the data from the device.
1862  * @retval ERR_INTERNAL_ERROR if not able to fetch the data.
1863  * @retval NOK if it is not handle.
1864  * @ingroup TR69_HOSTIF_DEVICE_IPv6_INTERFACE_ADDRESS_API
1865  */
1867 {
1868  LOG_ENTRY_EXIT;
1869 
1870  /*
1871  * Getting IPV6 info for the supplied instance
1872  */
1873  struct in6_addr in6_address;
1874  struct in6_addr in6_mask;
1875  int rc = getIPv6AddressAndMask (subInstanceNo, in6_address, in6_mask);
1876 
1877  char ipAddress[BUFF_LENGTH_64];
1878  inet_ntop (AF_INET6, &in6_address, ipAddress, BUFF_LENGTH_64);
1879 
1880  /*
1881  * If IPV6 address has already been available, remove it.
1882  */
1883  if (OK == rc && (strcmp (ipAddress, "") != 0))
1884  {
1885  rc = removeIp (dev_id, ipAddress);
1886  }
1887 
1888  /*
1889  * Assign a new IP address
1890  */
1891  if (OK == rc)
1892  {
1893  rc = setIp (dev_id, stMsgData->paramValue);
1894  }
1895 
1896  return rc;
1897 }
1898 
1899 /* End of doxygen group */
1900 /**
1901  * @}
1902  */
1903 
1904 int hostIf_IPv6Address::set_IPv6Address_Prefix (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1905 {
1906  LOG_ENTRY_EXIT;
1907  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1908  return NOK;
1909 }
1910 
1911 int hostIf_IPv6Address::set_IPv6Address_PreferredLifetime (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1912 {
1913  LOG_ENTRY_EXIT;
1914  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1915  return NOK;
1916 }
1917 
1918 int hostIf_IPv6Address::set_IPv6Address_ValidLifetime (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1919 {
1920  LOG_ENTRY_EXIT;
1921  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1922  return NOK;
1923 }
1924 
1925 int hostIf_IPv6Address::set_IPv6Address_Anycast (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1926 {
1927  LOG_ENTRY_EXIT;
1928  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1929  return NOK;
1930 }
1931 
1932 int hostIf_IPv6Address::set_IPv6Prefix_Enable (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1933 {
1934  LOG_ENTRY_EXIT;
1935  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1936  return NOK;
1937 }
1938 
1939 int hostIf_IPv6Address::set_IPv6Prefix_Alias (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1940 {
1941  LOG_ENTRY_EXIT;
1942  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1943  return NOK;
1944 }
1945 
1946 int hostIf_IPv6Address::set_IPv6Prefix_Prefix (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1947 {
1948  LOG_ENTRY_EXIT;
1949  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1950  return NOK;
1951 }
1952 
1953 int hostIf_IPv6Address::set_IPv6Prefix_StaticType (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1954 {
1955  LOG_ENTRY_EXIT;
1956  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1957  return NOK;
1958 }
1959 
1960 int hostIf_IPv6Address::set_IPv6Prefix_ParentPrefix (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1961 {
1962  LOG_ENTRY_EXIT;
1963  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1964  return NOK;
1965 }
1966 
1967 int hostIf_IPv6Address::set_IPv6Prefix_ChildPrefixBits (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1968 {
1969  LOG_ENTRY_EXIT;
1970  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1971  return NOK;
1972 }
1973 
1974 int hostIf_IPv6Address::set_IPv6Prefix_OnLink (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1975 {
1976  LOG_ENTRY_EXIT;
1977  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1978  return NOK;
1979 }
1980 
1981 int hostIf_IPv6Address::set_IPv6Prefix_Autonomous (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1982 {
1983  LOG_ENTRY_EXIT;
1984  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1985  return NOK;
1986 }
1987 
1988 int hostIf_IPv6Address::set_IPv6Prefix_PreferredLifetime (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1989 {
1990  LOG_ENTRY_EXIT;
1991  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1992  return NOK;
1993 }
1994 
1995 int hostIf_IPv6Address::set_IPv6Prefix_ValidLifetime (HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
1996 {
1997  LOG_ENTRY_EXIT;
1998  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Not Implemented\n", __FUNCTION__);
1999  return NOK;
2000 }
hostIf_IPv6Address::set_IPv6Address_Enable
int set_IPv6Address_Enable(HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
Enable/Disable an IP Interface IPv6 Address.
Definition: Device_IP_Interface_IPv6Address.cpp:1813
hostIf_IPv6Address::set_IPv6Address_Alias
int set_IPv6Address_Alias(HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
Set the instance handle for an IPv6 Address of an IP Interface.
Definition: Device_IP_Interface_IPv6Address.cpp:1844
hostIf_IPv6Address::isLinkLocalAddress
static bool isLinkLocalAddress(const struct in6_addr &in6_address)
tests if an IPv6 address is link-local.
Definition: Device_IP_Interface_IPv6Address.cpp:485
hostIf_IPv6Address::get_IPv6Address_IPAddress
int get_IPv6Address_IPAddress(HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged=NULL)
This function provides the IPv6 address.
Definition: Device_IP_Interface_IPv6Address.cpp:863
_HostIf_MsgData_t
Definition: hostIf_tr69ReqHandler.h:170
hostIf_IPv6Address::get_ipv6address_lifetime
bool get_ipv6address_lifetime(unsigned int instance, char *search_string, long int &lifetime)
Definition: Device_IP_Interface_IPv6Address.cpp:1105
Device_IP_Interface.h
The header file provides TR069 device IP interface information APIs.
hostIf_IPv6Address::get_ipv6address_valid_lifetime
bool get_ipv6address_valid_lifetime(unsigned int instance, long int &valid_lifetime)
Definition: Device_IP_Interface_IPv6Address.cpp:1191
hostIf_IPv6Address
This class provides the hostIf IP interface for getting IPv6 interface information.
Definition: Device_IP_Interface_IPv6Address.h:81
Device_IP_Interface_Stats.h
The header file provides TR069 device IP interface stats information APIs.
_HostIf_MsgData_t::paramtype
HostIf_ParamType_t paramtype
Definition: hostIf_tr69ReqHandler.h:177
hostIf_IP::getInterfaceName
static char * getInterfaceName(int if_index, char *if_name)
Definition: Device_IP.cpp:183
RDK_LOG
#define RDK_LOG
Definition: rdk_debug.h:258
_HostIf_MsgData_t::faultCode
faultCode_t faultCode
Definition: hostIf_tr69ReqHandler.h:179
hostIf_IPv6Address::get_IPv6Address_Origin
int get_IPv6Address_Origin(HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged=NULL)
This function provides the addressing method used to assign the IP address. The Possible enum vlaues.
Definition: Device_IP_Interface_IPv6Address.cpp:911
_HostIf_MsgData_t::paramName
char paramName[(4 *1024)]
Definition: hostIf_tr69ReqHandler.h:171
hostIf_IPv6Address::get_IPv6Address_Status
int get_IPv6Address_Status(HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged=NULL)
This function provides the status of this IPv6Address table entry. Possible values.
Definition: Device_IP_Interface_IPv6Address.cpp:695
hostIf_IPv6Address::get_IPv6Address_Alias
int get_IPv6Address_Alias(HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged=NULL)
This function provides a non-volatile handle used to reference this IPv6 address instance of this IP ...
Definition: Device_IP_Interface_IPv6Address.cpp:840
_HostIf_MsgData_t::paramValue
char paramValue[(4 *1024)]
Definition: hostIf_tr69ReqHandler.h:172
Device_IP.h
The header file provides TR069 device IP information APIs.
hostIf_IPv6Address::get_IPv6Address_Enable
int get_IPv6Address_Enable(HOSTIF_MsgData_t *stMsgData, int subInstanceNo, bool *pChanged=NULL)
This function provides the value 'true' or 'false' for Enable status of IPv6 address.
Definition: Device_IP_Interface_IPv6Address.cpp:653
hostIf_IPv6Address::get_ipv6address_preferred_lifetime
bool get_ipv6address_preferred_lifetime(unsigned int instance, long int &preferred_lifetime)
Definition: Device_IP_Interface_IPv6Address.cpp:1176
Device_IP_Interface_IPv6Address.h
The header file provides TR069 device IPv6 interface address information APIs.
hostIf_IPv6Address::set_IPv6Address_IPAddress
int set_IPv6Address_IPAddress(HOSTIF_MsgData_t *stMsgData, int subInstanceNo)
Set an IP Interface IPv6 Address.
Definition: Device_IP_Interface_IPv6Address.cpp:1866
put_int
void put_int(char *ptr, int val)
This function converts the input data to integer type.
Definition: hostIf_utils.cpp:152
in6_ifreq
The structure holds the required parameters such as IPv6 address,interface index etc....
Definition: Device_IP_Interface_IPv6Address.cpp:54
_HostIf_MsgData_t::paramLen
short paramLen
Definition: hostIf_tr69ReqHandler.h:175