2 * Copyright (C) 2012 Martin Willi
3 * Copyright (C) 2012 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "lookip_msg.h"
18 #include <sys/socket.h>
27 * Connect to the daemon, return FD
29 static int make_connection()
31 struct sockaddr_un addr
;
34 addr
.sun_family
= AF_UNIX
;
35 strcpy(addr
.sun_path
, LOOKIP_SOCKET
);
37 fd
= socket(AF_UNIX
, SOCK_SEQPACKET
, 0);
40 fprintf(stderr
, "opening socket failed: %s\n", strerror(errno
));
43 if (connect(fd
, (struct sockaddr
*)&addr
,
44 offsetof(struct sockaddr_un
, sun_path
) + strlen(addr
.sun_path
)) < 0)
46 fprintf(stderr
, "connecting to %s failed: %s\n",
47 LOOKIP_SOCKET
, strerror(errno
));
55 * Send a request message
57 static int send_request(int fd
, int type
, char *vip
)
59 lookip_request_t req
= {
65 snprintf(req
.vip
, sizeof(req
.vip
), "%s", vip
);
67 if (send(fd
, &req
, sizeof(req
), 0) != sizeof(req
))
69 fprintf(stderr
, "writing to socket failed: %s\n", strerror(errno
));
76 * Receive entries from fd. If block is != 0, the call blocks until closed
78 static int receive(int fd
, int block
)
80 lookip_response_t resp
;
86 res
= recv(fd
, &resp
, sizeof(resp
), block ?
0 : MSG_DONTWAIT
);
88 { /* closed by server */
91 if (res
!= sizeof(resp
))
93 if (!block
&& (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
94 { /* call would block, but we don't */
97 fprintf(stderr
, "reading from socket failed: %s\n", strerror(errno
));
105 case LOOKIP_NOTIFY_UP
:
108 case LOOKIP_NOTIFY_DOWN
:
112 fprintf(stderr
, "received invalid message type: %d\n", resp
.type
);
115 resp
.vip
[sizeof(resp
.vip
) - 1] = '\0';
116 resp
.ip
[sizeof(resp
.ip
) - 1] = '\0';
117 resp
.id
[sizeof(resp
.id
) - 1] = '\0';
118 resp
.name
[sizeof(resp
.name
) - 1] = '\0';
120 printf("%-8s %16s %16s %20s %s\n",
121 label
, resp
.vip
, resp
.ip
, resp
.name
, resp
.id
);
126 * Print usage information
128 static void usage(char *cmd
)
130 fprintf(stderr
, "Usage:\n");
131 fprintf(stderr
, " %s --help\n", cmd
);
132 fprintf(stderr
, " %s --dump\n", cmd
);
133 fprintf(stderr
, " %s --lookup <IP>\n", cmd
);
134 fprintf(stderr
, " %s --listen-up\n", cmd
);
135 fprintf(stderr
, " %s --listen-down\n", cmd
);
136 fprintf(stderr
, "Any combination of options is allowed.\n", cmd
);
139 int main(int argc
, char *argv
[])
141 int fd
, res
= 0, end
= 0;
142 struct option long_opts
[] = {
143 { "help", no_argument
, NULL
, 'h' },
144 { "dump", no_argument
, NULL
, 'd' },
145 { "lookup", required_argument
, NULL
, 'l' },
146 { "listen-up", no_argument
, NULL
, 'u' },
147 { "listen-down", no_argument
, NULL
, 'c' },
157 fd
= make_connection();
165 switch (getopt_long(argc
, argv
, "", long_opts
, NULL
))
174 res
= send_request(fd
, LOOKIP_DUMP
, NULL
);
177 res
= send_request(fd
, LOOKIP_LOOKUP
, optarg
);
180 res
= send_request(fd
, LOOKIP_REGISTER_UP
, NULL
);
183 res
= send_request(fd
, LOOKIP_REGISTER_DOWN
, NULL
);
195 { /* read all currently available results */
196 res
= receive(fd
, 0);
201 /* send close message */
202 send_request(fd
, LOOKIP_END
, NULL
);
203 /* read until socket gets closed */
204 res
= receive(fd
, 1);