11cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger/*
21cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * Copyright (C)2005 USAGI/WIDE Project
3ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
41cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * This program is free software; you can redistribute it and/or modify
51cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * it under the terms of the GNU General Public License as published by
61cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * the Free Software Foundation; either version 2 of the License, or
71cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * (at your option) any later version.
8ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
91cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * This program is distributed in the hope that it will be useful,
101cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * but WITHOUT ANY WARRANTY; without even the implied warranty of
111cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
121cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * GNU General Public License for more details.
13ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
141cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * You should have received a copy of the GNU General Public License
151cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * along with this program; if not, write to the Free Software
161cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
171cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger */
181cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger/*
191cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * based on ip.c, iproute.c
201cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger */
211cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger/*
221cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger * Authors:
231cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger *	Masahide NAKAMURA @USAGI
241cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger */
251cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
261cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger#include <stdio.h>
271cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger#include <stdlib.h>
281cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger#include <string.h>
291cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger#include <netinet/icmp6.h>
301cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger#include "utils.h"
311cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
321cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger/* prefix flags; see kernel's net/ipv6/addrconf.c and include/net/if_inet6.h */
331cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger#define IF_PREFIX_ONLINK	0x01
341cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger#define IF_PREFIX_AUTOCONF	0x02
351cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
361cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemmingerint print_prefix(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
371cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger{
381cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	FILE *fp = (FILE*)arg;
391cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	struct prefixmsg *prefix = NLMSG_DATA(n);
401cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	int len = n->nlmsg_len;
411cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	struct rtattr * tb[RTA_MAX+1];
421cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	int family = preferred_family;
431cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
441cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (n->nlmsg_type != RTM_NEWPREFIX) {
451cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		fprintf(stderr, "Not a prefix: %08x %08x %08x\n",
461cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
471cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		return 0;
481cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
491cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
501cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	len -= NLMSG_LENGTH(sizeof(*prefix));
511cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (len < 0) {
521cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
531cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		return -1;
541cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
551cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
561cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (family == AF_UNSPEC)
571cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		family = AF_INET6;
581cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (family != AF_INET6)
591cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		return 0;
601cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
611cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (prefix->prefix_family != AF_INET6) {
621cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		fprintf(stderr, "wrong family %d\n", prefix->prefix_family);
631cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		return 0;
641cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
651cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (prefix->prefix_type != ND_OPT_PREFIX_INFORMATION) {
661cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		fprintf(stderr, "wrong ND type %d\n", prefix->prefix_type);
671cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		return 0;
681cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
691cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
701cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	parse_rtattr(tb, RTA_MAX, RTM_RTA(prefix), len);
711cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
721cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	fprintf(fp, "prefix ");
731cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
741cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (tb[PREFIX_ADDRESS]) {
751cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		struct in6_addr *pfx;
761cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		char abuf[256];
771cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
781cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		pfx = (struct in6_addr *)RTA_DATA(tb[PREFIX_ADDRESS]);
791cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
801cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		memset(abuf, '\0', sizeof(abuf));
81ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger		fprintf(fp, "%s", rt_addr_n2a(family, sizeof(*pfx), pfx,
821cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger					      abuf, sizeof(abuf)));
831cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
841cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	fprintf(fp, "/%u ", prefix->prefix_len);
851cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
861cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	fprintf(fp, "dev %s ", ll_index_to_name(prefix->prefix_ifindex));
871cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
881cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (prefix->prefix_flags & IF_PREFIX_ONLINK)
891cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		fprintf(fp, "onlink ");
901cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (prefix->prefix_flags & IF_PREFIX_AUTOCONF)
911cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		fprintf(fp, "autoconf ");
921cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
931cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (tb[PREFIX_CACHEINFO]) {
941cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		struct prefix_cacheinfo *pc;
95c13f598242dd2b108016367ab318f15b0cf4db44Christoph Biedl		pc = (struct prefix_cacheinfo *)RTA_DATA(tb[PREFIX_CACHEINFO]);
961cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
971cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		fprintf(fp, "valid %u ", pc->valid_time);
981cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		fprintf(fp, "preferred %u ", pc->preferred_time);
991cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
1001cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
1011cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	fprintf(fp, "\n");
1021cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	fflush(fp);
1031cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
1041cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	return 0;
1051cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger}
1061cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger
107