mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-03-15 14:58:21 +08:00
moved ip-related macros to ip-util
This commit is contained in:
@@ -76,7 +76,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
|||||||
sup-config/radius.c sup-config/radius.h \
|
sup-config/radius.c sup-config/radius.h \
|
||||||
worker-bandwidth.c worker-bandwidth.h ctl.h main-ctl.h \
|
worker-bandwidth.c worker-bandwidth.h ctl.h main-ctl.h \
|
||||||
vasprintf.c vasprintf.h worker-proxyproto.c \
|
vasprintf.c vasprintf.h worker-proxyproto.c \
|
||||||
proc-search.c proc-search.h http-heads.h \
|
proc-search.c proc-search.h http-heads.h ip-util.c ip-util.h \
|
||||||
main-ban.c main-ban.h common-config.h \
|
main-ban.c main-ban.h common-config.h \
|
||||||
str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \
|
str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \
|
||||||
$(PROTOBUF_SOURCES) sec-mod-acct.h setproctitle.c setproctitle.h
|
$(PROTOBUF_SOURCES) sec-mod-acct.h setproctitle.c setproctitle.h
|
||||||
|
|||||||
101
src/common.c
101
src/common.c
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2015 Nikos Mavrogiannopoulos
|
* Copyright (C) 2013-2015 Nikos Mavrogiannopoulos
|
||||||
|
* Copyright (C) 2015 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -28,8 +29,6 @@
|
|||||||
/* for recvmsg */
|
/* for recvmsg */
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
/* for inet_ntop */
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
@@ -255,51 +254,6 @@ fd_set set;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2)
|
|
||||||
{
|
|
||||||
if (((struct sockaddr*)s1)->sa_family == AF_INET) {
|
|
||||||
return memcmp(SA_IN_P(s1), SA_IN_P(s2), sizeof(struct in_addr));
|
|
||||||
} else { /* inet6 */
|
|
||||||
return memcmp(SA_IN6_P(s1), SA_IN6_P(s2), sizeof(struct in6_addr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns an allocated string with the mask to apply for the prefix
|
|
||||||
*/
|
|
||||||
char* ipv4_prefix_to_strmask(void *pool, unsigned prefix)
|
|
||||||
{
|
|
||||||
struct in_addr in;
|
|
||||||
char str[MAX_IP_STR];
|
|
||||||
|
|
||||||
if (prefix == 0 || prefix > 32)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
in.s_addr = ntohl(((uint32_t)0xFFFFFFFF) << (32 - prefix));
|
|
||||||
if (inet_ntop(AF_INET, &in, str, sizeof(str)) == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return talloc_strdup(pool, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned ipv6_prefix_to_mask(struct in6_addr *in6, unsigned prefix)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
if (prefix == 0 || prefix > 128)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
memset(in6, 0x0, sizeof(*in6));
|
|
||||||
for (i = prefix, j = 0; i > 0; i -= 8, j++) {
|
|
||||||
if (i >= 8) {
|
|
||||||
in6->s6_addr[j] = 0xff;
|
|
||||||
} else {
|
|
||||||
in6->s6_addr[j] = (unsigned long)(0xffU << ( 8 - i ));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sends message + socketfd */
|
/* Sends message + socketfd */
|
||||||
int send_socket_msg(void *pool, int fd, uint8_t cmd,
|
int send_socket_msg(void *pool, int fd, uint8_t cmd,
|
||||||
int socketfd,
|
int socketfd,
|
||||||
@@ -571,59 +525,6 @@ struct msghdr mh = {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether a route is on the expected format, and if it cannot be
|
|
||||||
* fixed, then returns a negative code.
|
|
||||||
*
|
|
||||||
* The expected format by clients for IPv4 is xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx, i.e.,
|
|
||||||
* this function converts xxx.xxx.xxx.xxx/prefix to the above for IPv4.
|
|
||||||
*/
|
|
||||||
int ip_route_sanity_check(void *pool, char **_route)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
unsigned prefix;
|
|
||||||
char *route = *_route, *n;
|
|
||||||
char *slash_ptr, *pstr;
|
|
||||||
|
|
||||||
/* this check is valid for IPv4 only */
|
|
||||||
p = strchr(route, '.');
|
|
||||||
if (p == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
p = strchr(p, '/');
|
|
||||||
if (p == NULL) {
|
|
||||||
fprintf(stderr, "route '%s' in wrong format, use xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx\n", route);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
slash_ptr = p;
|
|
||||||
p++;
|
|
||||||
|
|
||||||
/* if we are in dotted notation exit */
|
|
||||||
if (strchr(p, '.') != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* we are most likely in the xxx.xxx.xxx.xxx/prefix format */
|
|
||||||
prefix = atoi(p);
|
|
||||||
|
|
||||||
pstr = ipv4_prefix_to_strmask(pool, prefix);
|
|
||||||
if (pstr == NULL) {
|
|
||||||
fprintf(stderr, "cannot figure format of route '%s'\n", route);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*slash_ptr = 0;
|
|
||||||
|
|
||||||
n = talloc_asprintf(pool, "%s/%s", route, pstr);
|
|
||||||
if (n == NULL) {
|
|
||||||
fprintf(stderr, "memory error\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*_route = n;
|
|
||||||
|
|
||||||
talloc_free(pstr);
|
|
||||||
talloc_free(route);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef HAVE_STRLCPY
|
#ifndef HAVE_STRLCPY
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
12
src/common.h
12
src/common.h
@@ -42,22 +42,10 @@ void *_talloc_size2(void *ctx, size_t size);
|
|||||||
void set_non_block(int fd);
|
void set_non_block(int fd);
|
||||||
void set_block(int fd);
|
void set_block(int fd);
|
||||||
|
|
||||||
int ip_route_sanity_check(void *pool, char **_route);
|
|
||||||
|
|
||||||
ssize_t force_write(int sockfd, const void *buf, size_t len);
|
ssize_t force_write(int sockfd, const void *buf, size_t len);
|
||||||
ssize_t force_read(int sockfd, void *buf, size_t len);
|
ssize_t force_read(int sockfd, void *buf, size_t len);
|
||||||
ssize_t force_read_timeout(int sockfd, void *buf, size_t len, unsigned sec);
|
ssize_t force_read_timeout(int sockfd, void *buf, size_t len, unsigned sec);
|
||||||
ssize_t recv_timeout(int sockfd, void *buf, size_t len, unsigned sec);
|
ssize_t recv_timeout(int sockfd, void *buf, size_t len, unsigned sec);
|
||||||
int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2);
|
|
||||||
char* ipv4_prefix_to_strmask(void *pool, unsigned prefix);
|
|
||||||
unsigned ipv6_prefix_to_mask(struct in6_addr *in6, unsigned prefix);
|
|
||||||
inline static int valid_ipv6_prefix(unsigned prefix)
|
|
||||||
{
|
|
||||||
if (prefix > 10 && prefix <= 128)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef size_t (*pack_func)(const void*, uint8_t *);
|
typedef size_t (*pack_func)(const void*, uint8_t *);
|
||||||
typedef size_t (*pack_size_func)(const void*);
|
typedef size_t (*pack_size_func)(const void*);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <autoopts/options.h>
|
#include <autoopts/options.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <ip-util.h>
|
||||||
#include <c-strcase.h>
|
#include <c-strcase.h>
|
||||||
#include <c-ctype.h>
|
#include <c-ctype.h>
|
||||||
#include <auth/pam.h>
|
#include <auth/pam.h>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <ip-lease.h>
|
#include <ip-lease.h>
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <common.h>
|
#include <ip-util.h>
|
||||||
#include <gnutls/crypto.h>
|
#include <gnutls/crypto.h>
|
||||||
#include <icmp-ping.h>
|
#include <icmp-ping.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|||||||
123
src/ip-util.c
Normal file
123
src/ip-util.c
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2015 Nikos Mavrogiannopoulos
|
||||||
|
* Copyright (C) 2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include "ip-util.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <talloc.h>
|
||||||
|
/* for inet_ntop */
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2)
|
||||||
|
{
|
||||||
|
if (((struct sockaddr*)s1)->sa_family == AF_INET) {
|
||||||
|
return memcmp(SA_IN_P(s1), SA_IN_P(s2), sizeof(struct in_addr));
|
||||||
|
} else { /* inet6 */
|
||||||
|
return memcmp(SA_IN6_P(s1), SA_IN6_P(s2), sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns an allocated string with the mask to apply for the prefix
|
||||||
|
*/
|
||||||
|
char* ipv4_prefix_to_strmask(void *pool, unsigned prefix)
|
||||||
|
{
|
||||||
|
struct in_addr in;
|
||||||
|
char str[MAX_IP_STR];
|
||||||
|
|
||||||
|
if (prefix == 0 || prefix > 32)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
in.s_addr = ntohl(((uint32_t)0xFFFFFFFF) << (32 - prefix));
|
||||||
|
if (inet_ntop(AF_INET, &in, str, sizeof(str)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return talloc_strdup(pool, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ipv6_prefix_to_mask(struct in6_addr *in6, unsigned prefix)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (prefix == 0 || prefix > 128)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(in6, 0x0, sizeof(*in6));
|
||||||
|
for (i = prefix, j = 0; i > 0; i -= 8, j++) {
|
||||||
|
if (i >= 8) {
|
||||||
|
in6->s6_addr[j] = 0xff;
|
||||||
|
} else {
|
||||||
|
in6->s6_addr[j] = (unsigned long)(0xffU << ( 8 - i ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check whether a route is on the expected format, and if it cannot be
|
||||||
|
* fixed, then returns a negative code.
|
||||||
|
*
|
||||||
|
* The expected format by clients for IPv4 is xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx, i.e.,
|
||||||
|
* this function converts xxx.xxx.xxx.xxx/prefix to the above for IPv4.
|
||||||
|
*/
|
||||||
|
int ip_route_sanity_check(void *pool, char **_route)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
unsigned prefix;
|
||||||
|
char *route = *_route, *n;
|
||||||
|
char *slash_ptr, *pstr;
|
||||||
|
|
||||||
|
/* this check is valid for IPv4 only */
|
||||||
|
p = strchr(route, '.');
|
||||||
|
if (p == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
p = strchr(p, '/');
|
||||||
|
if (p == NULL) {
|
||||||
|
fprintf(stderr, "route '%s' in wrong format, use xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx\n", route);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
slash_ptr = p;
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* if we are in dotted notation exit */
|
||||||
|
if (strchr(p, '.') != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* we are most likely in the xxx.xxx.xxx.xxx/prefix format */
|
||||||
|
prefix = atoi(p);
|
||||||
|
|
||||||
|
pstr = ipv4_prefix_to_strmask(pool, prefix);
|
||||||
|
if (pstr == NULL) {
|
||||||
|
fprintf(stderr, "cannot figure format of route '%s'\n", route);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*slash_ptr = 0;
|
||||||
|
|
||||||
|
n = talloc_asprintf(pool, "%s/%s", route, pstr);
|
||||||
|
if (n == NULL) {
|
||||||
|
fprintf(stderr, "memory error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*_route = n;
|
||||||
|
|
||||||
|
talloc_free(pstr);
|
||||||
|
talloc_free(route);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
56
src/ip-util.h
Normal file
56
src/ip-util.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013, 2014 Nikos Mavrogiannopoulos
|
||||||
|
* Copyright (C) 2014 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Author: Nikos Mavrogiannopoulos
|
||||||
|
*
|
||||||
|
* This file is part of ocserv.
|
||||||
|
*
|
||||||
|
* The GnuTLS is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
#ifndef IP_UTIL_H
|
||||||
|
# define IP_UTIL_H
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#define MAX_IP_STR 46
|
||||||
|
|
||||||
|
int ip_route_sanity_check(void *pool, char **_route);
|
||||||
|
|
||||||
|
int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2);
|
||||||
|
char* ipv4_prefix_to_strmask(void *pool, unsigned prefix);
|
||||||
|
unsigned ipv6_prefix_to_mask(struct in6_addr *in6, unsigned prefix);
|
||||||
|
inline static int valid_ipv6_prefix(unsigned prefix)
|
||||||
|
{
|
||||||
|
if (prefix > 10 && prefix <= 128)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper casts */
|
||||||
|
#define SA_IN_P(p) (&((struct sockaddr_in *)(p))->sin_addr)
|
||||||
|
#define SA_IN_U8_P(p) ((uint8_t*)(&((struct sockaddr_in *)(p))->sin_addr))
|
||||||
|
#define SA_IN6_P(p) (&((struct sockaddr_in6 *)(p))->sin6_addr)
|
||||||
|
#define SA_IN6_U8_P(p) ((uint8_t*)(&((struct sockaddr_in6 *)(p))->sin6_addr))
|
||||||
|
|
||||||
|
#define SA_IN_PORT(p) (((struct sockaddr_in *)(p))->sin_port)
|
||||||
|
#define SA_IN6_PORT(p) (((struct sockaddr_in6 *)(p))->sin6_port)
|
||||||
|
|
||||||
|
#define SA_IN_P_GENERIC(addr, size) ((size==sizeof(struct sockaddr_in))?SA_IN_U8_P(addr):SA_IN6_U8_P(addr))
|
||||||
|
#define SA_IN_P_TYPE(addr, type) ((type==AF_INET)?SA_IN_U8_P(addr):SA_IN6_U8_P(addr))
|
||||||
|
#define SA_IN_SIZE(size) ((size==sizeof(struct sockaddr_in))?sizeof(struct in_addr):sizeof(struct in6_addr))
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <ip-util.h>
|
||||||
#include <tlslib.h>
|
#include <tlslib.h>
|
||||||
|
|
||||||
int handle_resume_delete_req(main_server_st * s, struct proc_st *proc,
|
int handle_resume_delete_req(main_server_st * s, struct proc_st *proc,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <autoopts/options.h>
|
#include <autoopts/options.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <ip-util.h>
|
||||||
#include <c-strcase.h>
|
#include <c-strcase.h>
|
||||||
|
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <autoopts/options.h>
|
#include <autoopts/options.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <ip-util.h>
|
||||||
#include <c-strcase.h>
|
#include <c-strcase.h>
|
||||||
|
|
||||||
#ifdef HAVE_RADIUS
|
#ifdef HAVE_RADIUS
|
||||||
|
|||||||
15
src/vpn.h
15
src/vpn.h
@@ -463,19 +463,6 @@ char *human_addr2(const struct sockaddr *sa, socklen_t salen,
|
|||||||
|
|
||||||
#define human_addr(x, y, z, w) human_addr2(x, y, z, w, 1)
|
#define human_addr(x, y, z, w) human_addr2(x, y, z, w, 1)
|
||||||
|
|
||||||
/* Helper casts */
|
|
||||||
#define SA_IN_P(p) (&((struct sockaddr_in *)(p))->sin_addr)
|
|
||||||
#define SA_IN_U8_P(p) ((uint8_t*)(&((struct sockaddr_in *)(p))->sin_addr))
|
|
||||||
#define SA_IN6_P(p) (&((struct sockaddr_in6 *)(p))->sin6_addr)
|
|
||||||
#define SA_IN6_U8_P(p) ((uint8_t*)(&((struct sockaddr_in6 *)(p))->sin6_addr))
|
|
||||||
|
|
||||||
#define SA_IN_PORT(p) (((struct sockaddr_in *)(p))->sin_port)
|
|
||||||
#define SA_IN6_PORT(p) (((struct sockaddr_in6 *)(p))->sin6_port)
|
|
||||||
|
|
||||||
#define SA_IN_P_GENERIC(addr, size) ((size==sizeof(struct sockaddr_in))?SA_IN_U8_P(addr):SA_IN6_U8_P(addr))
|
|
||||||
#define SA_IN_P_TYPE(addr, type) ((type==AF_INET)?SA_IN_U8_P(addr):SA_IN6_U8_P(addr))
|
|
||||||
#define SA_IN_SIZE(size) ((size==sizeof(struct sockaddr_in))?sizeof(struct in_addr):sizeof(struct in6_addr))
|
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
#define TOS_PACK(x) (x<<4)
|
#define TOS_PACK(x) (x<<4)
|
||||||
#define TOS_UNPACK(x) (x>>4)
|
#define TOS_UNPACK(x) (x>>4)
|
||||||
@@ -484,4 +471,6 @@ char *human_addr2(const struct sockaddr *sa, socklen_t salen,
|
|||||||
/* Helper structures */
|
/* Helper structures */
|
||||||
enum option_types { OPTION_NUMERIC, OPTION_STRING, OPTION_BOOLEAN, OPTION_MULTI_LINE };
|
enum option_types { OPTION_NUMERIC, OPTION_STRING, OPTION_BOOLEAN, OPTION_MULTI_LINE };
|
||||||
|
|
||||||
|
#include <ip-util.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user