dessert.h

Go to the documentation of this file.
00001 /***************************************************************************/
00031 /***************************************************************************/
00083 #ifndef DESSERT_H
00084 #define DESSERT_H
00085 
00086 #ifdef __DARWIN__
00087 #include <net/if_dl.h>
00088 #define TUN_BSD
00089 #endif
00090 
00091 #ifdef __linux__
00092 #define TUN_LINUX
00093 #endif
00094 
00095 #include <net/if.h>
00096 #include <net/ethernet.h>
00097 #include <pcap.h>
00098 #include <stdint.h>
00099 #include <syslog.h>
00100 #include <stdlib.h>
00101 #include <libcli.h>
00102 
00103 /***************************************************************************/
00112 /******************************************************************************
00113  * #defines
00114  ******************************************************************************/
00115 
00117 #define DESSERT_ETHPROTO 0x88B5
00118 
00123 #define DESSERT_MAXFRAMELEN ETH_FRAME_LEN
00124 
00126 #define DESSERT_MAXEXTDATALEN 254
00127 
00129 #define DESSERT_PROTO_STRLEN 4
00130 
00132 #define DESSERT_LBUF_LEN 1024
00133 
00135 #define DESSERT_OK                  0
00136 
00138 #define DESSERT_ERR                 1
00139 
00140 /******************************************************************************
00141  * typedefs
00142  ******************************************************************************/
00144 typedef uint64_t dessert_frameid_t;
00145 
00152 typedef struct __attribute__ ((__packed__)) dessert_msg {
00154     struct     ether_header l2h;
00156     char       proto[DESSERT_PROTO_STRLEN];
00158     uint8_t    ver;
00160     uint8_t    flags;
00161     union {
00163         uint32_t u32;
00164         struct __attribute__ ((__packed__)) {
00166             uint8_t    ttl;
00168             uint8_t    u8;
00170             uint16_t   u16;
00171         };
00172     };
00174     uint16_t   hlen;
00176     uint16_t   plen;
00177 } dessert_msg_t;
00178 
00186 typedef struct dessert_msg_proc {
00188     uint16_t    lflags;
00190     uint16_t    lreserved;
00192     char        lbuf[DESSERT_LBUF_LEN];
00193 } dessert_msg_proc_t;
00194 
00196 typedef struct __attribute__ ((__packed__)) dessert_ext {
00199     uint8_t    type;
00200 
00206     uint8_t    len;
00207 
00209     uint8_t       data[DESSERT_MAXEXTDATALEN];
00210 } dessert_ext_t;
00211 
00213 typedef struct dessert_meshif {
00215     struct dessert_meshif    *next;
00217     char                if_name[IFNAMSIZ];
00219     unsigned int        if_index;
00221     uint8_t             hwaddr[ETHER_ADDR_LEN]; /* uthash key*/
00223     pthread_mutex_t     cnt_mutex;
00225     uint64_t            ipkts;
00227     uint64_t            opkts;
00229     uint64_t            ibytes;
00231     uint64_t            obytes;
00233     pcap_t              *pcap;
00235     char                pcap_err[PCAP_ERRBUF_SIZE];
00237     pthread_t           worker;
00238 
00240     struct dessert_meshif    *prev;
00241 } dessert_meshif_t;
00242 
00249 typedef struct dessert_sysif {
00251     struct dessert_sysif   *next;
00253     char                if_name[IFNAMSIZ];
00255     unsigned int        if_index;
00257     uint8_t             hwaddr[ETHER_ADDR_LEN];
00259     pthread_mutex_t     cnt_mutex;
00261     uint64_t            ipkts;
00263     uint64_t            opkts;
00265     uint64_t            ibytes;
00267     uint64_t            obytes;
00269     int                 fd;
00271     uint8_t             flags;
00273     pthread_t           worker;
00274 } dessert_sysif_t;
00275 
00298 typedef int dessert_meshrxcb_t(dessert_msg_t* msg, size_t len, dessert_msg_proc_t *proc, const dessert_meshif_t *iface, dessert_frameid_t id);
00299 
00316 typedef int dessert_sysrxcb_t(dessert_msg_t *msg, size_t len, dessert_msg_proc_t *proc, dessert_sysif_t *sysif, dessert_frameid_t id);
00317 
00329 typedef int dessert_periodiccallback_t(void *data, struct timeval *scheduled, struct timeval *interval);
00330 
00332 typedef struct dessert_periodic {
00334     dessert_periodiccallback_t *c;
00336     struct timeval scheduled;
00338     struct timeval interval;
00340     void *data;
00342     struct dessert_periodic  *next;
00343 } dessert_periodic_t;
00344 
00346 typedef int dessert_signalcb_t(int signal);
00347 
00348 /***************************************************************************/
00358 /******************************************************************************
00359  *  #defines
00360  ******************************************************************************/
00361 
00363 #define DESSERT_FRAMEID_MAX ((uint64_t)-1)
00364 
00367 #define DESSERT_OPT_DAEMONIZE    0x0100
00368 
00370 #define DESSERT_OPT_NODAEMONIZE  0x0200
00371 
00372 /******************************************************************************
00373  * globals
00374  ******************************************************************************/
00375 
00377 extern char        dessert_proto[DESSERT_PROTO_STRLEN+1];
00378 
00380 extern u_int8_t    dessert_ver;
00381 
00383 extern u_int8_t    dessert_l25_defsrc[ETHER_ADDR_LEN];
00384 
00385 
00387 extern u_char      ether_broadcast[ETHER_ADDR_LEN];
00388 
00390 extern u_char      ether_null[ETHER_ADDR_LEN];
00391 
00393 extern pthread_rwlock_t dessert_cfglock;
00394 
00395 /******************************************************************************
00396  * functions
00397  ******************************************************************************/
00398 
00399 int dessert_init(const char* proto, int version, uint16_t opts);
00400 int dessert_pid(char* pidfile);
00401 int dessert_run(void);
00402 void dessert_exit(void);
00403 
00404 /***************************************************************************/
00414 /******************************************************************************
00415  * globals
00416  ******************************************************************************/
00417 
00418 extern struct cli_def *dessert_cli; 
00419 
00420 extern struct cli_command *dessert_cli_show; 
00421 extern struct cli_command *dessert_cli_cfg_iface; 
00422 extern struct cli_command *dessert_cli_cfg_no; 
00423 extern struct cli_command *dessert_cli_cfg_no_iface; 
00424 extern struct cli_command *dessert_cli_cfg_set; 
00425 extern struct cli_command *dessert_cli_cfg_logging; 
00426 extern struct cli_command *dessert_cli_cfg_no_logging; 
00427 
00428 /******************************************************************************
00429  * functions
00430  ******************************************************************************/
00431 
00432 int dessert_cli_run(void);
00433 FILE* dessert_cli_get_cfg(int argc, char** argv);
00434 int dessert_set_cli_port(uint16_t port);
00435 
00436 /***************************************************************************/
00446 /******************************************************************************
00447  * #defines
00448  ******************************************************************************/
00449 
00451 #define DESSERT_LOG_SYSLOG    0x0001
00452 
00454 #define DESSERT_LOG_NOSYSLOG  0x0002
00455 
00459 #define DESSERT_LOG_FILE      0x0004
00460 
00462 #define DESSERT_LOG_NOFILE    0x0008
00463 
00465 #define DESSERT_LOG_STDERR    0x0010
00466 
00468 #define DESSERT_LOG_NOSTDERR  0x0020
00469 
00471 #define DESSERT_LOG_RBUF      0x0040
00472 
00474 #define DESSERT_LOG_NORBUF    0x0080
00475 
00481 #define DESSERT_LOG_DEBUG     0x0100
00482 
00488 #define DESSERT_LOG_NODEBUG   0x0200
00489 
00490 /******************************************************************************
00491  * functions
00492  ******************************************************************************/
00493 int dessert_logcfg(uint16_t opts);
00494 void _dessert_log(int level, const char* func, const char* file, int line, const char *fmt, ...);
00496 #define dessert_debug(...) _dessert_log(LOG_DEBUG, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00497 
00498 #define dessert_info(...) _dessert_log(LOG_INFO, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00499 
00500 #define dessert_notice(...) _dessert_log(LOG_NOTICE, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00501 
00502 #define dessert_warn(...) _dessert_log(LOG_WARNING, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00503 
00504 #define dessert_warning(...) _dessert_log(LOG_WARNING, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00505 
00506 #define dessert_err(...) _dessert_log(LOG_ERR, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00507 
00508 #define dessert_crit(...) _dessert_log(LOG_CRIT, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00509 
00510 #define dessert_alert(...) _dessert_log(LOG_ALERT, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00511 
00512 #define dessert_emerg(...) _dessert_log(LOG_EMERG, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
00513 
00514 /***************************************************************************/
00524 /******************************************************************************
00525  * #defines
00526  ******************************************************************************/
00527 
00529 #define DESSERT_MSG_NEEDNOSPARSE     1
00530 
00532 #define DESSERT_MSG_NEEDMSGPROC      2
00533 
00535 #define DESSERT_MSG_KEEP             0
00536 
00538 #define DESSERT_MSG_DROP             -1
00539 
00541 #define DESSERT_IF_PROMISC 0x0
00542 
00544 #define DESSERT_IF_NOPROMISC 0x1
00545 
00547 #define DESSERT_IF_FILTER 0x0
00548 
00550 #define DESSERT_IF_NOFILTER 0x2
00551 
00552 /******************************************************************************
00553  * functions
00554  ******************************************************************************/
00555 
00556 /* sending messages */
00557 int dessert_meshsend(const dessert_msg_t* msgin, const dessert_meshif_t *iface);
00558 int dessert_meshsend_allbutone(const dessert_msg_t* msgin, const dessert_meshif_t *iface);
00559 int dessert_meshsend_hwaddr(const dessert_msg_t* msgin, const uint8_t hwaddr[ETHER_ADDR_LEN]);
00560 int dessert_meshsend_randomized(const dessert_msg_t* msgin);
00561 
00562 int dessert_meshsend_fast(dessert_msg_t* msg, const dessert_meshif_t *iface);
00563 int dessert_meshsend_fast_allbutone(dessert_msg_t* msg, const dessert_meshif_t *iface);
00564 int dessert_meshsend_fast_hwaddr(dessert_msg_t* msg, const uint8_t hwaddr[ETHER_ADDR_LEN]);
00565 int dessert_meshsend_fast_randomized(dessert_msg_t* msgin);
00566 int dessert_meshsend_raw(dessert_msg_t* msg, const dessert_meshif_t *iface);
00567 
00568 /* meshrx-callback handling */
00569 int dessert_meshrxcb_add(dessert_meshrxcb_t* c, int prio);
00570 int dessert_meshrxcb_del(dessert_meshrxcb_t* c);
00571 
00572 /* mesh interface handling */
00573 int dessert_meshif_add(const char* dev, uint8_t flags);
00574 int dessert_meshif_del(const char* dev);
00575 
00576 dessert_meshif_t * dessert_meshif_get_name(const char* dev);
00577 dessert_meshif_t * dessert_meshif_get_hwaddr(const uint8_t hwaddr[ETHER_ADDR_LEN]);
00578 dessert_meshif_t * dessert_meshiflist_get(void);
00579 /*\}*/
00580 /***************************************************************************/
00590 /******************************************************************************
00591  * #defines
00592  ******************************************************************************/
00593 
00595 #define DESSERT_TUN          0x00
00596 
00598 #define DESSERT_TAP          0x01
00599 
00601 #define DESSERT_MAKE_DEFSRC  0x02
00602 
00604 #define _DESSERT_TAP_NOMAC   0x80
00605 
00606 /******************************************************************************
00607  * functions
00608  ******************************************************************************/
00609 
00610 int dessert_sysif_init(char* name, uint8_t flags);
00611 
00612 int dessert_sysrxcb_add(dessert_sysrxcb_t* c, int prio);
00613 int dessert_sysrxcb_del(dessert_sysrxcb_t* c);
00614 
00615 int dessert_syssend_msg(dessert_msg_t *msg);
00616 int dessert_syssend(const void *pkt, size_t len);
00617 
00618 /***************************************************************************/
00628 /******************************************************************************
00629  * #defines
00630  ******************************************************************************/
00631 
00634 #define DESSERT_FLAG_SPARSE 0x1
00635 
00636 /* *********************** */
00637 
00639 #define DESSERT_LFLAG_SRC_SELF 0x0002
00640 
00642 #define DESSERT_LFLAG_DST_MULTICAST 0x0004
00643 
00645 #define DESSERT_LFLAG_DST_SELF 0x0008
00646 
00648 #define DESSERT_LFLAG_DST_BROADCAST 0x0010
00649 
00651 #define DESSERT_LFLAG_PREVHOP_SELF 0x0020
00652 
00654 #define DESSERT_LFLAG_NEXTHOP_SELF 0x0040
00655 
00657 #define DESSERT_LFLAG_NEXTHOP_BROADCAST 0x0080
00658 
00662 #define DESSERT_LFLAG_DST_SELF_OVERHEARD 0x0100
00663 
00667 #define DESSERT_LFLAG_NEXTHOP_SELF_OVERHEARD 0x0200
00668 
00669 /* *********************** */
00670 
00672 #define DESSERT_EXTLEN (sizeof(struct dessert_ext) - DESSERT_MAXEXTDATALEN)
00673 
00675 enum dessert_extensions {
00676   DESSERT_EXT_ANY           = 0x00, 
00677   DESSERT_EXT_ETH           = 0x01, 
00678   DESSERT_EXT_TRACE_REQ     = 0x02, 
00679   DESSERT_EXT_TRACE_RPL     = 0x03, 
00680   DESSERT_EXT_PING          = 0x04, 
00681   DESSERT_EXT_PONG          = 0x05, 
00682   /* leave some space for future extensions */
00683   DESSERT_EXT_USER          = 0x40, 
00684 };
00685 
00686 /* *********************** */
00687 
00689 #define DESSERT_MSG_TRACE_HOST (ETHER_ADDR_LEN)
00690 
00692 #define DESSERT_MSG_TRACE_IFACE (3*ETHER_ADDR_LEN)
00693 
00694 /* *********************** */
00695 
00697 static inline size_t dessert_ext_getdatalen(dessert_ext_t* ext) { return (ext->len - DESSERT_EXTLEN); }
00698 
00699 /******************************************************************************
00700  * functions
00701  ******************************************************************************/
00702 
00703 int dessert_msg_new(dessert_msg_t **msgout);
00704 int dessert_msg_clone(dessert_msg_t **msgnew, const dessert_msg_t *msgold, uint8_t sparse);
00705 int dessert_msg_check(const dessert_msg_t* msg, size_t len);
00706 void dessert_msg_dump(const dessert_msg_t* msg, size_t len, char *buf, size_t blen);
00707 void dessert_msg_destroy(dessert_msg_t* msg);
00708 
00709 int dessert_msg_ethencap(const struct ether_header* eth, size_t eth_len, dessert_msg_t **msgout);
00710 int dessert_msg_ethdecap(const dessert_msg_t* msg, struct ether_header** ethout);
00711 struct ether_header* dessert_msg_getl25ether (const dessert_msg_t* msg);
00712 int dessert_msg_ipencap(const uint8_t* ip, size_t len, dessert_msg_t** msgout);
00713 int dessert_msg_ipdecap(const dessert_msg_t* msg, uint8_t** ip);
00714 
00715 int dessert_msg_proc_clone(dessert_msg_proc_t **procnew, const dessert_msg_proc_t *procold);
00716 void dessert_msg_proc_dump(const dessert_msg_t* msg, size_t len, const dessert_msg_proc_t *proc, char *buf, size_t blen);
00717 void dessert_msg_proc_destroy(dessert_msg_proc_t* proc);
00718 
00719 int dessert_msg_addpayload(dessert_msg_t* msg, void** payload, int len);
00720 int dessert_msg_getpayload(dessert_msg_t *msg, void **payload);
00721 int dessert_msg_addext(dessert_msg_t* msg, dessert_ext_t** ext, uint8_t type, size_t len);
00722 int dessert_msg_delext(dessert_msg_t *msg, dessert_ext_t *ext);
00723 int dessert_msg_resizeext(dessert_msg_t *msg, dessert_ext_t *ext, size_t new_len);
00724 int dessert_msg_getext(const dessert_msg_t* msg, dessert_ext_t** ext, uint8_t type, int index);
00725 int dessert_msg_get_ext_count(const dessert_msg_t* msg, uint8_t type);
00726 
00727 int dessert_msg_dump_cb(dessert_msg_t* msg, size_t len, dessert_msg_proc_t *proc, const dessert_meshif_t *iface, dessert_frameid_t id);
00728 int dessert_msg_check_cb(dessert_msg_t* msg, size_t len, dessert_msg_proc_t *proc, const dessert_meshif_t *iface, dessert_frameid_t id);
00729 int dessert_msg_trace_cb(dessert_msg_t* msg, size_t len, dessert_msg_proc_t *proc, const dessert_meshif_t *iface, dessert_frameid_t id);
00730 int dessert_msg_ifaceflags_cb(dessert_msg_t* msg, size_t len, dessert_msg_proc_t *proc, const dessert_meshif_t *riface, dessert_frameid_t id);
00731 
00732 int dessert_msg_trace_dump(const dessert_msg_t* msg, uint8_t type, char* buf, int blen);
00733 
00734 /***************************************************************************/
00744 dessert_periodic_t *dessert_periodic_add(dessert_periodiccallback_t* c, void *data, const struct timeval *scheduled, const struct timeval *interval);
00745 dessert_periodic_t *dessert_periodic_add_delayed(dessert_periodiccallback_t* c, void *data, int delay);
00746 int dessert_periodic_del(dessert_periodic_t *p);
00747 
00748 /***************************************************************************/
00758 int dessert_signalcb_add(int signal, dessert_signalcb_t* callback);
00759 int dessert_signalcb_del(int signal, dessert_signalcb_t* callback);
00760 
00761 /***************************************************************************/
00771 /******************************************************************************
00772  * #defines
00773  ******************************************************************************/
00775 #define DESSERT_APPSTATS_VALUETYPE_BOOL         0
00776 
00778 #define DESSERT_APPSTATS_VALUETYPE_INT32        1
00779 
00781 #define DESSERT_APPSTATS_VALUETYPE_UINT32       2
00782 
00784 #define DESSERT_APPSTATS_VALUETYPE_COUNTER64    3
00785 
00787 #define DESSERT_APPSTATS_VALUETYPE_OCTETSTRING  4
00788 
00789 /* *********************** */
00790 
00792 #define DESSERT_APPSTATS_NODEORLINK_NONE        0
00793 
00795 #define DESSERT_APPSTATS_NODEORLINK_NODE        1
00796 
00798 #define DESSERT_APPSTATS_NODEORLINK_LINK        2
00799 
00800 /* *********************** */
00801 
00803 #define DESSERT_APPSTATS_BOOL_TRUE  1
00804 
00806 #define DESSERT_APPSTATS_BOOL_FALSE 0
00807 
00808 /* *********************** */
00809 
00811 #define DESSERT_APPPARAMS_VALUETYPE_BOOL         0
00812 
00814 #define DESSERT_APPPARAMS_VALUETYPE_INT32        1
00815 
00817 #define DESSERT_APPPARAMS_VALUETYPE_UINT32       2
00818 
00820 #define DESSERT_APPPARAMS_VALUETYPE_OCTETSTRING  3
00821 
00822 /* *********************** */
00823 
00825 #define DESSERT_APPPARAMS_BOOL_TRUE  1
00826 
00828 #define DESSERT_APPPARAMS_BOOL_FALSE 0
00829 
00830 /* *********************** */
00831 
00833 #define DESSERT_APPSTATS_CB_BULK   1
00834 
00835 #define DESSERT_APPSTATS_CB_NOBULK 2
00836 
00837 /******************************************************************************
00838  * typedefs
00839  ******************************************************************************/
00840 
00842 typedef struct dessert_agentx_appstats {
00843 
00845     struct dessert_agentx_appstats *prev;
00847     struct dessert_agentx_appstats *next;
00848 
00850     char name[256];
00852     char desc[256];
00853 
00862     int value_type;
00869     int node_or_link;
00870 
00872     uint8_t macaddress1 [ETHER_ADDR_LEN];
00874     uint8_t macaddress2 [ETHER_ADDR_LEN];
00875 
00876     union {
00882         uint8_t  bool;
00884         int32_t  int32;
00886         uint32_t uint32;
00888         uint64_t counter64;
00889 
00890         struct {
00892             uint8_t octetstring_len;
00894             char *octetstring;
00895         };
00896     };
00897 
00898 } dessert_agentx_appstats_t;
00899 
00901 typedef struct dessert_agentx_appparams {
00902 
00904     struct dessert_agentx_appparams *prev;
00906     struct dessert_agentx_appparams *next;
00907 
00909     uint8_t index;
00910 
00912     char name[256];
00914     char desc[256];
00915 
00923     int value_type;
00924 
00925     union {
00931         uint8_t  bool;
00933         int32_t  int32;
00935         uint32_t uint32;
00936 
00937         struct {
00939             uint16_t octetstring_len;
00941             char *octetstring;
00942         };
00943     };
00944 
00945 } dessert_agentx_appparams_t;
00946 
00956 typedef int dessert_agentx_appstatscb_get_t(struct dessert_agentx_appstats *appstats);
00957 
00967 typedef int dessert_agentx_appparamscb_get_t(struct dessert_agentx_appparams *appparams);
00968 
00979 typedef int dessert_agentx_appparamscb_set_t(struct dessert_agentx_appparams *appparams);
00980 
00982 typedef struct dessert_agentx_appstats_cb_entry {
00983 
00985     struct dessert_agentx_appstats_cb_entry *prev;
00987     struct dessert_agentx_appstats_cb_entry *next;
00988 
00990     uint8_t isbulk_flag;
00991 
00993     dessert_agentx_appstatscb_get_t *c;
00994 
00995 } dessert_agentx_appstats_cb_entry_t;
00996 
00998 typedef struct dessert_agentx_appparams_cb_entry {
00999 
01001     struct dessert_agentx_appparams_cb_entry *prev;
01003     struct dessert_agentx_appparams_cb_entry *next;
01004 
01006     uint8_t index;
01007 
01009     dessert_agentx_appparamscb_get_t *get;
01011     dessert_agentx_appparamscb_set_t *set;
01012 
01013 } dessert_agentx_appparams_cb_entry_t;
01014 
01015 
01016 /******************************************************************************
01017  * globals
01018  ******************************************************************************/
01019 
01020 
01021 /******************************************************************************
01022  * functions
01023  ******************************************************************************/
01024 dessert_agentx_appstats_t *dessert_agentx_appstats_new(void);
01025 void dessert_agentx_appstats_destroy(dessert_agentx_appstats_t *appstat);
01026 
01027 dessert_agentx_appstats_cb_entry_t *dessert_agentx_appstats_add(dessert_agentx_appstatscb_get_t *c);
01028 dessert_agentx_appstats_cb_entry_t *dessert_agentx_appstats_add_bulk(dessert_agentx_appstatscb_get_t *c);
01029 int dessert_agentx_appstats_del(dessert_agentx_appstats_cb_entry_t *e);
01030 
01031 dessert_agentx_appparams_t *dessert_agentx_appparam_new(void);
01032 void dessert_agentx_appparam_destroy(dessert_agentx_appparams_t *appparam);
01033 
01034 dessert_agentx_appparams_cb_entry_t *dessert_agentx_appparams_add(dessert_agentx_appparamscb_get_t *get, dessert_agentx_appparamscb_set_t *set);
01035 int dessert_agentx_appparams_del(dessert_agentx_appparams_cb_entry_t *e);
01036 
01037 /**************************************************************************/
01065 #define MESHIFLIST_ITERATOR_START(__interface) \
01066 pthread_rwlock_rdlock(&dessert_cfglock); \
01067 DL_FOREACH(dessert_meshiflist_get(), __interface) {
01068 
01073 #define MESHIFLIST_ITERATOR_STOP } pthread_rwlock_unlock(&dessert_cfglock)
01074 
01089 #define TIMEVAL_ADD(__tv, __sec, __usec)       \
01090     do {                                       \
01091         (__tv)->tv_sec  += __sec;              \
01092         (__tv)->tv_usec += __usec;             \
01093         if((__tv)->tv_usec >= 1000000) {       \
01094             ++(__tv)->tv_sec;                  \
01095             (__tv)->tv_usec -= 1000000;        \
01096         }                                      \
01097     } while(0)
01098 
01106 #define likely(x)       (__builtin_expect((x),1))
01107 
01115 #define unlikely(x)     (__builtin_expect((x),0))
01116 
01117 #define __dessert_assert(func, file, line, e) \
01118     ((void)_dessert_log(LOG_EMERG, func, file, line, "assertion `%s' failed!\n", e), abort)
01119 
01126 #ifdef NDEBUG
01127 #define assert(e)       ((void)0)
01128 #else
01129 #define assert(e) \
01130     (__builtin_expect(!(e), 0) ? __dessert_assert(__FUNCTION__, __FILE__, __LINE__, #e) : (void)0)
01131 #endif
01132 
01135 #endif /* DESSERT_H*/