device_info_query.c

Go to the documentation of this file.
00001 /* $Id: device_info_query.c,v 1.8 2001/08/04 20:55:56 jm Exp $
00002  * Device information query
00003  *
00004  * Dynamic hierarchial IP tunnel
00005  * Copyright (C) 1998-2001, Dynamics group
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 2 as
00009  * published by the Free Software Foundation. See README and COPYING for
00010  * more details.
00011  */
00012 
00013 
00014 #ifndef _GNU_SOURCE
00015 #define _GNU_SOURCE
00016 #endif
00017 
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <errno.h>
00022 #include <time.h>
00023 #include <getopt.h>
00024 #include <unistd.h>
00025 #include <signal.h>
00026 #include <arpa/inet.h>
00027 #include <sys/types.h>
00028 #include <sys/socket.h>
00029 #include <sys/un.h>
00030 #include <sys/param.h>
00031 #include <sys/ioctl.h>
00032 #include <linux/if.h>
00033 
00034 #include "util.h"
00035 #include "dyn_mnlib.h"
00036 #include "agentapi.h"
00037 #include "fixed_fd_zero.h"
00038 #include "device_info.h"
00039 #include "dyn_ip.h"
00040 
00041 static char *default_path = DEFAULT_DEVICE_INFO_PATH;
00042 static char *usage = "device_info_query -p <socket path>] [-d device] [-h help]\n";
00043 
00044 static int open_socket(void)
00045 {
00046         int sock, r;
00047         struct sockaddr_un addr;
00048         socklen_t addrlen;
00049         
00050         sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
00051         if (sock < 0)
00052                 return sock;
00053         
00054         memset(&addr, 0, sizeof(struct sockaddr_un));
00055         addr.sun_family = AF_LOCAL;
00056         addr.sun_path[0] = '\0';
00057         snprintf(addr.sun_path + 1, sizeof(addr.sun_path) - 1,
00058                  "dynamics-%i-%li", getpid(), random());
00059         addrlen = sizeof(addr.sun_family) + 1 + strlen(addr.sun_path + 1);
00060         
00061         r = bind(sock, (struct sockaddr *) &addr, addrlen);
00062         if (r < 0) {
00063                 fprintf(stderr, "open_socket: bind failed: %s\n",
00064                         strerror(errno));
00065                 return -1;
00066         }
00067 
00068         return sock;
00069 }
00070 
00071 static int send_query(int s, struct sockaddr_un addr, 
00072                       char *path, struct device_info_query *msg)
00073 {
00074         int n;
00075 
00076         if (!path || !msg) {
00077                 fprintf(stderr, "send_query: NULL argument\n");
00078                 return -1;
00079         }
00080 
00081         n = sendto(s, msg, sizeof(struct device_info_query), 0, 
00082                    (struct sockaddr *)&addr, sizeof(addr));
00083 
00084         if (n != sizeof(struct device_info_query)) {
00085                 fprintf(stderr, "send_query: sendto %d/%d bytes: %s\n",
00086                         n, sizeof(struct device_info_query), strerror(errno));
00087         }
00088 
00089         return 0;
00090 }
00091 
00092 static int process_reply(int s, struct device_info_query *msg)
00093 {
00094         fd_set set;
00095         int len, n;
00096         struct sockaddr_un addr;
00097         
00098         FD_ZERO(&set);
00099         FD_SET(s, &set);
00100         select(FD_SETSIZE, &set, NULL, NULL, NULL);
00101         if (!(FD_ISSET(s, &set)))
00102                 return 0;
00103         
00104         len = sizeof(addr);
00105         n = recvfrom(s, msg, sizeof(struct device_info_query), 0,
00106                      (struct sockaddr *)&addr, (unsigned int *)&len);
00107         if (n != sizeof(struct device_info_query)) {
00108                 fprintf(stderr, "process_reply: couldn't receive whole "
00109                         "message %d/%d\n", 
00110                         n, sizeof(struct device_info_query));
00111                 return -1;
00112         }
00113 
00114         return 0;
00115 }
00116 
00117 int main(int argc, char *argv[])
00118 {
00119         char *path = NULL;
00120         char *ifname = NULL;
00121         int c, s, r;
00122         struct device_info_query msg;
00123         struct idxmap *idx = NULL, *idxmap = NULL, *prev;
00124         struct sockaddr_un serv_addr;
00125 
00126         if (argc < 2) {
00127                 fprintf(stderr, usage);
00128                 exit(1);
00129         }
00130 
00131         while (1) {
00132                 int option_index = 0;
00133                 
00134                 c = getopt_long (argc, argv, "hd:p:", NULL, &option_index);
00135                 if (c == -1)
00136                         break;
00137                 
00138                 switch (c) {
00139                 case 'd':
00140                         ifname = malloc(IFNAMSIZ);
00141                         if (ifname == NULL) {
00142                                 fprintf(stderr, "malloc for device: %s\n",
00143                                         strerror(errno));
00144                                 exit(1);
00145                         }
00146                         memset(ifname, 0, IFNAMSIZ);
00147                         dynamics_strlcpy(ifname, optarg, IFNAMSIZ);
00148                         break;
00149                 case 'p':
00150                         path = malloc(MAXPATHLEN);
00151                         if (path == NULL) {
00152                                 fprintf(stderr, "malloc for path: %s\n",
00153                                         strerror(errno));
00154                                 exit(1);
00155                         }
00156                         memset(path, 0, MAXPATHLEN);
00157                         dynamics_strlcpy(path, optarg, MAXPATHLEN);
00158                         break;
00159                 case '?':
00160                 case 'h':
00161                         fprintf(stderr, usage);
00162                         exit(1);
00163                 default:
00164                         printf ("?? getopt returned character code "
00165                                 "0%o ??\n", c);
00166                 }
00167         }
00168 
00169         if (path == NULL)
00170                 path = default_path;
00171 
00172         if (ifname == NULL)
00173                 printf("Querying all interfaces\n");
00174 
00175         idxmap = dyn_ip_get_interface_map();
00176         idx = idxmap;
00177 
00178         s = open_socket();
00179         if (s < 0) {
00180                 fprintf(stderr, "socket open failed\n");
00181                 exit(1);
00182         }
00183 
00184         memset(&serv_addr, 0, sizeof(serv_addr));
00185         serv_addr.sun_family = AF_LOCAL;
00186         dynamics_strlcpy(serv_addr.sun_path, path,
00187                          sizeof(serv_addr.sun_path));
00188 
00189         while (idx != NULL) {
00190                 if (ifname != NULL && strncmp(idx->name, ifname, 
00191                                               sizeof(ifname))) {
00192                         idx = idx->next;
00193                         continue;
00194                 }
00195                 msg.device_index = idx->index;
00196                 msg.priority = -1;
00197                 r = send_query(s, serv_addr, path, &msg);
00198                 if (r == 0)
00199                         process_reply(s, &msg);
00200                 else {
00201                         fprintf(stderr, "send_query failed\n");
00202                         continue;
00203                 }
00204                 printf("interface %s:\n", idx->name);
00205                 if (msg.priority != -1)
00206                         printf("\tpriority %d\n", msg.priority);
00207                 idx = idx->next;
00208         }
00209 
00210         idx = idxmap;
00211         while (idx != NULL) {
00212                 prev = idx;
00213                 idx = idx->next;
00214                 free(prev);
00215         }
00216 
00217         close(s);
00218         return 0;
00219 }

Generated on Tue Jan 15 08:50:43 2008 for Virtual foreign agent generator version 0.1 by  doxygen 1.5.1