/*
* Copyright (c) 2002, 2003, 2004 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _HONEYD_H_
#define _HONEYD_H_
#define PIDFILE "/var/run/honeyd.pid"
#define TCP_DEFAULT_SIZE 512
#define TCP_MAX_SIZE 4096
#define TCP_MAX_SEND 512
#define HONEYD_MTU 1500
#define HONEYD_MAX_INTERFACES 8
#define HONEYD_MAX_CONNECTS 32000
#define HONEYD_CLOSE_WAIT 60
#define HONEYD_SYN_WAIT 60
#define HONEYD_IDLE_TIMEOUT 300
#define HONEYD_DFL_TTL 64
#define HONEYD_UDP_WAIT 60
#define HONEYD_MAX_SOFTERRS 3 /* Softerrors to state free*/
#define HONEYD_POLL_INTERVAL {0, 10000}
#define HONEYD_ADDR_MASK 0xFFFFFF00 /* for ICMP address mask replies */
struct config {
char *config; /* Name of configuration file */
char *pers;
char *xprobe;
char *assoc;
char *osfp;
};
struct count;
struct stats_network {
struct count *input_bytes;
struct count *output_bytes;
};
struct spoof {
struct addr new_src; /* where the reply should appear to come from */
struct addr new_dst; /* where the reply should go */
};
extern struct spoof no_spoof;
struct delay {
struct event timeout;
struct addr src;
struct addr dst;
struct template *tmpl;
struct ip_hdr *ip;
u_int iplen;
struct spoof spoof;
int flags;
};
#define DELAY_NEEDFREE 0x0001
#define DELAY_EXTERNAL 0x0002
#define DELAY_FREEPKT 0x0004
#define DELAY_TUNNEL 0x0008
#define DELAY_UNREACH 0x0010
#define DELAY_ETHERNET 0x0020 /* packet needs to be sent via ethernet */
enum status {PORT_OPEN = 0, PORT_PROXY, PORT_BLOCK, PORT_RESET,
PORT_SUBSYSTEM, PORT_PYTHON, PORT_RESERVED
};
enum forward {FW_DROP = 0, FW_INTERNAL, FW_EXTERNAL};
#define PORT_ISOPEN(x) ((x)->status == PORT_OPEN || \
(x)->status == PORT_PROXY || \
(x)->status == PORT_SUBSYSTEM || \
(x)->status == PORT_PYTHON)
struct interface;
struct subsystem;
struct action {
char *action;
void *action_extend;
struct addrinfo *aitop;
enum status status;
int flags;
};
#define PORT_TARPIT 0x01
struct port_encapsulate;
struct port {
SPLAY_ENTRY(port) node;
TAILQ_ENTRY(port) next;
TAILQ_HEAD(pendingq, port_encapsulate) pending;
int proto;
u_short number;
struct action action;
/* Subsystem related information */
struct subsystem *sub;
struct template *subtmpl;
int sub_fd;
int sub_islisten;
struct port **sub_conport;
};
SPLAY_HEAD(porttree, port);
/* Contains information common to both UDP and TCP connections */
struct tuple {
SPLAY_ENTRY(tuple) node;
TAILQ_ENTRY(tuple) next;
ip_addr_t ip_src;
ip_addr_t ip_dst;
uint16_t sport;
uint16_t dport;
int type; /* Eiter SOCK_STREAM or SOCK_DGRAM */
/* Statistics */
uint32_t received;
uint32_t sent;
struct event timeout;
int local; /* locally initiated */
/* Potentially pending connection to subsystem */
struct port_encapsulate *pending;
};
SPLAY_HEAD(tree, tuple);
TAILQ_HEAD(conlru, tuple);
struct command {
pid_t pid;
int pfd;
int perrfd;
struct event pread;
struct event pwrite;
struct event peread;
uint8_t fdconnected:1,
fdwantclose:1,
fdgotfin:1, /* if data still buffered delay shutdown */
unused:5;
void *state; /* Currently used only for Python */
};
/*
* For subsystems, we need to be able to schedule a callback that hands
* the subsytem a file descriptor to the new connection. However, Honeyd
* may not block on this as this might lead to dead lock with the
* subsystem. Intead, we encapsulate all the necessary information and
* hope that the underlying data does not go away. XXX: that's a bug.
*/
struct port_encapsulate {
TAILQ_ENTRY(port_encapsulate) next;
struct tuple *hdr;
struct command *cmd;
struct port *port;
void *con;
struct event ev;
};
/* State about TCP connections */
struct tcp_con {
/* Has to be the first member of the structure */
struct tuple conhdr;
#define con_ipsrc conhdr.ip_src
#define con_ipdst conhdr.ip_dst
#define con_sport conhdr.sport
#define con_dport conhdr.dport
uint8_t dupacks;
uint32_t snd_una;
uint32_t rcv_next;
uint32_t last_acked;
struct template *tmpl;
uint8_t rcv_flags;
struct command cmd;
#define cmd_pfd cmd.pfd
#define cmd_perrfd cmd.perrfd
u_char *payload;
u_int psize;
u_int plen; /* date in buffer */
u_int poff; /* current send offset */
u_char *readbuf;
u_int rsize;
u_int rlen;
uint8_t state;
uint8_t sentfin:1,
finacked:1,
sawwscale:1,
sawtimestamp:1,
unused:4;
u_short mss;
u_short window;
uint32_t echotimestamp;
u_short retrans_time;
struct event retrans_timeout;
struct port *port; /* used if bound to sub system */
uint16_t flags; /* Currently used for tarpitting */
};
#define TCP_TARPIT 0x01
#define MAX_UDP_BUFFERS 10
struct conbuffer {
TAILQ_ENTRY(conbuffer) next;
u_char *buf;
size_t len;
};
struct udp_con {
/* Has to be the first member of the structure */
struct tuple conhdr;
struct template *tmpl;
struct command cmd;
TAILQ_HEAD(bufferq, conbuffer) incoming;
int nincoming;
int softerrors; /* ICMP unreachables for this state */
struct port *port;
};
struct callback {
void (*cb_read)(int, short, void *);
void (*cb_write)(int, short, void *);
void (*cb_eread)(int, short, void *);
void (*cb_connect)(int, short, void *);
};
/* YM
* Timestamp message data
*/
struct icmp_msg_timestamp { /* dnet.h define this but the size is wrong */
/* So define ours */
struct icmp_hdr hdr; /* ICMP header */
uint16_t icmp_id; /* identifier */
uint16_t icmp_seq; /* sequence number */
uint32_t icmp_ts_orig; /* originate timestamp */
uint32_t icmp_ts_rx; /* receive timestamp */
uint32_t icmp_ts_tx; /* transmit timestamp */
};
/* YM
* Address mask message data, RFC 950
*/
struct icmp_mesg_mask { /* Our definition */
struct icmp_hdr hdr; /* ICMP header */
uint16_t icmp_id; /* identifier */
uint16_t icmp_seq; /* sequence number */
uint32_t icmp_mask; /* address mask */
};
/* YM
* Information Reply message data, RFC 792
*/
struct icmp_msg_inforeply { /* Our definition */
struct icmp_hdr hdr; /* ICMP header */
struct icmp_msg_idseq idseq; /* ID_SEQ */
};
#define TCP_BYTESINFLIGHT(x) (x)->poff
#define TCP_MAX_INFLIGHT 4096
/* Iterate over all active connections */
int tuple_iterate(struct conlru *, int (*f)(struct tuple *, void *), void *);
struct tuple *tuple_find(struct tree *, struct tuple *);
void honeyd_ip_send(u_char *, u_int, struct spoof spoof);
void honeyd_dispatch(struct template *, struct ip_hdr *, u_short);
char *honeyd_contoa(const struct tuple *);
void honeyd_input(const struct interface *, struct ip_hdr *, u_short);
/* Command prototypes for services */
void cmd_droppriv(uid_t, gid_t);
void cmd_ready_fd(struct command *, struct callback *, void *);
void cmd_trigger_read(struct command *, int);
void cmd_trigger_write(struct command *, int);
void cmd_free(struct command *);
int cmd_fork(struct tuple *, struct command *, struct template *,
char *, char **, void *);
int cmd_python(struct tuple *, struct command *, void *);
int cmd_subsystem(struct template *, struct subsystem *, char *, char **);
struct addrinfo;
struct addrinfo *cmd_proxy_getinfo(char *, int, short);
int cmd_proxy_connect(struct tuple *, struct command *, struct addrinfo *,
void *);
int cmd_subsystem_schedule_connect(struct tuple *hdr, struct command *cmd,
struct port *, void *arg);
int cmd_subsystem_connect(struct tuple *hdr, struct command *cmd,
struct port *, void *arg);
int cmd_subsystem_localconnect(struct tuple *hdr, struct command *cmd,
struct port *, void *arg);
/* Network connection elements */
struct tcp_con *tcp_new(struct ip_hdr *, struct tcp_hdr *, int);
struct udp_con *udp_new(struct ip_hdr *, struct udp_hdr *, int);
int tcp_setupconnect(struct tcp_con *);
void tcp_connectfail(struct tcp_con *con);
void generic_timeout(struct event *, int);
/* Network protocol related prototypes */
int conhdr_compare(struct tuple *, struct tuple *);
void tcp_free(struct tcp_con *);
int tcp_send(struct tcp_con *, uint8_t, u_char *, u_int);
void tcp_senddata(struct tcp_con *, uint8_t);
void tcp_sendfin(struct tcp_con *);
void udp_free(struct udp_con *);
int udp_send(struct udp_con *con, u_char *payload, u_int len);
void config_init(void);
void config_read(char *);
struct port *port_insert(struct template *, int, int, struct action *);
struct port *port_random(struct template *, int, struct action *, int, int);
struct port *port_find(struct template *, int, int);
void port_free(struct template *, struct port *);
void port_encapsulation_free(struct port_encapsulate *);
void icmp_echo_reply(struct template *, struct ip_hdr *, uint8_t,
uint8_t, uint16_t, uint8_t, u_char *, u_int, struct spoof spoof);
void change_quote_header(struct ip_hdr *, uint16_t,
uint16_t, uint16_t, uint16_t, uint16_t);
void icmp_unreachable_reply(struct ip_hdr *rip, uint8_t ttl, uint8_t tos,
uint16_t df, uint16_t riplen, struct spoof spoof);
void icmp_mask_reply(struct template *, struct ip_hdr *,
struct icmp_msg_idseq *, uint8_t, uint32_t, struct spoof spoof);
void icmp_info_reply(struct template *, struct ip_hdr *,
struct icmp_msg_idseq *, uint8_t, struct spoof spoof);
void icmp_timestamp_reply(struct template *, struct ip_hdr *,
struct icmp_msg_timestamp *, uint8_t, struct spoof spoof);
void honeyd_use_uid(uid_t);
void honeyd_use_gid(gid_t);
#endif
syntax highlighted by Code2HTML, v. 0.9.1