00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 }