1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include "defs.h"
30 #include "tables.h"
31
32 static void print_opt(struct nd_opt_hdr *opt, int len);
33
34 void
print_route_sol(char * str,struct phyint * pi,struct nd_router_solicit * rs,int len,struct sockaddr_in6 * addr)35 print_route_sol(char *str, struct phyint *pi,
36 struct nd_router_solicit *rs, int len, struct sockaddr_in6 *addr)
37 {
38 struct nd_opt_hdr *opt;
39 char abuf[INET6_ADDRSTRLEN];
40
41 logmsg(LOG_DEBUG, "%s %s (%d bytes) on %s\n", str,
42 inet_ntop(addr->sin6_family, (void *)&addr->sin6_addr,
43 abuf, sizeof (abuf)),
44 len, pi->pi_name);
45
46 len -= sizeof (*rs);
47 opt = (struct nd_opt_hdr *)&rs[1];
48 print_opt(opt, len);
49 }
50
51 void
print_route_adv(char * str,struct phyint * pi,struct nd_router_advert * ra,int len,struct sockaddr_in6 * addr)52 print_route_adv(char *str, struct phyint *pi,
53 struct nd_router_advert *ra, int len, struct sockaddr_in6 *addr)
54 {
55 struct nd_opt_hdr *opt;
56 char abuf[INET6_ADDRSTRLEN];
57
58 logmsg(LOG_DEBUG, "%s %s (%d bytes) on %s\n", str,
59 inet_ntop(addr->sin6_family, (void *)&addr->sin6_addr,
60 abuf, sizeof (abuf)),
61 len, pi->pi_name);
62 logmsg(LOG_DEBUG, "\tMax hop limit: %u\n", ra->nd_ra_curhoplimit);
63 logmsg(LOG_DEBUG, "\tManaged address configuration: %s\n",
64 (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) ?
65 "Set" : "Not set");
66 logmsg(LOG_DEBUG, "\tOther configuration flag: %s\n",
67 (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) ?
68 "Set" : "Not set");
69 logmsg(LOG_DEBUG, "\tRouter lifetime: %u\n",
70 ntohs(ra->nd_ra_router_lifetime));
71 logmsg(LOG_DEBUG, "\tReachable timer: %u\n",
72 ntohl(ra->nd_ra_reachable));
73 logmsg(LOG_DEBUG, "\tReachable retrans timer: %u\n",
74 ntohl(ra->nd_ra_retransmit));
75
76 len -= sizeof (*ra);
77 opt = (struct nd_opt_hdr *)&ra[1];
78 print_opt(opt, len);
79 }
80
81 static void
print_opt(struct nd_opt_hdr * opt,int len)82 print_opt(struct nd_opt_hdr *opt, int len)
83 {
84 struct nd_opt_prefix_info *po;
85 struct nd_opt_mtu *mo;
86 struct nd_opt_lla *lo;
87 int optlen;
88 char abuf[INET6_ADDRSTRLEN];
89 char llabuf[BUFSIZ];
90
91 while (len >= sizeof (struct nd_opt_hdr)) {
92 optlen = opt->nd_opt_len * 8;
93 if (optlen == 0) {
94 logmsg(LOG_DEBUG, "Zero length option!\n");
95 break;
96 }
97 switch (opt->nd_opt_type) {
98 case ND_OPT_PREFIX_INFORMATION:
99 po = (struct nd_opt_prefix_info *)opt;
100 if (optlen != sizeof (*po) ||
101 optlen > len)
102 break;
103
104 logmsg(LOG_DEBUG, "\tPrefix: %s/%u\n",
105 inet_ntop(AF_INET6, (void *)&po->nd_opt_pi_prefix,
106 abuf, sizeof (abuf)),
107 po->nd_opt_pi_prefix_len);
108 logmsg(LOG_DEBUG, "\t\tOn link flag:%s\n",
109 (po->nd_opt_pi_flags_reserved &
110 ND_OPT_PI_FLAG_ONLINK) ?
111 "Set" : "Not set");
112 logmsg(LOG_DEBUG, "\t\tAuto addrconf flag:%s\n",
113 (po->nd_opt_pi_flags_reserved &
114 ND_OPT_PI_FLAG_AUTO) ?
115 "Set" : "Not set");
116 logmsg(LOG_DEBUG, "\t\tValid time: %u\n",
117 ntohl(po->nd_opt_pi_valid_time));
118 logmsg(LOG_DEBUG, "\t\tPreferred time: %u\n",
119 ntohl(po->nd_opt_pi_preferred_time));
120 break;
121 case ND_OPT_MTU:
122 mo = (struct nd_opt_mtu *)opt;
123 if (optlen != sizeof (*mo) ||
124 optlen > len)
125 break;
126 logmsg(LOG_DEBUG, "\tMTU: %d\n",
127 ntohl(mo->nd_opt_mtu_mtu));
128 break;
129 case ND_OPT_SOURCE_LINKADDR:
130 lo = (struct nd_opt_lla *)opt;
131 if (optlen < 8 ||
132 optlen > len)
133 break;
134 (void) fmt_lla(llabuf, sizeof (llabuf),
135 lo->nd_opt_lla_hdw_addr,
136 optlen - sizeof (nd_opt_hdr_t));
137 logmsg(LOG_DEBUG, "\tSource LLA: len %d <%s>\n",
138 optlen - sizeof (nd_opt_hdr_t),
139 llabuf);
140 break;
141 case ND_OPT_TARGET_LINKADDR:
142 lo = (struct nd_opt_lla *)opt;
143 if (optlen < 8||
144 optlen > len)
145 break;
146 (void) fmt_lla(llabuf, sizeof (llabuf),
147 lo->nd_opt_lla_hdw_addr,
148 optlen - sizeof (nd_opt_hdr_t));
149 logmsg(LOG_DEBUG, "\tTarget LLA: len %d <%s>\n",
150 optlen - sizeof (nd_opt_hdr_t),
151 llabuf);
152 break;
153 case ND_OPT_REDIRECTED_HEADER:
154 logmsg(LOG_DEBUG, "\tRedirected header option!\n");
155 break;
156 default:
157 logmsg(LOG_DEBUG, "Unknown option %d (0x%x)\n",
158 opt->nd_opt_type, opt->nd_opt_type);
159 break;
160 }
161 opt = (struct nd_opt_hdr *)((char *)opt + optlen);
162 len -= optlen;
163 }
164 }
165
166 char *
fmt_lla(char * llabuf,int bufsize,uchar_t * lla,int llalen)167 fmt_lla(char *llabuf, int bufsize, uchar_t *lla, int llalen)
168 {
169 int i;
170 char *cp = llabuf;
171
172 for (i = 0; i < llalen; i++) {
173 if (i == llalen - 1) /* Last byte? */
174 (void) snprintf(cp, bufsize, "%02x", lla[i] & 0xFF);
175 else
176 (void) snprintf(cp, bufsize, "%02x:", lla[i] & 0xFF);
177 bufsize -= strlen(cp);
178 cp += strlen(cp);
179 }
180 return (llabuf);
181 }
182