232 lines
4 KiB
C
232 lines
4 KiB
C
/*
|
|
* common.h - common types and macros
|
|
*
|
|
* Copyright (C) 2014 Arnaud Andre
|
|
*
|
|
* This file is part of uvrrpd.
|
|
*
|
|
* uvrrpd 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* uvrrpd 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 uvrrpd. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#ifndef _COMMON_H_
|
|
#define _COMMON_H_
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <stdint.h>
|
|
#include <limits.h>
|
|
#include <sys/stat.h>
|
|
#include <arpa/inet.h>
|
|
#include "log.h"
|
|
|
|
/**
|
|
* bool - boolean type
|
|
*/
|
|
typedef enum {
|
|
FALSE,
|
|
TRUE
|
|
} bool;
|
|
|
|
/**
|
|
* matches( s, c_str ) - Compare strings.
|
|
* s Data strings
|
|
* c_str C-Strings
|
|
*/
|
|
#define matches( s, c_str ) \
|
|
({ \
|
|
const char __dummy[] = c_str; \
|
|
(void)(&__dummy); \
|
|
( memcmp ( s, c_str, sizeof( c_str ) ) == 0 ); \
|
|
})
|
|
|
|
/**
|
|
* stringify(x)
|
|
*/
|
|
#define _stringify(x) #x
|
|
#define stringify(x) _stringify(x)
|
|
|
|
/**
|
|
* ARRAY_SIZE()
|
|
*/
|
|
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
|
|
|
/**
|
|
* max(a,b)
|
|
*/
|
|
#define max(a,b) \
|
|
({ \
|
|
__typeof__ (a) _a = (a); \
|
|
__typeof__ (b) _b = (b); \
|
|
_a > _b ? _a : _b; \
|
|
})
|
|
|
|
/**
|
|
* WHITESPACE
|
|
*/
|
|
#define WHITESPACE " \f\r\t\n\v"
|
|
|
|
/**
|
|
* cksum - compute IP checksum
|
|
*/
|
|
static inline int unsigned short cksum(unsigned short *buf, int nbytes)
|
|
{
|
|
uint32_t sum;
|
|
uint16_t oddbyte;
|
|
|
|
sum = 0;
|
|
while (nbytes > 1) {
|
|
sum += *buf++;
|
|
nbytes -= 2;
|
|
}
|
|
|
|
if (nbytes == 1) {
|
|
oddbyte = 0;
|
|
*((uint16_t *) & oddbyte) = *(uint16_t *) buf;
|
|
sum += oddbyte;
|
|
}
|
|
|
|
sum = (sum >> 16) + (sum & 0xffff);
|
|
sum += (sum >> 16);
|
|
|
|
return (uint16_t) ~ sum;
|
|
}
|
|
|
|
/**
|
|
* mystrtoul - convert a string to an unsigned long int
|
|
*/
|
|
static inline int mystrtoul(unsigned long *const dest,
|
|
const char *const str, unsigned long max)
|
|
{
|
|
unsigned long val;
|
|
char *endptr;
|
|
|
|
errno = 0;
|
|
val = strtoull(str, &endptr, 0);
|
|
|
|
if ((val == 0 || val == LONG_MAX) && errno == ERANGE)
|
|
return -ERANGE;
|
|
|
|
if (val > max)
|
|
return -ERANGE;
|
|
|
|
if (*endptr != '\0')
|
|
return -EINVAL;
|
|
|
|
*dest = val;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* is_file_executable
|
|
*/
|
|
static inline int is_file_executable(const char *filename)
|
|
{
|
|
struct stat sb;
|
|
|
|
if (stat(filename, &sb) == -1) {
|
|
perror("stat");
|
|
return 0;
|
|
}
|
|
|
|
if (S_ISREG(sb.st_mode) &&
|
|
(sb.st_mode & S_IRUSR) && (sb.st_mode & S_IXUSR))
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
#define IP4_NMASK 32
|
|
#define IP6_NMASK 128
|
|
/**
|
|
* split_ip_netmask() - split IPvX and netmask from a string
|
|
*/
|
|
static inline int split_ip_netmask(int family,
|
|
const char *str, void *addr,
|
|
uint8_t * netmask)
|
|
{
|
|
char *tmp;
|
|
unsigned long ul;
|
|
|
|
int netmask_length, err;
|
|
|
|
/* IPv4 */
|
|
if (family == AF_INET)
|
|
netmask_length = IP4_NMASK;
|
|
|
|
/* IPv6 */
|
|
if (family == AF_INET6)
|
|
netmask_length = IP6_NMASK;
|
|
|
|
tmp = strstr(str, "/");
|
|
*netmask = 0;
|
|
|
|
if (tmp != NULL) {
|
|
*tmp = '\0';
|
|
++tmp;
|
|
err = mystrtoul(&ul, tmp, netmask_length);
|
|
if (err == -ERANGE) {
|
|
log_error("%s", "CIDR netmask out of range");
|
|
return err;
|
|
}
|
|
if (err == -EINVAL) {
|
|
log_error("Error parsing %s as a number", tmp);
|
|
return err;
|
|
}
|
|
|
|
if (netmask != NULL)
|
|
*netmask = (uint8_t) ul;
|
|
}
|
|
|
|
if (inet_pton(family, str, addr) == 0) {
|
|
log_error("inet_pton - %m");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/**
|
|
* print buf hexa
|
|
*/
|
|
static inline void print_buf_hexa(const char *str, void *buf, size_t x)
|
|
{
|
|
uint8_t i;
|
|
int j = 0;
|
|
|
|
unsigned char *pbuf = (unsigned char *) buf;
|
|
|
|
printf("*** %s ***\n", str);
|
|
|
|
for (i = 0; i < x; ++i, ++j) {
|
|
if (j == 4) {
|
|
printf("\n");
|
|
j = 0;
|
|
}
|
|
if (j > 0)
|
|
printf(":");
|
|
printf("%02X", pbuf[i]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
#endif
|
|
|
|
#endif /* _COMMON_H_ */
|