HAMMER VFS - Fix serious bug when downgrading (and later upgrading) a PFS
[dragonfly.git] / lib / libatm / ioctl_subr.c
blob7a8abe2da38f5b615cbd007f35fae96b476f8a9c
1 /*
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * $FreeBSD: src/lib/libatm/ioctl_subr.c,v 1.3.2.1 2001/09/28 16:52:10 dillon Exp $
27 * $DragonFly: src/lib/libatm/ioctl_subr.c,v 1.5 2008/09/30 16:57:04 swildner Exp $
31 * User Space Library Functions
32 * ----------------------------
34 * IOCTL subroutines
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
41 #include <sys/sockio.h>
42 #include <net/if.h>
43 #include <netinet/in.h>
44 #include <netatm/port.h>
45 #include <netatm/atm.h>
46 #include <netatm/atm_if.h>
47 #include <netatm/atm_sap.h>
48 #include <netatm/atm_sys.h>
49 #include <netatm/atm_ioctl.h>
51 #include <errno.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <unistd.h>
56 #include "libatm.h"
58 #ifndef TRUE
59 #define TRUE 1
60 #endif
62 #ifndef FALSE
63 #define FALSE 0
64 #endif
66 extern char *prog;
70 * Issue an informational IOCTL
72 * The user fills out the opcode and any subtype information. This
73 * routine will allocate a buffer and issue the IOCTL. If the request
74 * fails because the buffer wasn't big enough, this routine will double
75 * the buffer size and retry the request repeatedly. The buffer must
76 * be freed by the caller.
78 * Arguments:
79 * req pointer to an ATM information request IOCTL structure
80 * buf_len length of buffer to be allocated
82 * Returns:
83 * -1 error encountered (reason in errno)
84 * int length of the returned VCC information
87 int
88 do_info_ioctl(struct atminfreq *req, int buf_len)
90 int rc, s;
91 caddr_t buf;
94 * Open a socket for the IOCTL
96 s = socket(AF_ATM, SOCK_DGRAM, 0);
97 if (s < 0) {
98 return(-1);
102 * Get memory for returned information
104 mem_retry:
105 buf = (caddr_t)UM_ALLOC(buf_len);
106 if (buf == NULL) {
107 errno = ENOMEM;
108 return(-1);
112 * Set the buffer address and length in the request
114 req->air_buf_addr = buf;
115 req->air_buf_len = buf_len;
118 * Issue the IOCTL
120 rc = ioctl(s, AIOCINFO, (caddr_t)req);
121 if (rc) {
122 UM_FREE(buf);
123 if (errno == ENOSPC) {
124 buf_len = buf_len * 2;
125 goto mem_retry;
127 return(-1);
129 (void)close(s);
131 * Set a pointer to the returned info in the request
132 * and return its length
134 req->air_buf_addr = buf;
135 return(req->air_buf_len);
140 * Get VCC information
142 * Arguments:
143 * intf pointer to interface name (or null string)
144 * vccp pointer to a pointer to a struct air_vcc_rsp for the
145 * address of the returned VCC information
147 * Returns:
148 * int length of the retuned VCC information
152 get_vcc_info(char *intf, struct air_vcc_rsp **vccp)
154 int buf_len = sizeof(struct air_vcc_rsp) * 100;
155 struct atminfreq air;
158 * Initialize IOCTL request
160 air.air_opcode = AIOCS_INF_VCC;
161 UM_ZERO(air.air_vcc_intf, sizeof(air.air_vcc_intf));
162 if (intf != NULL && strlen(intf) != 0)
163 strlcpy(air.air_vcc_intf, intf, IFNAMSIZ);
165 buf_len = do_info_ioctl(&air, buf_len);
168 * Return a pointer to the VCC info and its length
170 *vccp = (struct air_vcc_rsp *) air.air_buf_addr;
171 return(buf_len);
176 * Get subnet mask
178 * Arguments:
179 * intf pointer to an interface name
180 * mask pointer to a struct sockaddr_in to receive the mask
182 * Returns:
183 * 0 good completion
184 * -1 error
188 get_subnet_mask(char *intf, struct sockaddr_in *mask)
190 int rc, s;
191 struct ifreq req;
192 struct sockaddr_in *ip_mask;
195 * Check parameters
197 if (!intf || !mask ||
198 strlen(intf) == 0 ||
199 strlen(intf) > IFNAMSIZ-1)
200 return(-1);
203 * Open a socket for the IOCTL
205 s = socket(AF_INET, SOCK_DGRAM, 0);
206 if (s < 0)
207 return(-1);
210 * Set up and issue the IOCTL
212 UM_ZERO(&req, sizeof(req));
213 strlcpy(req.ifr_name, intf, sizeof(req.ifr_name));
214 rc = ioctl(s, SIOCGIFNETMASK, (caddr_t)&req);
215 (void)close(s);
216 if (rc)
217 return(-1);
220 * Give the answer back to the caller
222 ip_mask = (struct sockaddr_in *)&req.ifr_addr;
223 *mask = *ip_mask;
224 mask->sin_family = AF_INET;
226 return(0);
231 * Get an interface's MTU
233 * Arguments:
234 * intf pointer to an interface name
235 * mtu pointer to an int to receive the MTU
237 * Returns:
238 * >= 0 interface MTU
239 * -1 error
243 get_mtu(char *intf)
245 int rc, s;
246 struct ifreq req;
249 * Check parameters
251 if (!intf || strlen(intf) == 0 ||
252 strlen(intf) > IFNAMSIZ-1)
253 return(-1);
256 * Open a socket for the IOCTL
258 s = socket(AF_INET, SOCK_DGRAM, 0);
259 if (s < 0)
260 return(-1);
263 * Set up and issue the IOCTL
265 UM_ZERO(&req, sizeof(req));
266 strlcpy(req.ifr_name, intf, sizeof(req.ifr_name));
267 rc = ioctl(s, SIOCGIFMTU, (caddr_t)&req);
268 (void)close(s);
271 * Set the appropriate return value
273 if (rc)
274 return(-1);
275 else
276 return(req.ifr_mtu);
281 * Verify netif name
283 * This routine issues an IOCTL to check whether the passed string is
284 * a valid network interface name.
286 * Arguments:
287 * req pointer to an ATM information request IOCTL structure
289 * Returns:
290 * -1 error encountered
291 * FALSE (0) the string is not a NIF name
292 * TRUE (> 0) the string is a valid NIF name
296 verify_nif_name(char *name)
298 int rc, s;
299 struct atminfreq air;
300 struct air_netif_rsp *nif_info;
303 * Check whether name is of a valid length
305 if (strlen(name) > IFNAMSIZ - 1 ||
306 strlen(name) < 1) {
307 return(FALSE);
311 * Open a socket for the IOCTL
313 s = socket(AF_ATM, SOCK_DGRAM, 0);
314 if (s < 0) {
315 return(-1);
319 * Get memory for returned information
321 nif_info = (struct air_netif_rsp *)UM_ALLOC(
322 sizeof(struct air_netif_rsp));
323 if (nif_info == NULL) {
324 errno = ENOMEM;
325 return(-1);
329 * Set up the request
331 air.air_opcode = AIOCS_INF_NIF;
332 air.air_buf_addr = (caddr_t)nif_info;
333 air.air_buf_len = sizeof(struct air_netif_rsp);
334 UM_ZERO(air.air_netif_intf, sizeof(air.air_netif_intf));
335 strlcpy(air.air_netif_intf, name, sizeof(air.air_netif_intf));
338 * Issue the IOCTL
340 rc = ioctl(s, AIOCINFO, (caddr_t)&air);
341 UM_FREE(nif_info);
342 (void)close(s);
345 * Base return value on IOCTL return code
347 if (rc)
348 return(FALSE);
349 else
350 return(TRUE);
354 * Get Config information
356 * Arguments:
357 * intf pointer to interface name (or null string)
358 * cfgp pointer to a pointer to a struct air_cfg_rsp for the
359 * address of the returned Config information
361 * Returns:
362 * int length of returned Config information
366 get_cfg_info(char *intf, struct air_cfg_rsp **cfgp)
368 int buf_len = sizeof(struct air_cfg_rsp) * 4;
369 struct atminfreq air;
372 * Initialize IOCTL request
374 air.air_opcode = AIOCS_INF_CFG;
375 UM_ZERO ( air.air_cfg_intf, sizeof(air.air_cfg_intf));
376 if ( intf != NULL && strlen(intf) != 0 )
377 strlcpy ( air.air_cfg_intf, intf, IFNAMSIZ );
379 buf_len = do_info_ioctl ( &air, buf_len );
382 * Return a pointer to the Config info and its length
384 *cfgp = (struct air_cfg_rsp *) air.air_buf_addr;
385 return ( buf_len );
390 * Get Physical Interface information
392 * Arguments:
393 * intf pointer to interface name (or null string)
394 * intp pointer to a pointer to a struct air_cfg_rsp for the
395 * address of the returned Config information
397 * Returns:
398 * int length of returned Config information
402 get_intf_info(char *intf, struct air_int_rsp **intp)
404 int buf_len = sizeof(struct air_int_rsp) * 4;
405 struct atminfreq air;
408 * Initialize IOCTL request
410 air.air_opcode = AIOCS_INF_INT;
411 UM_ZERO ( air.air_int_intf, sizeof(air.air_int_intf));
412 if ( intf != NULL && strlen(intf) != 0 )
413 strlcpy ( air.air_int_intf, intf, IFNAMSIZ );
415 buf_len = do_info_ioctl ( &air, buf_len );
418 * Return a pointer to the Physical Interface info and its length
420 *intp = (struct air_int_rsp *) air.air_buf_addr;
421 return ( buf_len );
427 * Get Netif information
429 * Arguments:
430 * intf pointer to interface name (or null string)
431 * netp pointer to a pointer to a struct air_netif_rsp for the
432 * address of the returned Netif information
434 * Returns:
435 * int length of returned Netif information
439 get_netif_info(char *intf, struct air_netif_rsp **netp)
441 int buf_len = sizeof(struct air_netif_rsp) * 10;
442 struct atminfreq air;
445 * Initialize IOCTL request
447 air.air_opcode = AIOCS_INF_NIF;
448 UM_ZERO ( air.air_int_intf, sizeof(air.air_int_intf) );
449 if ( intf != NULL && strlen(intf) != 0 )
450 strlcpy ( air.air_int_intf, intf, IFNAMSIZ );
452 buf_len = do_info_ioctl ( &air, buf_len );
455 * Return a pointer to the Netif info and its length
457 *netp = (struct air_netif_rsp *) air.air_buf_addr;
458 return ( buf_len );