ifspec.c (c7e4935f) ifspec.c (2b24ab6b)
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
23 * Use is subject to license terms.
24 */
25
26#pragma ident "%Z%%M% %I% %E% SMI"
27
28/*
29 * This file contains a routine used to validate a ifconfig-style interface
30 * specification
31 */
32
33#include <stdlib.h>
34#include <ctype.h>
35#include <alloca.h>

--- 51 unchanged lines hidden (view full) ---

87 if (!isdigit(*ep)) {
88 errno = EINVAL;
89 return (-1);
90 }
91
92 for (tp = ep; tp >= bp && isdigit(*tp); tp--)
93 /* Null body */;
94
26/*
27 * This file contains a routine used to validate a ifconfig-style interface
28 * specification
29 */
30
31#include <stdlib.h>
32#include <ctype.h>
33#include <alloca.h>

--- 51 unchanged lines hidden (view full) ---

85 if (!isdigit(*ep)) {
86 errno = EINVAL;
87 return (-1);
88 }
89
90 for (tp = ep; tp >= bp && isdigit(*tp); tp--)
91 /* Null body */;
92
95 if (*tp == '.' || *tp == ':') {
93 if (*tp == ':') {
96 errno = EINVAL;
97 return (-1);
98 }
99
100 *ppa = atoi(tp + 1);
101 return (0);
102}
103
104/*
105 * Given an ifconfig-style inet relative-path interface specification
94 errno = EINVAL;
95 return (-1);
96 }
97
98 *ppa = atoi(tp + 1);
99 return (0);
100}
101
102/*
103 * Given an ifconfig-style inet relative-path interface specification
106 * (e.g: hme.[module].[module][PPA]:2), validate its form and decompose the
107 * contents into a dynamically allocated ifspec_t.
104 * (e.g: bge0:2), validate its form and decompose the contents into a
105 * dynamically allocated ifspec_t.
108 *
109 * Returns ifspec_t for success, NULL pointer if spec is malformed.
110 */
111boolean_t
112ifparse_ifspec(const char *ifname, ifspec_t *ifsp)
113{
106 *
107 * Returns ifspec_t for success, NULL pointer if spec is malformed.
108 */
109boolean_t
110ifparse_ifspec(const char *ifname, ifspec_t *ifsp)
111{
114 char *mp, *ep, *lp, *tp;
115 char *ifnamecp;
116 size_t iflen;
117 boolean_t have_ppa = B_FALSE;
112 char *lp, *tp;
113 char ifnamecp[LIFNAMSIZ];
118
114
119 iflen = strlen(ifname);
120 if (iflen > LIFNAMSIZ) {
115 /* snag a copy we can modify */
116 if (strlcpy(ifnamecp, ifname, LIFNAMSIZ) >= LIFNAMSIZ) {
121 errno = EINVAL;
122 return (B_FALSE);
123 }
124
117 errno = EINVAL;
118 return (B_FALSE);
119 }
120
125 /* snag a copy we can modify */
126 ifnamecp = alloca(iflen + 1);
127 (void) strlcpy(ifnamecp, ifname, iflen + 1);
128
129 ifsp->ifsp_lunvalid = B_FALSE;
130
131 /*
132 * An interface name must have the format of:
121 ifsp->ifsp_lunvalid = B_FALSE;
122
123 /*
124 * An interface name must have the format of:
133 * dev[.module[.module...]][ppa][:lun]
125 * dev[ppa][:lun]
134 *
126 *
135 * where the ppa must be specified at the end of the interface name.
136 * e.g. ip.foo.tun0
137 *
138 * lun - logical unit number.
127 * lun - logical unit number.
139 *
140 * Produce substrings for each grouping, starting first with modules,
141 * then lun, devname, and finally ppa.
142 */
143
128 */
129
144 /* Any modules? */
145 mp = strchr(ifnamecp, '.');
146
147 /* Any logical units? */
148 lp = strchr(ifnamecp, ':');
130 /* Any logical units? */
131 lp = strchr(ifnamecp, ':');
149
150 if (lp != NULL && mp != NULL && lp < mp) {
151 errno = EINVAL;
152 return (B_FALSE);
153 }
154
155 ifsp->ifsp_modcnt = 0;
156 if (mp != NULL) {
157 *mp++ = '\0';
158 if (lp != NULL)
159 *lp = '\0';
160 while (mp != NULL && ifsp->ifsp_modcnt <= IFSP_MAXMODS) {
161 if ((ep = strchr(mp, '.')) != NULL)
162 *ep++ = '\0';
163 (void) strlcpy(ifsp->ifsp_mods[ifsp->ifsp_modcnt++],
164 mp, LIFNAMSIZ);
165 mp = ep;
166 }
167 if (lp != NULL)
168 *lp = ':';
169 if (ifsp->ifsp_modcnt > IFSP_MAXMODS) {
170 errno = E2BIG;
171 return (B_FALSE);
172 }
173 }
174
175 if (lp != NULL) {
176 if (getlun(lp, strlen(lp), &ifsp->ifsp_lun) != 0)
177 return (B_FALSE);
178 ifsp->ifsp_lunvalid = B_TRUE;
179 }
180
181 (void) strlcpy(ifsp->ifsp_devnm, ifnamecp, LIFNAMSIZ);
182
132 if (lp != NULL) {
133 if (getlun(lp, strlen(lp), &ifsp->ifsp_lun) != 0)
134 return (B_FALSE);
135 ifsp->ifsp_lunvalid = B_TRUE;
136 }
137
138 (void) strlcpy(ifsp->ifsp_devnm, ifnamecp, LIFNAMSIZ);
139
183 /*
184 * Find ppa - has to be part of devname or if modules exist part of
185 * last module name.
186 */
187 if (ifsp->ifsp_modcnt != 0 &&
188 getppa(ifsp->ifsp_mods[ifsp->ifsp_modcnt - 1],
189 strlen(ifsp->ifsp_mods[ifsp->ifsp_modcnt - 1]),
190 &ifsp->ifsp_ppa) == 0) {
191 have_ppa = B_TRUE;
192 } else if (ifsp->ifsp_modcnt == 0 &&
193 getppa(ifsp->ifsp_devnm, strlen(ifsp->ifsp_devnm),
194 &ifsp->ifsp_ppa) == 0) {
195 have_ppa = B_TRUE;
140 /* Find ppa */
141 if (getppa(ifsp->ifsp_devnm, strlen(ifsp->ifsp_devnm),
142 &ifsp->ifsp_ppa) != 0) {
143 return (B_FALSE);
144 }
196
145
197 /* strip the ppa off of the device name if present */
198 for (tp = &ifsp->ifsp_devnm[strlen(ifsp->ifsp_devnm) - 1];
199 tp >= ifsp->ifsp_devnm && isdigit(*tp); tp--)
200 *tp = '\0';
146 /* strip the ppa off of the device name if present */
147 for (tp = &ifsp->ifsp_devnm[strlen(ifsp->ifsp_devnm) - 1];
148 tp >= ifsp->ifsp_devnm && isdigit(*tp); tp--) {
149 *tp = '\0';
201 }
202
150 }
151
203 return (have_ppa);
152 return (B_TRUE);
204}
153}