@@ -684,7 +684,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
684684
685685 adv .mtu .nd_opt_mtu_mtu = htonl (iface -> ra_mtu );
686686
687- iov [IOV_RA_ADV ].iov_base = ( char * ) & adv ;
687+ iov [IOV_RA_ADV ].iov_base = & adv ;
688688 iov [IOV_RA_ADV ].iov_len = sizeof (adv );
689689
690690 valid_addr_cnt = (iface -> timer_rs .cb /* if not shutdown */ ? iface -> addr6_len : 0 );
@@ -735,6 +735,10 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
735735 }
736736
737737 /* Construct Prefix Information options */
738+ if (total_addr_cnt > 0 ) {
739+ pfxs = alloca (total_addr_cnt * sizeof (* pfxs ));
740+ memset (pfxs , 0 , total_addr_cnt * sizeof (* pfxs ));
741+ }
738742 for (size_t i = 0 ; i < total_addr_cnt ; ++ i ) {
739743 struct odhcpd_ipaddr * addr = & addrs [i ];
740744 struct nd_opt_prefix_info * p = NULL ;
@@ -762,19 +766,8 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
762766 p = & pfxs [j ];
763767 }
764768
765- if (!p ) {
766- struct nd_opt_prefix_info * tmp ;
767-
768- tmp = realloc (pfxs , sizeof (* pfxs ) * (pfxs_cnt + 1 ));
769- if (!tmp ) {
770- error ("Realloc failed for RA prefix option on %s" , iface -> name );
771- continue ;
772- }
773-
774- pfxs = tmp ;
769+ if (!p )
775770 p = & pfxs [pfxs_cnt ++ ];
776- memset (p , 0 , sizeof (* p ));
777- }
778771
779772 if (addr -> preferred_lt > (uint32_t )now ) {
780773 preferred_lt = TIME_LEFT (addr -> preferred_lt , now );
@@ -860,7 +853,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
860853
861854 router_clear_duplicated_ra_pio (iface );
862855
863- iov [IOV_RA_PFXS ].iov_base = ( char * ) pfxs ;
856+ iov [IOV_RA_PFXS ].iov_base = pfxs ;
864857 iov [IOV_RA_PFXS ].iov_len = pfxs_cnt * sizeof (* pfxs );
865858
866859 /* Calculate periodic transmit */
@@ -938,9 +931,9 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
938931 }
939932 }
940933
941- iov [IOV_RA_DNS ].iov_base = ( char * ) dns ;
934+ iov [IOV_RA_DNS ].iov_base = dns ;
942935 iov [IOV_RA_DNS ].iov_len = dns_sz ;
943- iov [IOV_RA_SEARCH ].iov_base = ( char * ) search ;
936+ iov [IOV_RA_SEARCH ].iov_base = search ;
944937 iov [IOV_RA_SEARCH ].iov_len = search_sz ;
945938
946939 if (iface -> pref64_length ) {
@@ -955,7 +948,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
955948 (0x7 & iface -> pref64_plc ));
956949 memcpy (pref64 -> prefix , iface -> pref64_prefix , sizeof (pref64 -> prefix ));
957950 }
958- iov [IOV_RA_PREF64 ].iov_base = ( char * ) pref64 ;
951+ iov [IOV_RA_PREF64 ].iov_base = pref64 ;
959952 iov [IOV_RA_PREF64 ].iov_len = pref64_sz ;
960953
961954 if (iface -> dnr_cnt ) {
@@ -1003,7 +996,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
1003996 memcpy (tmp , iface -> dnr [i ].svc , iface -> dnr [i ].svc_len );
1004997 }
1005998 }
1006- iov [IOV_RA_DNR ].iov_base = ( char * ) dnrs ;
999+ iov [IOV_RA_DNR ].iov_base = dnrs ;
10071000 iov [IOV_RA_DNR ].iov_len = dnrs_sz ;
10081001
10091002 /*
@@ -1015,25 +1008,26 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
10151008 * independent of having or not having IPv6 connectivity on the
10161009 * WAN interface.
10171010 */
1018-
1011+ if (valid_addr_cnt > 0 ) {
1012+ routes = alloca (valid_addr_cnt * sizeof (* routes ));
1013+ memset (routes , 0 , valid_addr_cnt * sizeof (* routes ));
1014+ }
10191015 for (size_t i = 0 ; i < valid_addr_cnt ; ++ i ) {
10201016 struct odhcpd_ipaddr * addr = & addrs [i ];
1021- struct nd_opt_route_info * tmp ;
10221017 uint32_t valid_lt ;
10231018
10241019 if (addr -> dprefix_len >= 64 || addr -> dprefix_len == 0 || addr -> valid_lt <= (uint32_t )now ) {
10251020 info ("Address %s (dprefix %d, valid-lifetime %u) not suitable as RA route on %s" ,
10261021 inet_ntop (AF_INET6 , & addr -> addr .in6 , buf , sizeof (buf )),
10271022 addr -> dprefix_len , addr -> valid_lt , iface -> name );
1028-
1029- continue ; /* Address not suitable */
1023+ continue ;
10301024 }
10311025
10321026 if (ADDR_MATCH_PIO_FILTER (addr , iface )) {
10331027 info ("Address %s filtered out as RA route on %s" ,
10341028 inet_ntop (AF_INET6 , & addr -> addr .in6 , buf , sizeof (buf )),
10351029 iface -> name );
1036- continue ; /* PIO filtered out of this RA */
1030+ continue ;
10371031 }
10381032
10391033 if (addr -> dprefix_len > 32 ) {
@@ -1043,15 +1037,6 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
10431037 addr -> addr .in6 .s6_addr32 [1 ] = 0 ;
10441038 }
10451039
1046- tmp = realloc (routes , sizeof (* routes ) * (routes_cnt + 1 ));
1047- if (!tmp ) {
1048- error ("Realloc failed for RA route option on %s" , iface -> name );
1049- continue ;
1050- }
1051-
1052- routes = tmp ;
1053-
1054- memset (& routes [routes_cnt ], 0 , sizeof (* routes ));
10551040 routes [routes_cnt ].type = ND_OPT_ROUTE_INFO ;
10561041 routes [routes_cnt ].len = sizeof (* routes ) / 8 ;
10571042 routes [routes_cnt ].prefix_len = addr -> dprefix_len ;
@@ -1070,22 +1055,20 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
10701055 routes [routes_cnt ].addr [2 ] = 0 ;
10711056 routes [routes_cnt ].addr [3 ] = 0 ;
10721057
1073- ++ routes_cnt ;
1058+ routes_cnt ++ ;
10741059 }
1075-
1076- iov [IOV_RA_ROUTES ].iov_base = (char * )routes ;
1060+ iov [IOV_RA_ROUTES ].iov_base = routes ;
10771061 iov [IOV_RA_ROUTES ].iov_len = routes_cnt * sizeof (* routes );
10781062
10791063 memset (& adv_interval , 0 , sizeof (adv_interval ));
10801064 adv_interval .nd_opt_adv_interval_type = ND_OPT_RTR_ADV_INTERVAL ;
10811065 adv_interval .nd_opt_adv_interval_len = 1 ;
10821066 adv_interval .nd_opt_adv_interval_ival = htonl (maxival * 1000 );
10831067
1084- iov [IOV_RA_ADV_INTERVAL ].iov_base = ( char * ) & adv_interval ;
1068+ iov [IOV_RA_ADV_INTERVAL ].iov_base = & adv_interval ;
10851069 iov [IOV_RA_ADV_INTERVAL ].iov_len = adv_interval .nd_opt_adv_interval_len * 8 ;
10861070
10871071 /* RFC 8910 Captive Portal */
1088- uint8_t * captive_portal_uri = (uint8_t * )iface -> captive_portal_uri ;
10891072 if (iface -> captive_portal_uri_len > 0 ) {
10901073 /* compute pad so that (header + data + pad) is a multiple of 8 */
10911074 capt_portal_sz = (sizeof (struct nd_opt_capt_portal ) + iface -> captive_portal_uri_len + 7 ) & ~7 ;
@@ -1096,7 +1079,7 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
10961079 capt_portal -> type = ND_OPT_CAPTIVE_PORTAL ;
10971080 capt_portal -> len = capt_portal_sz / 8 ;
10981081
1099- memcpy (capt_portal -> data , captive_portal_uri , iface -> captive_portal_uri_len );
1082+ memcpy (capt_portal -> data , iface -> captive_portal_uri , iface -> captive_portal_uri_len );
11001083 /* remaining padding bytes already set to 0x00 */
11011084 }
11021085
@@ -1120,9 +1103,6 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
11201103 }
11211104
11221105out :
1123- free (pfxs );
1124- free (routes );
1125-
11261106 return msecs ;
11271107}
11281108
0 commit comments