Mercurial > illumos > onarm
comparison usr/src/cmd/cmd-inet/usr.sbin/in.routed/common.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
1 /* | |
2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
3 * Use is subject to license terms. | |
4 */ | |
5 | |
6 #pragma ident "@(#)common.c 2.2 07/12/03 SMI" | |
7 | |
8 /* | |
9 * Common (shared) routines used by in.routed daemon and the | |
10 * the rtquery utility program | |
11 */ | |
12 | |
13 #include "defs.h" | |
14 #include <ctype.h> | |
15 | |
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 */ | |
19 { | |
20 addr = ntohl(addr); | |
21 | |
22 if (addr == 0) /* default route has mask 0 */ | |
23 return (0); | |
24 if (IN_CLASSA(addr)) | |
25 return (IN_CLASSA_NET); | |
26 if (IN_CLASSB(addr)) | |
27 return (IN_CLASSB_NET); | |
28 if (IN_CLASSC(addr)) | |
29 return (IN_CLASSC_NET); | |
30 return (IN_CLASSE_NET); | |
31 } | |
32 | |
33 /* | |
34 * Get a network number as a name or a number, with an optional "/xx" | |
35 * netmask. | |
36 */ | |
37 boolean_t /* 0=bad */ | |
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 */ | |
41 { | |
42 int i; | |
43 struct netent *np; | |
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]; | |
47 char *mname, *p; | |
48 | |
49 | |
50 /* | |
51 * The "name" argument of this function can be one of | |
52 * the follwoing: | |
53 * a) network name/mask | |
54 * b) network name | |
55 * c) network number/mask | |
56 * d) network number | |
57 * e) host IP address/mask | |
58 * f) host IP address | |
59 * g) "default" | |
60 * | |
61 * Detect and separate "1.2.3.4/24" | |
62 */ | |
63 if (NULL != (mname = strrchr(name, '/'))) { | |
64 i = (int)(mname - name); | |
65 if (i > (int)sizeof (hname)-1) /* name too long */ | |
66 return (_B_FALSE); | |
67 (void) memmove(hname, name, i); | |
68 hname[i] = '\0'; | |
69 mname++; | |
70 name = hname; | |
71 } | |
72 | |
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; | |
78 else | |
79 return (_B_FALSE); | |
80 } | |
81 /* Left-align the host-byte-order result from above. */ | |
82 if (0 == (in.s_addr & 0xff000000)) | |
83 in.s_addr <<= 8; | |
84 if (0 == (in.s_addr & 0xff000000)) | |
85 in.s_addr <<= 8; | |
86 if (0 == (in.s_addr & 0xff000000)) | |
87 in.s_addr <<= 8; | |
88 | |
89 if (mname == NULL) { | |
90 mask = std_mask(htonl(in.s_addr)); | |
91 if ((~mask & in.s_addr) != 0) | |
92 mask = HOST_MASK; | |
93 } else { | |
94 mask = (uint32_t)strtoul(mname, &p, 0); | |
95 if (*p != '\0' || mask > 32 || mname == p) | |
96 return (_B_FALSE); | |
97 if (mask != 0) | |
98 mask = HOST_MASK << (32-mask); | |
99 } | |
100 | |
101 /* must have mask of 0 with default */ | |
102 if (mask != 0 && in.s_addr == RIP_DEFAULT) | |
103 return (_B_FALSE); | |
104 /* no host bits allowed in a network number */ | |
105 if ((~mask & in.s_addr) != 0) | |
106 return (_B_FALSE); | |
107 /* require non-zero network number */ | |
108 if ((mask & in.s_addr) == 0 && in.s_addr != RIP_DEFAULT) | |
109 return (_B_FALSE); | |
110 if ((in.s_addr >> 24) == 0 && in.s_addr != RIP_DEFAULT) | |
111 return (_B_FALSE); | |
112 if ((in.s_addr >> 24) == 0xff) | |
113 return (_B_FALSE); | |
114 | |
115 *netp = in.s_addr; | |
116 *maskp = mask; | |
117 return (_B_TRUE); | |
118 } | |
119 | |
120 /* | |
121 * Convert string to printable characters | |
122 */ | |
123 char * | |
124 qstring(const uchar_t *srcp, int len) | |
125 { | |
126 /* | |
127 * Authentication schemes for RIPv2 uses the space of an | |
128 * 20-octet route entry. | |
129 */ | |
130 static char buf[8*20+1]; | |
131 char *prcp, *tmp_ptr; | |
132 uchar_t c; | |
133 const uchar_t *s2; | |
134 | |
135 s2 = srcp + len; | |
136 while (s2 > srcp && *--s2 == '\0') | |
137 len--; | |
138 for (prcp = buf; len != 0 && prcp < &buf[sizeof (buf)-1]; len--) { | |
139 c = *srcp++; | |
140 if (isprint(c) && c != '\\') { | |
141 *prcp++ = c; | |
142 continue; | |
143 } | |
144 | |
145 *prcp++ = '\\'; | |
146 tmp_ptr = strchr("\\\\\nn\rr\tt\bb\aa\ff", c); | |
147 if (tmp_ptr != NULL) | |
148 *prcp++ = tmp_ptr[1]; | |
149 else | |
150 prcp += snprintf(prcp, | |
151 (sizeof (buf) - (strlen(buf)+1)), "%o", c); | |
152 } | |
153 *prcp = '\0'; | |
154 return (buf); | |
155 } | |
156 | |
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 */ | |
164 { | |
165 char c = '\0', *pc; | |
166 const char *p; | |
167 | |
168 | |
169 pc = *linep; | |
170 if (*pc == '\0') | |
171 return (-1); | |
172 | |
173 while (lim != 0) { | |
174 c = *pc++; | |
175 if (c == '\0') | |
176 break; | |
177 | |
178 if (c == '\\' && *pc != '\0') { | |
179 c = *pc++; | |
180 switch (c) { | |
181 case 'n': | |
182 c = '\n'; | |
183 break; | |
184 case 'r': | |
185 c = '\r'; | |
186 break; | |
187 case 't': | |
188 c = '\t'; | |
189 break; | |
190 case 'b': | |
191 c = '\b'; | |
192 } | |
193 if (c >= '0' && c <= '7') { | |
194 c -= '0'; | |
195 if (*pc >= '0' && *pc <= '7') { | |
196 c = (c<<3)+(*pc++ - '0'); | |
197 if (*pc >= '0' && *pc <= '7') | |
198 c = (c<<3)+(*pc++ - '0'); | |
199 } | |
200 } | |
201 | |
202 } else { | |
203 for (p = delims; *p != '\0'; ++p) { | |
204 if (*p == c || isspace(c) && *p == ' ') | |
205 goto exit; | |
206 } | |
207 } | |
208 | |
209 *buf++ = c; | |
210 --lim; | |
211 } | |
212 exit: | |
213 if (lim == 0) | |
214 return (-1); | |
215 | |
216 *buf = '\0'; /* terminate copy of token */ | |
217 if (delimp != NULL) | |
218 *delimp = c; /* return delimiter */ | |
219 *linep = pc-1; /* say where we ended */ | |
220 return (0); | |
221 } | |
222 | |
223 /* | |
224 * Find the option buffer in the msg corresponding to cmsg_type. | |
225 */ | |
226 void * | |
227 find_ancillary(struct msghdr *msg, int cmsg_type) | |
228 { | |
229 struct cmsghdr *cmsg; | |
230 | |
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)); | |
236 } | |
237 } | |
238 return (NULL); | |
239 } |