-/*
- * This file is free software: you may copy, redistribute 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 file 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/>.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *
+/*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
THE SOFTWARE.
*/
+#ifndef BABEL_UTIL_H
+#define BABEL_UTIL_H
+
#include "babeld.h"
#include "babel_main.h"
#include "log.h"
#if defined(i386) || defined(__mc68020__) || defined(__x86_64__)
-#define DO_NTOHS(_d, _s) do { _d = ntohs(*(unsigned short*)(_s)); } while(0)
-#define DO_NTOHL(_d, _s) do { _d = ntohl(*(unsigned*)(_s)); } while(0)
-#define DO_HTONS(_d, _s) do { *(unsigned short*)(_d) = htons(_s); } while(0)
-#define DO_HTONL(_d, _s) do { *(unsigned*)(_d) = htonl(_s); } while(0)
+#define DO_NTOHS(_d, _s) do{ _d = ntohs(*(const unsigned short*)(_s)); }while(0)
+#define DO_NTOHL(_d, _s) do{ _d = ntohl(*(const unsigned*)(_s)); } while(0)
+#define DO_HTONS(_d, _s) do{ *(unsigned short*)(_d) = htons(_s); } while(0)
+#define DO_HTONL(_d, _s) do{ *(unsigned*)(_d) = htonl(_s); } while(0)
/* Some versions of gcc seem to be buggy, and ignore the packed attribute.
Disable this code until the issue is clarified. */
/* #elif defined __GNUC__*/
-#elif 0
-struct __us { unsigned short x __attribute__((packed)); };
-#define DO_NTOHS(_d, _s) \
- do { _d = ntohs(((const struct __us*)(_s))->x); } while(0)
-#define DO_HTONS(_d, _s) \
- do { ((struct __us*)(_d))->x = htons(_s); } while(0)
#else
#define DO_NTOHS(_d, _s) \
do { short _dd; \
memcpy(&(_dd), (_s), 2); \
_d = ntohs(_dd); } while(0)
+#define DO_NTOHL(_d, _s) \
+ do { int _dd; \
+ memcpy(&(_dd), (_s), 4); \
+ _d = ntohl(_dd); } while(0)
#define DO_HTONS(_d, _s) \
do { unsigned short _dd; \
_dd = htons(_s); \
memcpy((_d), &(_dd), 2); } while(0)
+#define DO_HTONL(_d, _s) \
+ do { unsigned _dd; \
+ _dd = htonl(_s); \
+ memcpy((_d), &(_dd), 4); } while(0)
#endif
static inline int
return ((s + plus) & 0xFFFF);
}
-unsigned roughly(unsigned value);
+/* Returns a time in microseconds on 32 bits (thus modulo 2^32,
+ i.e. about 4295 seconds). */
+static inline unsigned int
+time_us(const struct timeval t)
+{
+ return (unsigned int) (t.tv_sec * 1000000 + t.tv_usec);
+}
+
+int roughly(int value);
void timeval_minus(struct timeval *d,
const struct timeval *s1, const struct timeval *s2);
unsigned timeval_minus_msec(const struct timeval *s1, const struct timeval *s2)
ATTRIBUTE ((pure));
-void timeval_add_msec(struct timeval *d,
- const struct timeval *s, const int msecs);
+void timeval_add_msec(struct timeval *d, const struct timeval *s, int msecs);
void set_timeout (struct timeval *timeout, int msecs);
int timeval_compare(const struct timeval *s1, const struct timeval *s2)
ATTRIBUTE ((pure));
void timeval_min(struct timeval *d, const struct timeval *s);
void timeval_min_sec(struct timeval *d, time_t secs);
+int parse_nat(const char *string) ATTRIBUTE ((pure));
int parse_msec(const char *string) ATTRIBUTE ((pure));
-void do_debugf(const char *format, ...)
- ATTRIBUTE ((format (printf, 1, 2))) COLD;
int in_prefix(const unsigned char *restrict address,
const unsigned char *restrict prefix, unsigned char plen)
ATTRIBUTE ((pure));
const char *format_address(const unsigned char *address);
const char *format_prefix(const unsigned char *address, unsigned char prefix);
const char *format_eui64(const unsigned char *eui);
+const char *format_thousands(unsigned int value);
int parse_address(const char *address, unsigned char *addr_r, int *af_r);
-int parse_net(const char *ifp, unsigned char *prefix_r, unsigned char *plen_r,
- int *af_r);
int parse_eui64(const char *eui, unsigned char *eui_r);
int wait_for_fd(int direction, int fd, int msecs);
int martian_prefix(const unsigned char *prefix, int plen) ATTRIBUTE ((pure));
void in6addr_to_uchar(unsigned char *dest, const struct in6_addr *src);
void uchar_to_in6addr(struct in6_addr *dest, const unsigned char *src);
int daemonise(void);
+const unsigned char v4prefix[16];
/* If debugging is disabled, we want to avoid calling format_address
for every omitted debugging message. So debug is a macro. But
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#define debugf(level, ...) \
do { \
-if(UNLIKELY(debug & level)) do_debugf(__VA_ARGS__); \
+if(UNLIKELY(debug & level)) zlog_debug(__VA_ARGS__); \
} while(0)
#elif defined __GNUC__
#define debugf(level, _args...) \
do { \
-if(UNLIKELY(debug & level)) do_debugf(_args); \
+if(UNLIKELY(debug & level)) zlog_debug(_args); \
} while(0)
#else
static inline void debugf(int level, const char *format, ...) { return; }
#endif /* NO_DEBUG */
+#endif /* BABEL_UTIL_H */