2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 * Common (shared) routines used by in.routed daemon and the
10 * the rtquery utility program
16 /* Return the classical netmask for an IP address. */
17 in_addr_t
/* host byte order */
18 std_mask(in_addr_t addr
) /* network byte order */
22 if (addr
== 0) /* default route has mask 0 */
25 return (IN_CLASSA_NET
);
27 return (IN_CLASSB_NET
);
29 return (IN_CLASSC_NET
);
30 return (IN_CLASSE_NET
);
34 * Get a network number as a name or a number, with an optional "/xx"
38 getnet(const char *name
,
39 in_addr_t
*netp
, /* network in host byte order */
40 in_addr_t
*maskp
) /* masks are always in host order */
44 in_addr_t mask
; /* in host byte order */
45 struct in_addr in
; /* a network and so host byte order */
46 char hname
[MAXHOSTNAMELEN
+1];
51 * The "name" argument of this function can be one of
53 * a) network name/mask
55 * c) network number/mask
57 * e) host IP address/mask
61 * Detect and separate "1.2.3.4/24"
63 if (NULL
!= (mname
= strrchr(name
, '/'))) {
64 i
= (int)(mname
- name
);
65 if (i
> (int)sizeof (hname
)-1) /* name too long */
67 (void) memmove(hname
, name
, i
);
73 if ((in
.s_addr
= inet_network(name
)) == (in_addr_t
)-1) {
74 if (mname
== NULL
&& strcasecmp(name
, "default") == 0)
75 in
.s_addr
= ntohl(RIP_DEFAULT
);
76 else if ((np
= getnetbyname(name
)) != NULL
)
77 in
.s_addr
= np
->n_net
;
81 /* Left-align the host-byte-order result from above. */
82 if (0 == (in
.s_addr
& 0xff000000))
84 if (0 == (in
.s_addr
& 0xff000000))
86 if (0 == (in
.s_addr
& 0xff000000))
90 mask
= std_mask(htonl(in
.s_addr
));
91 if ((~mask
& in
.s_addr
) != 0)
94 mask
= (uint32_t)strtoul(mname
, &p
, 0);
95 if (*p
!= '\0' || mask
> 32 || mname
== p
)
98 mask
= HOST_MASK
<< (32-mask
);
101 /* must have mask of 0 with default */
102 if (mask
!= 0 && in
.s_addr
== RIP_DEFAULT
)
104 /* no host bits allowed in a network number */
105 if ((~mask
& in
.s_addr
) != 0)
107 /* require non-zero network number */
108 if ((mask
& in
.s_addr
) == 0 && in
.s_addr
!= RIP_DEFAULT
)
110 if ((in
.s_addr
>> 24) == 0 && in
.s_addr
!= RIP_DEFAULT
)
112 if ((in
.s_addr
>> 24) == 0xff)
121 * Convert string to printable characters
124 qstring(const uchar_t
*srcp
, int len
)
127 * Authentication schemes for RIPv2 uses the space of an
128 * 20-octet route entry.
130 static char buf
[8*20+1];
131 char *prcp
, *tmp_ptr
;
136 while (s2
> srcp
&& *--s2
== '\0')
138 for (prcp
= buf
; len
!= 0 && prcp
< &buf
[sizeof (buf
)-1]; len
--) {
140 if (isprint(c
) && c
!= '\\') {
146 tmp_ptr
= strchr("\\\\\nn\rr\tt\bb\aa\ff", c
);
148 *prcp
++ = tmp_ptr
[1];
150 prcp
+= snprintf(prcp
,
151 (sizeof (buf
) - (strlen(buf
)+1)), "%o", c
);
157 /* like strtok(), but honoring backslash and not changing the source string */
158 int /* 0=ok, -1=bad */
159 parse_quote(char **linep
, /* look here */
160 const char *delims
, /* for these delimiters */
161 char *delimp
, /* 0 or put found delimiter here */
162 char *buf
, /* copy token to here */
163 int lim
) /* at most this many bytes */
178 if (c
== '\\' && *pc
!= '\0') {
193 if (c
>= '0' && c
<= '7') {
195 if (*pc
>= '0' && *pc
<= '7') {
196 c
= (c
<<3)+(*pc
++ - '0');
197 if (*pc
>= '0' && *pc
<= '7')
198 c
= (c
<<3)+(*pc
++ - '0');
203 for (p
= delims
; *p
!= '\0'; ++p
) {
204 if (*p
== c
|| isspace(c
) && *p
== ' ')
216 *buf
= '\0'; /* terminate copy of token */
218 *delimp
= c
; /* return delimiter */
219 *linep
= pc
-1; /* say where we ended */
224 * Find the option buffer in the msg corresponding to cmsg_type.
227 find_ancillary(struct msghdr
*msg
, int cmsg_type
)
229 struct cmsghdr
*cmsg
;
231 for (cmsg
= CMSG_FIRSTHDR(msg
); cmsg
!= NULL
;
232 cmsg
= CMSG_NXTHDR(msg
, cmsg
)) {
233 if (cmsg
->cmsg_level
== IPPROTO_IP
&&
234 cmsg
->cmsg_type
== cmsg_type
) {
235 return (CMSG_DATA(cmsg
));