Use hardware timer to simulate interrupt moderation.
[dragonfly.git] / lib / libatm / ioctl_subr.c
blob3fb6581e52b5862753d6e1fd950f81c1dcfe0d97
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.4 2004/09/23 21:39:08 geekgod 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(req, buf_len)
89 struct atminfreq *req;
90 int buf_len;
92 int rc, s;
93 caddr_t buf;
96 * Open a socket for the IOCTL
98 s = socket(AF_ATM, SOCK_DGRAM, 0);
99 if (s < 0) {
100 return(-1);
104 * Get memory for returned information
106 mem_retry:
107 buf = (caddr_t)UM_ALLOC(buf_len);
108 if (buf == NULL) {
109 errno = ENOMEM;
110 return(-1);
114 * Set the buffer address and length in the request
116 req->air_buf_addr = buf;
117 req->air_buf_len = buf_len;
120 * Issue the IOCTL
122 rc = ioctl(s, AIOCINFO, (caddr_t)req);
123 if (rc) {
124 UM_FREE(buf);
125 if (errno == ENOSPC) {
126 buf_len = buf_len * 2;
127 goto mem_retry;
129 return(-1);
131 (void)close(s);
133 * Set a pointer to the returned info in the request
134 * and return its length
136 req->air_buf_addr = buf;
137 return(req->air_buf_len);
142 * Get VCC information
144 * Arguments:
145 * intf pointer to interface name (or null string)
146 * vccp pointer to a pointer to a struct air_vcc_rsp for the
147 * address of the returned VCC information
149 * Returns:
150 * int length of the retuned VCC information
154 get_vcc_info(intf, vccp)
155 char *intf;
156 struct air_vcc_rsp **vccp;
158 int buf_len = sizeof(struct air_vcc_rsp) * 100;
159 struct atminfreq air;
162 * Initialize IOCTL request
164 air.air_opcode = AIOCS_INF_VCC;
165 UM_ZERO(air.air_vcc_intf, sizeof(air.air_vcc_intf));
166 if (intf != NULL && strlen(intf) != 0)
167 strlcpy(air.air_vcc_intf, intf, IFNAMSIZ);
169 buf_len = do_info_ioctl(&air, buf_len);
172 * Return a pointer to the VCC info and its length
174 *vccp = (struct air_vcc_rsp *) air.air_buf_addr;
175 return(buf_len);
180 * Get subnet mask
182 * Arguments:
183 * intf pointer to an interface name
184 * mask pointer to a struct sockaddr_in to receive the mask
186 * Returns:
187 * 0 good completion
188 * -1 error
192 get_subnet_mask(intf, mask)
193 char *intf;
194 struct sockaddr_in *mask;
196 int rc, s;
197 struct ifreq req;
198 struct sockaddr_in *ip_mask;
201 * Check parameters
203 if (!intf || !mask ||
204 strlen(intf) == 0 ||
205 strlen(intf) > IFNAMSIZ-1)
206 return(-1);
209 * Open a socket for the IOCTL
211 s = socket(AF_INET, SOCK_DGRAM, 0);
212 if (s < 0)
213 return(-1);
216 * Set up and issue the IOCTL
218 UM_ZERO(&req, sizeof(req));
219 strlcpy(req.ifr_name, intf, sizeof(req.ifr_name));
220 rc = ioctl(s, SIOCGIFNETMASK, (caddr_t)&req);
221 (void)close(s);
222 if (rc)
223 return(-1);
226 * Give the answer back to the caller
228 ip_mask = (struct sockaddr_in *)&req.ifr_addr;
229 *mask = *ip_mask;
230 mask->sin_family = AF_INET;
232 return(0);
237 * Get an interface's MTU
239 * Arguments:
240 * intf pointer to an interface name
241 * mtu pointer to an int to receive the MTU
243 * Returns:
244 * >= 0 interface MTU
245 * -1 error
249 get_mtu(intf)
250 char *intf;
252 int rc, s;
253 struct ifreq req;
256 * Check parameters
258 if (!intf || strlen(intf) == 0 ||
259 strlen(intf) > IFNAMSIZ-1)
260 return(-1);
263 * Open a socket for the IOCTL
265 s = socket(AF_INET, SOCK_DGRAM, 0);
266 if (s < 0)
267 return(-1);
270 * Set up and issue the IOCTL
272 UM_ZERO(&req, sizeof(req));
273 strlcpy(req.ifr_name, intf, sizeof(req.ifr_name));
274 rc = ioctl(s, SIOCGIFMTU, (caddr_t)&req);
275 (void)close(s);
278 * Set the appropriate return value
280 if (rc)
281 return(-1);
282 else
283 return(req.ifr_mtu);
288 * Verify netif name
290 * This routine issues an IOCTL to check whether the passed string is
291 * a valid network interface name.
293 * Arguments:
294 * req pointer to an ATM information request IOCTL structure
296 * Returns:
297 * -1 error encountered
298 * FALSE (0) the string is not a NIF name
299 * TRUE (> 0) the string is a valid NIF name
303 verify_nif_name(name)
304 char *name;
306 int rc, s;
307 struct atminfreq air;
308 struct air_netif_rsp *nif_info;
311 * Check whether name is of a valid length
313 if (strlen(name) > IFNAMSIZ - 1 ||
314 strlen(name) < 1) {
315 return(FALSE);
319 * Open a socket for the IOCTL
321 s = socket(AF_ATM, SOCK_DGRAM, 0);
322 if (s < 0) {
323 return(-1);
327 * Get memory for returned information
329 nif_info = (struct air_netif_rsp *)UM_ALLOC(
330 sizeof(struct air_netif_rsp));
331 if (nif_info == NULL) {
332 errno = ENOMEM;
333 return(-1);
337 * Set up the request
339 air.air_opcode = AIOCS_INF_NIF;
340 air.air_buf_addr = (caddr_t)nif_info;
341 air.air_buf_len = sizeof(struct air_netif_rsp);
342 UM_ZERO(air.air_netif_intf, sizeof(air.air_netif_intf));
343 strlcpy(air.air_netif_intf, name, sizeof(air.air_netif_intf));
346 * Issue the IOCTL
348 rc = ioctl(s, AIOCINFO, (caddr_t)&air);
349 UM_FREE(nif_info);
350 (void)close(s);
353 * Base return value on IOCTL return code
355 if (rc)
356 return(FALSE);
357 else
358 return(TRUE);
362 * Get Config information
364 * Arguments:
365 * intf pointer to interface name (or null string)
366 * cfgp pointer to a pointer to a struct air_cfg_rsp for the
367 * address of the returned Config information
369 * Returns:
370 * int length of returned Config information
374 get_cfg_info ( intf, cfgp )
375 char *intf;
376 struct air_cfg_rsp **cfgp;
378 int buf_len = sizeof(struct air_cfg_rsp) * 4;
379 struct atminfreq air;
382 * Initialize IOCTL request
384 air.air_opcode = AIOCS_INF_CFG;
385 UM_ZERO ( air.air_cfg_intf, sizeof(air.air_cfg_intf));
386 if ( intf != NULL && strlen(intf) != 0 )
387 strlcpy ( air.air_cfg_intf, intf, IFNAMSIZ );
389 buf_len = do_info_ioctl ( &air, buf_len );
392 * Return a pointer to the Config info and its length
394 *cfgp = (struct air_cfg_rsp *) air.air_buf_addr;
395 return ( buf_len );
400 * Get Physical Interface information
402 * Arguments:
403 * intf pointer to interface name (or null string)
404 * intp pointer to a pointer to a struct air_cfg_rsp for the
405 * address of the returned Config information
407 * Returns:
408 * int length of returned Config information
412 get_intf_info ( intf, intp )
413 char *intf;
414 struct air_int_rsp **intp;
416 int buf_len = sizeof(struct air_int_rsp) * 4;
417 struct atminfreq air;
420 * Initialize IOCTL request
422 air.air_opcode = AIOCS_INF_INT;
423 UM_ZERO ( air.air_int_intf, sizeof(air.air_int_intf));
424 if ( intf != NULL && strlen(intf) != 0 )
425 strlcpy ( air.air_int_intf, intf, IFNAMSIZ );
427 buf_len = do_info_ioctl ( &air, buf_len );
430 * Return a pointer to the Physical Interface info and its length
432 *intp = (struct air_int_rsp *) air.air_buf_addr;
433 return ( buf_len );
439 * Get Netif information
441 * Arguments:
442 * intf pointer to interface name (or null string)
443 * netp pointer to a pointer to a struct air_netif_rsp for the
444 * address of the returned Netif information
446 * Returns:
447 * int length of returned Netif information
451 get_netif_info ( intf, netp )
452 char *intf;
453 struct air_netif_rsp **netp;
455 int buf_len = sizeof(struct air_netif_rsp) * 10;
456 struct atminfreq air;
459 * Initialize IOCTL request
461 air.air_opcode = AIOCS_INF_NIF;
462 UM_ZERO ( air.air_int_intf, sizeof(air.air_int_intf) );
463 if ( intf != NULL && strlen(intf) != 0 )
464 strlcpy ( air.air_int_intf, intf, IFNAMSIZ );
466 buf_len = do_info_ioctl ( &air, buf_len );
469 * Return a pointer to the Netif info and its length
471 *netp = (struct air_netif_rsp *) air.air_buf_addr;
472 return ( buf_len );