moved ip-related macros to ip-util

This commit is contained in:
Nikos Mavrogiannopoulos
2015-10-30 14:03:24 +01:00
parent 4ae1c3e2ff
commit 7a4fc3b0aa
11 changed files with 188 additions and 127 deletions

View File

@@ -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 \
worker-bandwidth.c worker-bandwidth.h ctl.h main-ctl.h \
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 \
str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \
$(PROTOBUF_SOURCES) sec-mod-acct.h setproctitle.c setproctitle.h

View File

@@ -1,5 +1,6 @@
/*
* 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
@@ -28,8 +29,6 @@
/* for recvmsg */
#include <netinet/in.h>
#include <netinet/ip.h>
/* for inet_ntop */
#include <arpa/inet.h>
#include "common.h"
@@ -255,51 +254,6 @@ fd_set set;
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 */
int send_socket_msg(void *pool, int fd, uint8_t cmd,
int socketfd,
@@ -571,59 +525,6 @@ struct msghdr mh = {
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
/*

View File

@@ -42,22 +42,10 @@ void *_talloc_size2(void *ctx, size_t size);
void set_non_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_read(int sockfd, void *buf, size_t len);
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);
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_size_func)(const void*);

View File

@@ -29,6 +29,7 @@
#include <autoopts/options.h>
#include <limits.h>
#include <common.h>
#include <ip-util.h>
#include <c-strcase.h>
#include <c-ctype.h>
#include <auth/pam.h>

View File

@@ -22,7 +22,7 @@
#include <ip-lease.h>
#include <main.h>
#include <common.h>
#include <ip-util.h>
#include <gnutls/crypto.h>
#include <icmp-ping.h>
#include <arpa/inet.h>

123
src/ip-util.c Normal file
View 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
View 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

View File

@@ -36,6 +36,7 @@
#include <vpn.h>
#include <main.h>
#include <common.h>
#include <ip-util.h>
#include <tlslib.h>
int handle_resume_delete_req(main_server_st * s, struct proc_st *proc,

View File

@@ -30,6 +30,7 @@
#include <autoopts/options.h>
#include <limits.h>
#include <common.h>
#include <ip-util.h>
#include <c-strcase.h>
#include <vpn.h>

View File

@@ -29,6 +29,7 @@
#include <autoopts/options.h>
#include <limits.h>
#include <common.h>
#include <ip-util.h>
#include <c-strcase.h>
#ifdef HAVE_RADIUS

View File

@@ -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)
/* 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 */
#define TOS_PACK(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 */
enum option_types { OPTION_NUMERIC, OPTION_STRING, OPTION_BOOLEAN, OPTION_MULTI_LINE };
#include <ip-util.h>
#endif