|
|
@ -1,218 +0,0 @@ |
|
|
|
--- a/globals.c
|
|
|
|
+++ b/globals.c
|
|
|
|
@@ -27,9 +27,9 @@
|
|
|
|
* Global variables |
|
|
|
*/ |
|
|
|
|
|
|
|
-#ifdef __IPV4__
|
|
|
|
const struct in_addr inaddr_any = { INADDR_ANY }; |
|
|
|
-#endif
|
|
|
|
+
|
|
|
|
+int g_family = AF_INET;
|
|
|
|
|
|
|
|
in_port_t g_udp_port = 161; |
|
|
|
in_port_t g_tcp_port = 161; |
|
|
|
--- a/mini_snmpd.c
|
|
|
|
+++ b/mini_snmpd.c
|
|
|
|
@@ -54,6 +54,10 @@ static void print_help(void)
|
|
|
|
fprintf(stderr, "-d, --disks nnn set the disks to monitor (/)\n"); |
|
|
|
fprintf(stderr, "-i, --interfaces nnn set the network interfaces to monitor (lo)\n"); |
|
|
|
fprintf(stderr, "-I, --listen nnn set the network interface to listen (all)\n"); |
|
|
|
+#ifdef __IPV6__
|
|
|
|
+ fprintf(stderr, "-4, --ipv4 use IPv4 (default)\n");
|
|
|
|
+ fprintf(stderr, "-6, --ipv6 use IPv6\n");
|
|
|
|
+#endif
|
|
|
|
fprintf(stderr, "-t, --timeout nnn set the timeout for MIB updates (1 second)\n"); |
|
|
|
fprintf(stderr, "-a, --auth require authentication (thus SNMP version 2c)\n"); |
|
|
|
fprintf(stderr, "-v, --verbose verbose syslog messages \n"); |
|
|
|
@@ -117,7 +121,7 @@ static void handle_udp_client(void)
|
|
|
|
#endif |
|
|
|
|
|
|
|
/* Call the protocol handler which will prepare the response packet */ |
|
|
|
- inet_ntop(my_af_inet, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
+ inet_ntop(g_family, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
if (snmp(&g_udp_client) == -1) { |
|
|
|
lprintf(LOG_WARNING, "could not handle packet from UDP client %s:%d: %m\n", |
|
|
|
straddr, sockaddr.my_sin_port); |
|
|
|
@@ -132,7 +136,7 @@ static void handle_udp_client(void)
|
|
|
|
/* Send the whole UDP packet to the socket at once */ |
|
|
|
rv = sendto(g_udp_sockfd, g_udp_client.packet, g_udp_client.size, |
|
|
|
MSG_DONTWAIT, (struct sockaddr *)&sockaddr, socklen); |
|
|
|
- inet_ntop(my_af_inet, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
+ inet_ntop(g_family, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
if (rv == -1) { |
|
|
|
lprintf(LOG_WARNING, "could not send packet to UDP client %s:%d: %m\n", |
|
|
|
straddr, sockaddr.my_sin_port); |
|
|
|
@@ -176,7 +180,7 @@ static void handle_tcp_connect(void)
|
|
|
|
} |
|
|
|
tmp_sockaddr.my_sin_addr = client->addr; |
|
|
|
tmp_sockaddr.my_sin_port = client->port; |
|
|
|
- inet_ntop(my_af_inet, &tmp_sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
+ inet_ntop(g_family, &tmp_sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
lprintf(LOG_WARNING, "maximum number of %d clients reached, kicking out %s:%d\n", |
|
|
|
MAX_NR_CLIENTS, straddr, tmp_sockaddr.my_sin_port); |
|
|
|
close(client->sockfd); |
|
|
|
@@ -190,7 +194,7 @@ static void handle_tcp_connect(void)
|
|
|
|
} |
|
|
|
|
|
|
|
/* Now fill out the client control structure values */ |
|
|
|
- inet_ntop(my_af_inet, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
+ inet_ntop(g_family, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
lprintf(LOG_DEBUG, "connected TCP client %s:%d\n", |
|
|
|
straddr, sockaddr.my_sin_port); |
|
|
|
client->timestamp = time(NULL); |
|
|
|
@@ -211,7 +215,7 @@ static void handle_tcp_client_write(clie
|
|
|
|
sockaddr.my_sin_addr = client->addr; |
|
|
|
sockaddr.my_sin_port = client->port; |
|
|
|
rv = send(client->sockfd, client->packet, client->size, 0); |
|
|
|
- inet_ntop(my_af_inet, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
+ inet_ntop(g_family, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
if (rv == -1) { |
|
|
|
lprintf(LOG_WARNING, "could not send packet to TCP client %s:%d: %m\n", |
|
|
|
straddr, sockaddr.my_sin_port); |
|
|
|
@@ -246,7 +250,7 @@ static void handle_tcp_client_read(clien
|
|
|
|
sockaddr.my_sin_port = client->port; |
|
|
|
rv = read(client->sockfd, client->packet + client->size, |
|
|
|
sizeof (client->packet) - client->size); |
|
|
|
- inet_ntop(my_af_inet, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
+ inet_ntop(g_family, &sockaddr.my_sin_addr, straddr, sizeof(straddr));
|
|
|
|
if (rv == -1) { |
|
|
|
lprintf(LOG_WARNING, "could not read packet from TCP client %s:%d: %m\n", |
|
|
|
straddr, sockaddr.my_sin_port); |
|
|
|
@@ -304,7 +308,11 @@ static void handle_tcp_client_read(clien
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) |
|
|
|
{ |
|
|
|
+#ifdef __IPV6__
|
|
|
|
+ static const char short_options[] = "p:P:c:D:V:L:C:d:i:I:t:T:avl46h";
|
|
|
|
+#else
|
|
|
|
static const char short_options[] = "p:P:c:D:V:L:C:d:i:I:t:T:avlh"; |
|
|
|
+#endif
|
|
|
|
static const struct option long_options[] = { |
|
|
|
{ "udp-port", 1, 0, 'p' }, |
|
|
|
{ "tcp-port", 1, 0, 'P' }, |
|
|
|
@@ -316,6 +324,10 @@ int main(int argc, char *argv[])
|
|
|
|
{ "disks", 1, 0, 'd' }, |
|
|
|
{ "interfaces", 1, 0, 'i' }, |
|
|
|
{ "listen", 1, 0, 'I' }, |
|
|
|
+#ifdef __IPV6__
|
|
|
|
+ { "ipv4", 0, 0, '4' },
|
|
|
|
+ { "ipv6", 0, 0, '6' },
|
|
|
|
+#endif
|
|
|
|
{ "timeout", 1, 0, 't' }, |
|
|
|
{ "traps", 1, 0, 'T' }, |
|
|
|
{ "auth", 0, 0, 'a' }, |
|
|
|
@@ -327,7 +339,12 @@ int main(int argc, char *argv[])
|
|
|
|
int option_index = 1; |
|
|
|
int c; |
|
|
|
|
|
|
|
- struct my_sockaddr_t sockaddr;
|
|
|
|
+ union {
|
|
|
|
+ struct sockaddr_in sa;
|
|
|
|
+#ifdef __IPV6__
|
|
|
|
+ struct sockaddr_in6 sa6;
|
|
|
|
+#endif
|
|
|
|
+ } sockaddr;
|
|
|
|
my_socklen_t socklen; |
|
|
|
struct timeval tv_last; |
|
|
|
struct timeval tv_now; |
|
|
|
@@ -396,6 +413,14 @@ int main(int argc, char *argv[])
|
|
|
|
case 'v': |
|
|
|
g_verbose = 1; |
|
|
|
break; |
|
|
|
+#ifdef __IPV6__
|
|
|
|
+ case '4':
|
|
|
|
+ g_family = AF_INET;
|
|
|
|
+ break;
|
|
|
|
+ case '6':
|
|
|
|
+ g_family = AF_INET6;
|
|
|
|
+ break;
|
|
|
|
+#endif
|
|
|
|
case 'l': |
|
|
|
print_version(); |
|
|
|
exit(EXIT_ARGS); |
|
|
|
@@ -435,15 +460,24 @@ int main(int argc, char *argv[])
|
|
|
|
#endif |
|
|
|
|
|
|
|
/* Open the server's UDP port and prepare it for listening */ |
|
|
|
- g_udp_sockfd = socket(my_pf_inet, SOCK_DGRAM, 0);
|
|
|
|
+ g_udp_sockfd = socket((g_family == AF_INET) ? PF_INET : PF_INET6, SOCK_DGRAM, 0);
|
|
|
|
if (g_udp_sockfd == -1) { |
|
|
|
lprintf(LOG_ERR, "could not create UDP socket: %m\n"); |
|
|
|
exit(EXIT_SYSCALL); |
|
|
|
} |
|
|
|
- sockaddr.my_sin_family = my_af_inet;
|
|
|
|
- sockaddr.my_sin_port = htons(g_udp_port);
|
|
|
|
- sockaddr.my_sin_addr = my_inaddr_any;
|
|
|
|
- socklen = sizeof (sockaddr);
|
|
|
|
+ if (g_family == AF_INET) {
|
|
|
|
+ sockaddr.sa.sin_family = g_family;
|
|
|
|
+ sockaddr.sa.sin_port = htons(g_udp_port);
|
|
|
|
+ sockaddr.sa.sin_addr = inaddr_any;
|
|
|
|
+ socklen = sizeof(sockaddr.sa);
|
|
|
|
+#ifdef __IPV6__
|
|
|
|
+ } else {
|
|
|
|
+ sockaddr.sa6.sin6_family = g_family;
|
|
|
|
+ sockaddr.sa6.sin6_port = htons(g_udp_port);
|
|
|
|
+ sockaddr.sa6.sin6_addr = in6addr_any;
|
|
|
|
+ socklen = sizeof(sockaddr.sa6);
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
|
|
if (bind(g_udp_sockfd, (struct sockaddr *)&sockaddr, socklen) == -1) { |
|
|
|
lprintf(LOG_ERR, "could not bind UDP socket to port %d: %m\n", g_udp_port); |
|
|
|
exit(EXIT_SYSCALL); |
|
|
|
@@ -457,7 +491,7 @@ int main(int argc, char *argv[])
|
|
|
|
} |
|
|
|
|
|
|
|
/* Open the server's TCP port and prepare it for listening */ |
|
|
|
- g_tcp_sockfd = socket(my_pf_inet, SOCK_STREAM, 0);
|
|
|
|
+ g_tcp_sockfd = socket((g_family == AF_INET) ? PF_INET : PF_INET6, SOCK_STREAM, 0);
|
|
|
|
if (g_tcp_sockfd == -1) { |
|
|
|
lprintf(LOG_ERR, "could not create TCP socket: %m\n"); |
|
|
|
exit(EXIT_SYSCALL); |
|
|
|
@@ -474,10 +508,19 @@ int main(int argc, char *argv[])
|
|
|
|
lprintf(LOG_WARNING, "could not set SO_REUSEADDR on TCP socket: %m\n"); |
|
|
|
exit(EXIT_SYSCALL); |
|
|
|
} |
|
|
|
- sockaddr.my_sin_family = my_af_inet;
|
|
|
|
- sockaddr.my_sin_port = htons(g_tcp_port);
|
|
|
|
- sockaddr.my_sin_addr = my_inaddr_any;
|
|
|
|
- socklen = sizeof (sockaddr);
|
|
|
|
+ if (g_family == AF_INET) {
|
|
|
|
+ sockaddr.sa.sin_family = g_family;
|
|
|
|
+ sockaddr.sa.sin_port = htons(g_udp_port);
|
|
|
|
+ sockaddr.sa.sin_addr = inaddr_any;
|
|
|
|
+ socklen = sizeof(sockaddr.sa);
|
|
|
|
+#ifdef __IPV6__
|
|
|
|
+ } else {
|
|
|
|
+ sockaddr.sa6.sin6_family = g_family;
|
|
|
|
+ sockaddr.sa6.sin6_port = htons(g_udp_port);
|
|
|
|
+ sockaddr.sa6.sin6_addr = in6addr_any;
|
|
|
|
+ socklen = sizeof(sockaddr.sa6);
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
|
|
if (bind(g_tcp_sockfd, (struct sockaddr *)&sockaddr, socklen) == -1) { |
|
|
|
lprintf(LOG_ERR, "could not bind TCP socket to port %d: %m\n", g_tcp_port); |
|
|
|
exit(EXIT_SYSCALL); |
|
|
|
--- a/mini_snmpd.h
|
|
|
|
+++ b/mini_snmpd.h
|
|
|
|
@@ -255,6 +255,7 @@ typedef struct demoinfo_s {
|
|
|
|
|
|
|
|
extern in_port_t g_udp_port; |
|
|
|
extern in_port_t g_tcp_port; |
|
|
|
+extern int g_family;
|
|
|
|
extern int g_timeout; |
|
|
|
extern int g_auth; |
|
|
|
extern int g_verbose; |
|
|
|
@@ -265,9 +266,9 @@ extern char *g_vendor;
|
|
|
|
extern char *g_location; |
|
|
|
extern char *g_contact; |
|
|
|
extern char *g_bind_to_device; |
|
|
|
-#ifdef __IPV4__
|
|
|
|
+
|
|
|
|
extern const struct in_addr inaddr_any; |
|
|
|
-#endif
|
|
|
|
+
|
|
|
|
|
|
|
|
extern char *g_disk_list[MAX_NR_DISKS]; |
|
|
|
extern int g_disk_list_length; |