+ msg_data += sizeof(struct olsr_hna6);
+ msg_tlen -= sizeof(struct olsr_hna6);
+ }
+ } else {
+ int col = 0;
+
+ ND_PRINT("\n\t Advertised networks (total %u)",
+ (unsigned int) (msg_tlen / sizeof(struct olsr_hna4)));
+
+ while (msg_tlen >= sizeof(struct olsr_hna4)) {
+ ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hna4));
+
+ ptr.hna = (const struct olsr_hna4 *)msg_data;
+
+ /* print 4 prefixes per line */
+ if (!ptr.hna->network[0] && !ptr.hna->network[1] &&
+ !ptr.hna->network[2] && !ptr.hna->network[3] &&
+ !ptr.hna->mask[GW_HNA_PAD] &&
+ ptr.hna->mask[GW_HNA_FLAGS]) {
+ /* smart gateway */
+ ND_PRINT("%sSmart-Gateway:%s%s%s%s%s %u/%u",
+ col == 0 ? "\n\t " : ", ", /* indent */
+ /* sgw */
+ /* LINKSPEED */
+ (ptr.hna->mask[GW_HNA_FLAGS] &
+ GW_HNA_FLAG_LINKSPEED) ? " LINKSPEED" : "",
+ /* IPV4 */
+ (ptr.hna->mask[GW_HNA_FLAGS] &
+ GW_HNA_FLAG_IPV4) ? " IPV4" : "",
+ /* IPV4-NAT */
+ (ptr.hna->mask[GW_HNA_FLAGS] &
+ GW_HNA_FLAG_IPV4_NAT) ? " IPV4-NAT" : "",
+ /* IPV6 */
+ (ptr.hna->mask[GW_HNA_FLAGS] &
+ GW_HNA_FLAG_IPV6) ? " IPV6" : "",
+ /* IPv6PREFIX */
+ (ptr.hna->mask[GW_HNA_FLAGS] &
+ GW_HNA_FLAG_IPV6PREFIX) ? " IPv6-PREFIX" : "",
+ /* uplink */
+ (ptr.hna->mask[GW_HNA_FLAGS] &
+ GW_HNA_FLAG_LINKSPEED) ?
+ deserialize_gw_speed(ptr.hna->mask[GW_HNA_UPLINK]) : 0,
+ /* downlink */
+ (ptr.hna->mask[GW_HNA_FLAGS] &
+ GW_HNA_FLAG_LINKSPEED) ?
+ deserialize_gw_speed(ptr.hna->mask[GW_HNA_DOWNLINK]) : 0
+ );
+ } else {
+ /* normal route */
+ ND_PRINT("%s%s/%u",
+ col == 0 ? "\n\t " : ", ",
+ GET_IPADDR_STRING(ptr.hna->network),
+ mask2plen(GET_BE_U_4(ptr.hna->mask)));
+ }
+
+ msg_data += sizeof(struct olsr_hna4);
+ msg_tlen -= sizeof(struct olsr_hna4);
+
+ col = (col + 1) % 4;
+ }