#ifndef _LIBGLOUGLOU_H_ #define _LIBGLOUGLOU_H_ #include #include #if defined(__OpenBSD__) #include #else #include #endif /* libglouglou.c */ #define GLOUGLOU_PROBE_DEFAULT_PORT 4430 #define GLOUGLOU_ANALY_DEFAULT_PORT 4431 #define PACKET_VERSION 1 #define PACKET_BUFFER_SIZE 16384 #define PACKET_SNDBUF_MAX 500 #define GG_PKTARG_MAX 60 #define GG_PKTDATA_SIZE_FACTOR 20 #define GG_PKTDATA_SIZE_ENCODE(pktsize, size, response) \ (pktsize = ((size / GG_PKTDATA_SIZE_FACTOR) & 0x7f) | (response << 7)) #define GG_PKTDATA_SIZE_DECODE(pktsize, size, response) { \ response = pktsize >> 7; size = (pktsize & 0x7f) * GG_PKTDATA_SIZE_FACTOR; \ } #define PACKET_HEADER_SIZE 2 #define PACKET_TYPE_MIN 0x00 #define PACKET_TYPE_MAX 0x12 enum gg_packet_type { /* u_int8_t */ PACKET_NEWCONN = 0x00, PACKET_DELCONN = 0x01, PACKET_DATA = 0x02, PACKET_NAME = 0x03, PACKET_FORK = 0x10, PACKET_EXEC = 0x11, PACKET_EXIT = 0x12, }; /* XXX is packed needed everywhere ? */ struct __attribute__((packed)) gg_packet { u_int8_t ver; u_int8_t type; union { struct __attribute__((packed)) newconn { u_int16_t id; u_int32_t src; u_int32_t dst; u_int8_t proto; u_int8_t size; } newconn; struct __attribute__((packed)) delconn { u_int16_t id; } delconn; struct __attribute__((packed)) data { u_int16_t connid; u_int8_t size; } data; struct __attribute__((packed)) name { u_int32_t addr; u_int8_t len; u_char fqdn[GG_PKTARG_MAX]; } name; struct __attribute__((packed)) fork { u_int32_t pid; u_int32_t ppid; u_int32_t cpid; u_int32_t tgid; } fork; struct __attribute__((packed)) exec { u_int32_t pid; u_int8_t cmdlen; u_char cmd[GG_PKTARG_MAX]; } exec; struct __attribute__((packed)) exit { u_int32_t pid; u_int32_t tgid; u_int8_t ecode; } exit; } pdat; #define newconn_id pdat.newconn.id #define newconn_src pdat.newconn.src #define newconn_dst pdat.newconn.dst #define newconn_proto pdat.newconn.proto #define newconn_size pdat.newconn.size #define delconn_id pdat.delconn.id #define data_connid pdat.data.connid #define data_size pdat.data.size #define name_addr pdat.name.addr #define name_len pdat.name.len #define name_fqdn pdat.name.fqdn #define fork_pid pdat.fork.pid #define fork_ppid pdat.fork.ppid #define fork_cpid pdat.fork.cpid #define fork_tgid pdat.fork.tgid #define exec_pid pdat.exec.pid #define exec_cmdlen pdat.exec.cmdlen #define exec_cmd pdat.exec.cmd #define exit_pid pdat.exit.pid #define exit_tgid pdat.exit.tgid #define exit_ecode pdat.exit.ecode }; typedef struct gg_packet_props_t { int size; } gg_packet_props_t; extern gg_packet_props_t gg_packet_props[]; struct gg_user { LIST_ENTRY(gg_user) entry; int id; int sock; struct sockaddr_in addr; struct sendbuf *sbuf; }; struct gg_server { struct event_base *ev_base; const char *ip; int port; struct sockaddr_in addr; struct event *ev; int sock; int (*handle_conn)(struct gg_server *, struct gg_user *); int (*handle_packet)(struct gg_server *, struct gg_user *, struct gg_packet *); void *usrdata; LIST_HEAD(, gg_user) user_list; int user_count; int user_id_count; }; enum client_status { GG_CLIENT_STATUS_CONNECTING = 0, GG_CLIENT_STATUS_CONNECTED = 1 }; struct gg_client { struct event_base *ev_base; const char *ip; int port; struct sockaddr_in addr; struct event *ev; struct event *ev_timer; int sock; enum client_status status; int (*handle_conn)(struct gg_client *); int (*handle_packet)(struct gg_client *, struct gg_packet *); void *usrdata; struct sendbuf *sbuf; }; struct gg_server *gg_server_start(struct event_base *, char *, int, int (*handle_conn)(struct gg_server *, struct gg_user *), int (*handle_packet)(struct gg_server *, struct gg_user *, struct gg_packet *), void *); void gg_server_stop(struct gg_server *); int gg_server_send(struct gg_server *, struct gg_packet *, struct gg_user *); void gg_server_send_flush(struct gg_server *, struct gg_user *); struct gg_client *gg_client_connect(struct event_base *, char *, int, int (*handle_conn)(struct gg_client *), int (*handle_packet)(struct gg_client *, struct gg_packet *), void *); void gg_client_disconnect(struct gg_client *); int gg_client_send(struct gg_client *, struct gg_packet *); void gg_client_send_flush(struct gg_client *); int gg_verbosity_get(void); void gg_verbosity_set(int); /* utils.c */ #define GGLOG_FORCED -2 #define GGLOG_FATAL -1 #define GGLOG_WARN 0 #define GGLOG_INFO 1 #define GGLOG_DEBUG 2 int gg_log_init(char *, int); void gg_log_shutdown(void); void gg_log_tmp(const char *, ...); void gg_log_debug(const char *, ...); void gg_log_info(const char *, ...); void gg_log_warn(const char *, ...); #if defined(__OpenBSD__) void __dead gg_log_fatal(const char *, ...); #else void gg_log_fatal(const char *, ...); #endif void *xmalloc(size_t); void *xcalloc(size_t, size_t); void fd_nonblock(int); void addrcpy(struct sockaddr_in *, struct sockaddr_in *); int addrcmp(struct sockaddr_in *, struct sockaddr_in *); void droppriv(char *, int, char *); #endif /* _LIBGLOUGLOU_H_ */