diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/hippie.h linux-2.6.27.8-hippie/include/linux/hippie.h --- linux-2.6.27.8/include/linux/hippie.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/hippie.h 2008-01-25 15:21:53.000000000 -0600 @@ -0,0 +1,122 @@ +/* + * Hi-Performance Protocol Identification Engine Base Structures - hippie.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#ifndef __hippie_h +#define __hippie_h +//#include +//#include +#include +#include +#include +#include + +//#include + +/* pie_sess_sig_data - Structure containing a signatures extra data on a session */ +/* If the dataid < 100 then the value is a number, while if >= 100, it's a pointer that needs to be cleaned upon session termination */ +struct pie_sess_sig_data { + struct pie_sess_sig_data *next; + struct pie_sess_sig_data *prev; + u_int16_t sigcode; + u_int16_t dataid; + void *value; +}; + +struct pie_protocol_hdr { + u_int16_t protoindex; + void *proto_info; + u_int8_t *header; + u_int16_t hlen; + u_int8_t *data; + u_int16_t datalen; + struct pie_protocol_hdr *next_hdr; +}; + +struct pie_protocol_sess { + u_int16_t protoindex; + void *proto_info; + struct pie_protocol_sess *next_sess; +}; + +/* pie_sess_info struct - Structure containing each session in the state table. */ +struct pie_sess_info { + /* Don't change any of these unless you are prepared to have some huge problems */ + atomic_t packets; + atomic_t bytes; + /* Information about the protocol doing Network (IPv4,IPv6) */ + struct pie_protocol_sess *network_sess; + /* Information about the protocol doing Transport (ICMP,TCP,UDP,etc) */ + struct pie_protocol_sess *transport_sess; + /* Session Headers */ + struct pie_protocol_sess *first_sess; + struct pie_protocol_sess *last_sess; + /* Session structures */ + struct hrtimer timeout; + atomic_t state; + u_int8_t caninspect; + u_int8_t persist; + struct pie_sess_info *next; + struct pie_sess_info *prev; + /*struct pie_sess_info *prev; - Was causing issues to do doubly linked */ + rwlock_t *lock; + u_int32_t sessid; + void *bucket; + struct pie_sess_sig_data *sigdata; +}; + +/* pie_sess_hdr struct - Structure that contains the lock for each bucket and it's sessions */ +struct pie_sess_hdr { + rwlock_t lock; + u_int16_t bucketid; + struct pie_sess_info *sessions; + atomic_t sesscount; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc; + char *procbuffer; + u_int32_t procbuffersize; +#endif +}; + +struct pie_packet_info { + u_int8_t *rawpacket; + u_int16_t plen; + /* Information about the protocol doing Network (IPv4,IPv6) */ + struct pie_protocol_hdr *network_hdr; + /* Information about the protocol doing Transport (ICMP,TCP,UDP,etc) */ + struct pie_protocol_hdr *transport_hdr; + struct pie_protocol_hdr *first_hdr; + struct pie_protocol_hdr *last_hdr; + struct pie_sess_info *session; + u_int8_t direction; +}; + +extern atomic_t pie_packet_count; +extern atomic_t pie_byte_count; +extern atomic_t pie_inspect_count; + +struct sk_buff; + +struct pie_sess_info *pie_packet_read(u_int8_t *packet,u_int32_t len); +int pie_packet_read_skb(struct sk_buff *skb); + +int pie_packet_inspect(u_int8_t *packet, u_int32_t len, u_int16_t protoid); +int pie_packet_checkencap(u_int8_t *packet, u_int32_t len, u_int16_t protoid); +int pie_packet_multiinspect(u_int8_t *packet, u_int32_t len, u_int8_t *names); +int pie_skb_inspect(const struct sk_buff *skb, u_int16_t protoid); +int pie_skb_checkencap(const struct sk_buff *skb, u_int16_t protoid); +int pie_skb_multiinspect(const struct sk_buff *skb, u_int8_t *names); + +u_int8_t *pie_payload_search(u_int8_t *start, u_int8_t *end, u_int8_t *pattern, u_int16_t datalen); +struct pie_packet_info *pie_packet_mockup(u_int8_t *packet, u_int32_t len); +struct pie_protocol_hdr *pie_packet_protocheck(u_int16_t curproto, struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr, u_int8_t inspopt); +void pie_packet_cleanup(struct pie_packet_info *packet); +u_int16_t make_int16(u_int8_t *from); +u_int16_t make_int16_le(u_int8_t *from); +u_int32_t make_int32(u_int8_t *from); +u_int32_t make_int32_le(u_int8_t *from); +#endif diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/netdevice.h linux-2.6.27.8-hippie/include/linux/netdevice.h --- linux-2.6.27.8/include/linux/netdevice.h 2008-12-05 14:03:02.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/netdevice.h 2008-12-06 21:06:00.000000000 -0600 @@ -735,6 +735,10 @@ /* GARP */ struct garp_port *garp_port; +#ifdef CONFIG_HIPPIE_INTERFACES + u_int8_t hippie_read; +#endif + /* class/net/name entry */ struct device dev; /* space for optional statistics and wireless sysfs groups */ diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/netfilter/xt_hippie.h linux-2.6.27.8-hippie/include/linux/netfilter/xt_hippie.h --- linux-2.6.27.8/include/linux/netfilter/xt_hippie.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/netfilter/xt_hippie.h 2007-05-30 10:42:44.000000000 -0500 @@ -0,0 +1,27 @@ +/* + * Hi-Performance Protocol Identification Engine Netfilter Plugin Headers - xt_hippie.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#ifndef _XT_HIPPIE_H +#define _XT_HIPPIE_H + +#define HIPPIE_MODULE_MAXNAMELEN 512 + +#define NF_HIPPIE_PROTO 0 +#define NF_HIPPIE_ENCAP 1 +#define NF_HIPPIE_MPROTO 2 + +struct xt_hippie_info +{ + u_int8_t opcode; + char name[HIPPIE_MODULE_MAXNAMELEN]; + /*u_int16_t sigcode;*/ + u_int8_t invert; +}; + +#endif /*_XT_HIPPIE_H*/ + diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_hostinfo.h linux-2.6.27.8-hippie/include/linux/pie_hostinfo.h --- linux-2.6.27.8/include/linux/pie_hostinfo.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_hostinfo.h 2008-01-25 14:33:44.000000000 -0600 @@ -0,0 +1,49 @@ +/* + * Hi-Performance Protocol Identification Engine Host Information DB Structures - pie_hostinfo.h + * Copyright 2004-2007, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +struct pie_hostinfo_item { + u_int32_t addr; + u_int16_t proto; + u_int16_t field; + u_int8_t type; + u_int8_t byte; + u_int32_t number; + void *pointer; + struct pie_hostinfo_item *next; + struct pie_hostinfo_bucket *bucket; + //struct timer_list timeout; + struct hrtimer timeout; +}; + +struct pie_hostinfo_bucket { + struct pie_hostinfo_item *list; + atomic_t size; + rwlock_t lock; +}; + +extern struct pie_hostinfo_bucket **pie_hostinfo_hash; + +int pie_hostinfo_init(void); +u_int32_t pie_hostinfo_get_num(u_int32_t addr, u_int16_t proto, u_int16_t field); +u_int8_t pie_hostinfo_get_byte(u_int32_t addr, u_int16_t proto, u_int16_t field); +void *pie_hostinfo_get_pointer(u_int32_t addr, u_int16_t proto, u_int16_t field); +void pie_hostinfo_set_num(u_int32_t addr, u_int16_t proto, u_int16_t field, u_int32_t val, u_int16_t timeout); +void pie_hostinfo_set_byte(u_int32_t addr, u_int16_t proto, u_int16_t field, u_int8_t val, u_int16_t timeout); +void pie_hostinfo_set_pointer(u_int32_t addr, u_int16_t proto, u_int16_t field, void *val, u_int16_t timeout); +struct pie_hostinfo_item *pie_hostinfo_new(u_int32_t addr, u_int16_t proto, u_int16_t field, u_int8_t type, u_int16_t timeout); +enum hrtimer_restart pie_hostinfo_cleanup(struct hrtimer *timer); +#ifdef CONFIG_PROC_FS +int pie_hostinfo_print_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +int pie_hostinfo_print_proc_detail(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +#endif + +#define PIE_HOSTINFO_EMPTY 0 +#define PIE_HOSTINFO_BYTE 1 +#define PIE_HOSTINFO_NUM 2 +#define PIE_HOSTINFO_POINTER 3 + diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_interface.h linux-2.6.27.8-hippie/include/linux/pie_interface.h --- linux-2.6.27.8/include/linux/pie_interface.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_interface.h 2008-01-25 14:33:44.000000000 -0600 @@ -0,0 +1,29 @@ +/* + * Hi-Performance Protocol Identification Engine Network Interface Headers - pie_interface.h + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +struct pie_interface { + struct net_device *device; + struct pie_interface *next_int; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc; +#endif +}; + +extern struct pie_interface *pie_interfaces; +extern struct proc_dir_entry *proc_net_hippie_interfaces; + +extern int pie_interface_notifier(struct notifier_block *unused, unsigned long event, void *ptr); +extern int pie_interface_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +extern int pie_interface_proc_write(struct file *file, const char *buffer, unsigned long count, void *data); +u_int8_t pie_interfaces_init(void); +extern int pie_interface_up(struct net_device *dev); +extern int pie_interface_down(struct net_device *dev); +extern struct pie_interface *pie_add_interface(struct net_device *dev); +extern void pie_rem_interface(struct net_device *dev); +extern int pie_int_packet_read(struct net_device *dev, u_int8_t *packet, u_int32_t len); +extern int pie_int_packet_read_skb(struct net_device *dev, struct sk_buff *skb); diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_prediction.h linux-2.6.27.8-hippie/include/linux/pie_prediction.h --- linux-2.6.27.8/include/linux/pie_prediction.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_prediction.h 2008-01-25 14:33:44.000000000 -0600 @@ -0,0 +1,24 @@ +/* + * Hi-Performance Protocol Identification Engine Session Prediction Headers - pie_prediction.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +struct pie_sess_info *pie_use_prediction(struct pie_packet_info *packet, struct pie_sess_info *predsess); + +struct pie_sess_info *pie_prediction_create(void); +struct pie_protocol_sess *pie_prediction_add_header(struct pie_sess_info *sess, u_int16_t protocol); +u_int8_t pie_prediction_parameter(struct pie_protocol_sess *header, char *name, u_int8_t dtype, void *data); +u_int8_t pie_prediction_schedule(struct pie_sess_info *sess); + +int pie_prediction_init(void); + +extern struct pie_sess_hdr pie_prediction_table; +extern atomic_t pie_predict_add; +extern atomic_t pie_predict_used; + +#define PIE_DTYPE_NUM 0 +#define PIE_DTYPE_CHAR 1 +#define PIE_DTYPE_POINTER 2 diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_proc.h linux-2.6.27.8-hippie/include/linux/pie_proc.h --- linux-2.6.27.8/include/linux/pie_proc.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_proc.h 2008-12-06 21:00:12.000000000 -0600 @@ -0,0 +1,31 @@ +/* + * Hi-Performance Protocol Identification Engine Proc Filesystem Headers - pie_proc.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#ifdef CONFIG_PROC_FS +/* /proc/net/hippie */ +extern struct proc_dir_entry *proc_net_hippie; +extern struct proc_dir_entry *proc_net_hippie_proto; +extern struct proc_dir_entry *proc_net_hippie_sessions; +extern struct proc_dir_entry *proc_net_hippie_sessions_buckets; +extern struct proc_dir_entry *proc_net_hippie_sessions_all; +extern struct proc_dir_entry *proc_net_hippie_protocols; +extern struct proc_dir_entry *proc_net_hippie_stat; +extern struct proc_dir_entry *proc_net_hippie_sessions_predictions; +extern struct proc_dir_entry *proc_net_hippie_sessions_buckets_stat; + +int pie_proc_print_sessions(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +int pie_proc_print_proto_stats(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +int pie_proc_print_protocols(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +int pie_proc_print_stat(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +int pie_proc_stat_reset(struct file *file, const char *buffer, unsigned long count, void *data); +int pie_proc_print_predictions(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +int pie_proc_print_session_bucket(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +int pie_proc_print_bucket_stats(char *buffer, char **start, off_t offset, int length, int *eof, void *data); + +int pie_proc_init(void); +#endif diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_proto_icmp.h linux-2.6.27.8-hippie/include/linux/pie_proto_icmp.h --- linux-2.6.27.8/include/linux/pie_proto_icmp.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_proto_icmp.h 2008-01-15 16:37:37.000000000 -0600 @@ -0,0 +1,34 @@ +/* + * Hi-Performance Protocol Identification Engine ICMP Protocol Handling Headers - pie_proto_icmp.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include + +#define PIE_STATE_ICMP 100 + +#define PIE_STATE_TIMEOUT_ICMP 30 + +struct pie_protohdr_icmp { + u_int8_t type; + u_int8_t code; + u_int16_t chksum; + u_int16_t ident; + u_int16_t sequence; +}; + +struct pie_protosess_icmp { + u_int8_t type; +}; + +u_int8_t pie_icmp_get_sess_bucket(struct pie_protocol_hdr *, u_int8_t direction); +u_int8_t pie_icmp_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess, u_int8_t direction); +struct pie_protocol_sess *pie_icmp_new_session(struct pie_protocol_hdr *pkthdr); +int pie_icmp_proc_packet(struct pie_sess_info *sess, struct pie_protocol_hdr *pkthdr); +struct pie_protocol_hdr *pie_icmp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr); +int pie_icmp_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer); +void pie_icmp_session_cleanup(struct pie_protocol_sess *sess); +void pie_icmp_packet_cleanup(struct pie_protocol_hdr *hdr); diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_proto_ipv4.h linux-2.6.27.8-hippie/include/linux/pie_proto_ipv4.h --- linux-2.6.27.8/include/linux/pie_proto_ipv4.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_proto_ipv4.h 2006-07-18 20:51:57.000000000 -0500 @@ -0,0 +1,45 @@ +/* + * Hi-Performance Protocol Identification Engine IP Version 4 Protocol Handling Headers - pie_proto_ipv4.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +struct pie_protohdr_ipv4 { + /* Header Length = Number of 32-bit words in header, min 5 */ + u_int16_t hlen; + u_int8_t totlen; + /* Need fragmentation support */ + + u_int8_t ipflags; + /* Other stuff */ + u_int8_t ttl; + u_int8_t proto; + /* IP Addresses */ + u_int8_t srcip[4]; + u_int8_t dstip[4]; + /* Need Options Support */ +}; + +struct pie_protosess_ipv4 { + /* IP Addresses */ + u_int8_t srcip[4]; + u_int8_t dstip[4]; + u_int8_t proto; +}; + +u_int8_t pie_ipv4_get_sess_bucket(struct pie_protocol_hdr *, u_int8_t direction); +u_int8_t pie_ipv4_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *ipsess, u_int8_t direction); +struct pie_protocol_sess *pie_ipv4_new_session(struct pie_protocol_hdr *pkthdr); +int pie_ipv4_proc_packet(struct pie_sess_info *sess, struct pie_packet_info *pktinfo); +struct pie_protocol_hdr *pie_ipv4_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr); +int pie_ipv4_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer); +void pie_ipv4_session_cleanup(struct pie_protocol_sess *sess); +void pie_ipv4_packet_cleanup(struct pie_protocol_hdr *hdr); +struct pie_protocol_sess *pie_ipv4_create_predict(void); +u_int8_t pie_ipv4_add_predict_option(struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data); +u_int8_t pie_ipv4_validate_prediction(struct pie_protocol_sess *hdr); +u_int8_t pie_ipv4_convert_prediction(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess); + +char *pie_ipv4_addr_read(char *start, u_int8_t format, u_int8_t iparray[]); diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_proto_tcp.h linux-2.6.27.8-hippie/include/linux/pie_proto_tcp.h --- linux-2.6.27.8/include/linux/pie_proto_tcp.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_proto_tcp.h 2008-01-15 16:37:37.000000000 -0600 @@ -0,0 +1,53 @@ +/* + * Hi-Performance Protocol Identification Engine TCP Protocol Handling Headers - pie_proto_tcp.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include + +#define PIE_STATE_TCP_SYN 600 +#define PIE_STATE_TCP_SYNACK 601 +#define PIE_STATE_TCP_NORMAL 602 +#define PIE_STATE_TCP_FIN 603 +#define PIE_STATE_TCP_CLOSED 604 +#define PIE_STATE_TCP_UNKNOWN 605 + +#define PIE_STATE_TIMEOUT_TCP_SYN 30 +#define PIE_STATE_TIMEOUT_TCP_SYNACK 60 +#define PIE_STATE_TIMEOUT_TCP_NORMAL 300 +#define PIE_STATE_TIMEOUT_TCP_FIN 30 +#define PIE_STATE_TIMEOUT_TCP_CLOSED 30 +#define PIE_STATE_TIMEOUT_TCP_UNKNOWN 15 + +struct pie_protohdr_tcp { + u_int16_t sport; + u_int16_t dport; + u_int8_t hlen; + u_int8_t tcpflags; + //u_int8_t *data; + //u_int16_t datalen; +}; + +struct pie_protosess_tcp { + u_int16_t sport; + u_int16_t dport; +}; + +//int pie_tcp_predict(u_int16_t sigcode, u_int8_t *dstip, u_int16_t dport, u_int8_t *srcip, u_int16_t sport); + +u_int8_t pie_tcp_get_sess_bucket(struct pie_protocol_hdr *, u_int8_t direction); +u_int8_t pie_tcp_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *ipsess, u_int8_t direction); +struct pie_protocol_sess *pie_tcp_new_session(struct pie_protocol_hdr *pkthdr); +int pie_tcp_proc_packet(struct pie_sess_info *sess, struct pie_protocol_hdr *pkthdr); +struct pie_protocol_hdr *pie_tcp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr); +int pie_tcp_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer); +void pie_tcp_session_cleanup(struct pie_protocol_sess *sess); +void pie_tcp_packet_cleanup(struct pie_protocol_hdr *hdr); +struct pie_protocol_sess *pie_tcp_create_predict(void); +u_int8_t pie_tcp_add_predict_option(struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data); +u_int8_t pie_tcp_validate_prediction(struct pie_protocol_sess *hdr); +u_int8_t pie_tcp_convert_prediction(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess); + diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_proto_udp.h linux-2.6.27.8-hippie/include/linux/pie_proto_udp.h --- linux-2.6.27.8/include/linux/pie_proto_udp.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_proto_udp.h 2008-01-15 16:37:37.000000000 -0600 @@ -0,0 +1,34 @@ +/* + * Hi-Performance Protocol Identification Engine UDP Protocol Handling Headers - pie_proto_udp.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include + +#define PIE_STATE_UDP_UNANS 1700 +#define PIE_STATE_UDP_BIDIR 1701 + +#define PIE_STATE_TIMEOUT_UDP_UNANS 20 +#define PIE_STATE_TIMEOUT_UDP_BIDIR 60 + +struct pie_protohdr_udp { + u_int16_t sport; + u_int16_t dport; +}; + +struct pie_protosess_udp { + u_int16_t sport; + u_int16_t dport; +}; + +u_int8_t pie_udp_get_sess_bucket(struct pie_protocol_hdr *, u_int8_t direction); +u_int8_t pie_udp_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess, u_int8_t direction); +struct pie_protocol_sess *pie_udp_new_session(struct pie_protocol_hdr *pkthdr); +int pie_udp_proc_packet(struct pie_sess_info *sess, struct pie_protocol_hdr *pkthdr); +struct pie_protocol_hdr *pie_udp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr); +int pie_udp_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer); +void pie_udp_session_cleanup(struct pie_protocol_sess *sess); +void pie_udp_packet_cleanup(struct pie_protocol_hdr *hdr); diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_protocol.h linux-2.6.27.8-hippie/include/linux/pie_protocol.h --- linux-2.6.27.8/include/linux/pie_protocol.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_protocol.h 2007-09-20 09:28:09.000000000 -0500 @@ -0,0 +1,106 @@ +/* + * Hi-Performance Protocol Identification Engine Protocol Capsule Handling Headers - pie_protocol.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#define PIE_PROTOTYPE_LINK 2 +#define PIE_PROTOTYPE_NETWORK 3 +#define PIE_PROTOTYPE_TRANSPORT 4 +#define PIE_PROTOTYPE_ENCAP 5 +#define PIE_PROTOTYPE_APP 7 + +#define PIE_PROTO_MAX_NAMELEN 50 +#define PIE_PROTO_MAXCOUNT 256 + +#define PIE_ENCAP_NONE 0 +#define PIE_ENCAP_UNTAGGED 1 +#define PIE_ENCAP_TAGGED 2 +#define PIE_ENCAP_MULTIPLEX 3 + +#define PIE_PROTO_ACTIVE 1 +#define PIE_PROTO_INACTIVE 0 + +typedef int pie_protocheck_func(struct pie_packet_info *, struct pie_protocol_hdr *); +typedef void piepersistfunc(struct pie_sess_info *, struct pie_protocol_hdr *); + +struct pie_subprotocol_check { + u_int16_t protoindex; + pie_protocheck_func *check; + struct pie_subprotocol_check *next; +}; + +struct pie_persist_list { + piepersistfunc *func; + //u_int8_t proto; + struct pie_persist_list *next; +}; + +struct pie_protocol_list { + u_int16_t index; + struct pie_protocol_list *next; +}; + +struct pie_protocol { + u_int16_t fd; + char name[PIE_PROTO_MAX_NAMELEN]; + u_int8_t prototype; + u_int8_t encapsulation; + u_int8_t n_packets; + u_int8_t status; + struct pie_subprotocol_check *subchecks; + struct pie_protocol_list *parentlist; + struct pie_protocol_list *tunnel_types; + struct pie_persist_list *persist; + u_int8_t (*get_sess_bucket) (struct pie_protocol_hdr *, u_int8_t direction); + u_int8_t (*session_compare) (struct pie_protocol_hdr *,struct pie_protocol_sess *, u_int8_t direction); + struct pie_protocol_sess *(*new_session) (struct pie_protocol_hdr *); + struct pie_protocol_hdr *(*packet_mockup) (struct pie_packet_info *, struct pie_protocol_hdr *curhdr); + struct pie_protocol_sess *(*create_predict) (void); + u_int8_t (*add_predict_option) (struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data); + u_int8_t (*validate_prediction) (struct pie_protocol_sess *hdr); + u_int8_t (*convert_prediction) (struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess); + int (*proc_packet) (struct pie_sess_info *sess, struct pie_protocol_hdr *pkthdr); + int (*proc_print) (struct pie_sess_info *sess, struct pie_protocol_sess *, char *buffer); + void (*session_cleanup) (struct pie_protocol_sess *); + void (*packet_cleanup) (struct pie_protocol_hdr *); + atomic_t packets_ins; + atomic_t predicts; + atomic_t predicts_used; + /* Final Header is this protocol */ + atomic_t packets; + atomic_t conns; + atomic_t bytes; + /* Any header is this protocol */ + atomic_t all_packets; + atomic_t all_conns; + atomic_t all_bytes; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *procentry; +#endif + struct pie_protocol *next; +}; + +extern struct pie_protocol *pie_protocols[]; + +u_int16_t pie_reg_protocol(char *name, u_int8_t prototype, u_int8_t encap, u_int8_t npkt, + u_int8_t (*get_sess_bucket) (struct pie_protocol_hdr *, u_int8_t direction), + u_int8_t (*session_compare) (struct pie_protocol_hdr *, struct pie_protocol_sess *, u_int8_t direction), + struct pie_protocol_sess *(*new_session) (struct pie_protocol_hdr *), + struct pie_protocol_hdr *(*packet_mockup) (struct pie_packet_info *, struct pie_protocol_hdr *curhdr), + struct pie_protocol_sess *(*create_predict) (void), + u_int8_t (*add_predict_option) (struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data), + u_int8_t (*validate_prediction) (struct pie_protocol_sess *hdr), + u_int8_t (*convert_prediction) (struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess), + int (*proc_packet) (struct pie_sess_info *sess, struct pie_protocol_hdr *pkthdr), + int (*proc_print) (struct pie_sess_info *sess, struct pie_protocol_sess *, char *buffer), + void (*session_cleanup) (struct pie_protocol_sess *), + void (*packet_cleanup) (struct pie_protocol_hdr *)); +u_int16_t pie_unreg_protocol(char *name, u_int16_t fd); +int16_t pie_get_protocolid(char *name); +u_int16_t pie_reg_subprotocol(char *parentname, u_int16_t subprotoid, pie_protocheck_func *check); +u_int16_t pie_reg_tunnel_type(u_int16_t me, char *); +u_int16_t pie_reg_persist(/*char *parentname, */u_int16_t protoid, piepersistfunc *func); +int pie_protocols_init(void); diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/pie_sessions.h linux-2.6.27.8-hippie/include/linux/pie_sessions.h --- linux-2.6.27.8/include/linux/pie_sessions.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/pie_sessions.h 2008-02-06 11:45:18.000000000 -0600 @@ -0,0 +1,41 @@ +/* + * Hi-Performance Protocol Identification Engine Session Handling Headers - pie_sessions.h + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#define PIE_STATE_NEW 0 +#define PIE_STATE_UNANS 1 +#define PIE_STATE_BIDIR 2 +#define PIE_STATE_PREDICTED 3 +#define PIE_STATE_EXTERNAL_TERM 4 + +#define PIE_STATE_TIMEOUT_NEW 60 +#define PIE_STATE_TIMEOUT_UNANS 30 +#define PIE_STATE_TIMEOUT_BIDIR 60 +#define PIE_STATE_TIMEOUT_PREDICTED 30 +#define PIE_STATE_TIMEOUT_UNKNOWN 15 +#define PIE_STATE_TIMEOUT_EXTERNAL_TERM 15 + +extern struct pie_sess_hdr **pie_session_table; +extern atomic_t pie_session_count; +extern atomic_t pie_session_countactive; + +int pie_sessions_init(void); +struct pie_sess_info *pie_session_find(struct pie_packet_info *packet); + +void pie_session_timeout_cancel(struct pie_sess_info *sess); +void pie_session_timeout_init(struct pie_sess_info *sess); +void pie_session_timeout_reset(struct pie_sess_info *sess,u_int16_t timeout); +enum hrtimer_restart pie_session_timeout(struct hrtimer *timer); + +void *pie_session_get_value(struct pie_sess_info *sess, u_int16_t sigcode, u_int16_t dataid); +int pie_session_set_value(struct pie_sess_info *sess, u_int16_t sigcode, u_int16_t dataid, void *value); + +struct pie_sess_info *pie_create_session(struct pie_packet_info *packet); +struct pie_protocol_sess *pie_session_create_subsession(struct pie_sess_info *sess, struct pie_protocol_hdr *curhdr); + +int pie_session_print(char *buffer,struct pie_sess_info *sess); +void pie_free_session_header(struct pie_protocol_sess *sess); diff -Nru -X excludes.txt linux-2.6.27.8/include/linux/skbuff.h linux-2.6.27.8-hippie/include/linux/skbuff.h --- linux-2.6.27.8/include/linux/skbuff.h 2008-12-05 14:03:02.000000000 -0600 +++ linux-2.6.27.8-hippie/include/linux/skbuff.h 2008-12-06 21:06:00.000000000 -0600 @@ -28,6 +28,10 @@ #include #include #include +#ifdef CONFIG_HIPPIE +#include +#endif + #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ @@ -305,6 +309,10 @@ #ifdef CONFIG_BRIDGE_NETFILTER struct nf_bridge_info *nf_bridge; #endif +#ifdef CONFIG_HIPPIE + struct pie_sess_info *hippie_sess; +#endif + int iif; __u16 queue_mapping; diff -Nru -X excludes.txt linux-2.6.27.8/net/Kconfig linux-2.6.27.8-hippie/net/Kconfig --- linux-2.6.27.8/net/Kconfig 2008-12-05 14:03:02.000000000 -0600 +++ linux-2.6.27.8-hippie/net/Kconfig 2008-12-06 21:06:00.000000000 -0600 @@ -174,6 +174,20 @@ endif +config HIPPIE + bool "Hi-Performance Protocol Identification Engine (HiPPIE)" + ---help--- + The Hi-Performance Protocl Identification Engine is a packet filtering + signature engine that ties into Netfilter to add the ability to filter + and classify packets more effectively at 'layer 7' and add some + capabilities to netfilters classification capabilities. + +if HIPPIE + +source "net/hippie/Kconfig" + +endif + source "net/dccp/Kconfig" source "net/sctp/Kconfig" source "net/tipc/Kconfig" diff -Nru -X excludes.txt linux-2.6.27.8/net/Makefile linux-2.6.27.8-hippie/net/Makefile --- linux-2.6.27.8/net/Makefile 2008-12-05 14:03:02.000000000 -0600 +++ linux-2.6.27.8-hippie/net/Makefile 2008-12-06 21:06:00.000000000 -0600 @@ -16,6 +16,7 @@ obj-$(CONFIG_LLC) += llc/ obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/ obj-$(CONFIG_NETFILTER) += netfilter/ +obj-$(CONFIG_HIPPIE) += hippie/ obj-$(CONFIG_INET) += ipv4/ obj-$(CONFIG_XFRM) += xfrm/ obj-$(CONFIG_UNIX) += unix/ diff -Nru -X excludes.txt linux-2.6.27.8/net/core/dev.c linux-2.6.27.8-hippie/net/core/dev.c --- linux-2.6.27.8/net/core/dev.c 2008-12-05 14:03:02.000000000 -0600 +++ linux-2.6.27.8-hippie/net/core/dev.c 2008-12-06 21:06:00.000000000 -0600 @@ -128,6 +128,10 @@ #include #include +#ifdef CONFIG_HIPPIE_INTERFACES +#include +#endif + #include "net-sysfs.h" /* @@ -1761,6 +1765,13 @@ struct Qdisc *q; int rc = -ENOMEM; +#ifdef CONFIG_HIPPIE_INTERFACES + /* Feed packets coming in interfaces to HiPPIE for analysis */ + if (dev->hippie_read > 1) { + pie_int_packet_read_skb(dev,skb); + } +#endif + /* GSO will handle the following emulations directly. */ if (netif_needs_gso(dev, skb)) goto gso; @@ -2243,6 +2254,13 @@ ncls: #endif +#ifdef CONFIG_HIPPIE_INTERFACES + /* Feed packets coming in interfaces to HiPPIE for analysis */ + if (orig_dev->hippie_read > 0) { + pie_int_packet_read_skb(orig_dev,skb); + } +#endif + skb = handle_bridge(skb, &pt_prev, &ret, orig_dev); if (!skb) goto out; diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/Kconfig linux-2.6.27.8-hippie/net/hippie/Kconfig --- linux-2.6.27.8/net/hippie/Kconfig 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/Kconfig 2008-02-04 11:02:20.000000000 -0600 @@ -0,0 +1,318 @@ +config HIPPIE_PERSISTANCE + bool "Enable Connection Persistance" + depends on HIPPIE + ---help--- + This will enable the ability for certain protocols to enable further + inspection beyond initial classification. This ability enables protocols + such as FTP and IRC to track the external connections related to them + for data transfers and IRC-DCC. If unsure, choose Y. + +config HIPPIE_PREDICTION + bool "Enable Connection Prediction" + depends on HIPPIE + ---help--- + This wil enable HiPPIE protocol signatures to be able to predict oncoming sessions, + such as in FTP and IRC connections which open external connections. To get the + fullest use out of this feature, one should also enable Connection Persistance. + If unsure, choose Y. + +config HIPPIE_INTERFACES + bool "Enable device packet feed" + depends on HIPPIE + ---help--- + This will enable the feed of packets to HiPPIE directly from network devices. + To enable an interface to send packet to HiPPIE, you must enable it through proc + at /proc/net/hippie/interfaces/[name], setting it to 1 for regular, and 2 for + promiscuous mode. If you are unsure, say Y here. + +config HIPPIE_NETFILTER_FEED + bool "Enable netfilter packet feed (DEPRECATED!)" + depends on HIPPIE + ---help--- + This will enable the feed of packets to HiPPIE from netfilter. This has caused + some lost packets in the past on high-usage systems and is no longer the default + behavior, but is still reserved as an option. If you do not choose this option, + you will need to enable HiPPIE on a per-interface basis in /proc/net/hippie/interfaces/ + to get packets into HiPPIE. If you are unsure, say N here and use interface mode. + +config HIPPIE_HOSTINFO + bool "Enable HiPPIE Host Information Database" + depends on HIPPIE + ---help--- + This will enable the "host information database," an option in HiPPIE that allows + for protocol definitions to call out to a central source of information about a + host. This allows for the protocols to store and retrieve information (such as + online states, keys, or OS information) on a host by host basis rather than a + session by session basis. + +config HIPPIE_SESSDEBUG + bool "HiPPIE Session Debugging" + depends on HIPPIE + ---help--- + This will turn on debugging functions within the HiPPIE session tracking code + that can help with tracking down bugs or determining what sessions are not + getting classified. !!!WARNING!!! This will produce a lot of log messages + on a busy box, and should not be considered a production option. If you are + not doing any actual debugging, say N here. + +#config HIPPIE_INSPECT_ALL +# bool "Automatically classify all packets" +# depends on HIPPIE +# ---help--- +# This will cause all packets that are passed into HiPPIE to automatically +# be subjected to every protocol signature currently loaded into HiPPIE. +# This could potentially cause significant overhead on the system if not +# used properly. Unless you are using this specifically on a system doing +# protocol analysis such as a filtering device, this is not what you want. +# If unsure, choose N. + +menu "HiPPIE Signature Modules" + depends on HIPPIE + +menu "Network and Transport Protocols" + +config HIPPIE_GRE + tristate "GRE Tunneling Protocol" + ---help--- + This match function will identify traffic of the Generic Routing Encapsulation + (GRE) protocol with the type gre. This is one of the most common tunneling + protocols on the internet. + +config HIPPIE_ESP + tristate "ESP Encrypted Tunneling Protocol" + ---help--- + This match function will identify traffic of the ESP (Encapsulating Security + Payload) protocol for encrypted tunnels with the type esp. This is a very + common encrypted tunneling protocol. + +endmenu + +menu "Standard Protocols" + +config HIPPIE_DNS + tristate "DNS Protocol" + ---help--- + This match function will identify traffic of the Domain Name System (DNS) + Protocol with the type dns. This is one of the most core protocols of the + internet on which nearly all other protocols require for operation. This + should be included. + +config HIPPIE_HTTP + tristate "HTTP Protocol" + ---help--- + This match function will identify traffic in the Hypertext Transfer Protocol + (HTTP) with the type http. This is the most standard base internet protocol + and should most likely be included. + +config HIPPIE_FTP + tristate "FTP Protocol" + ---help--- + This match function will identify traffic in the File Transfer Protocol + (FTP) with the type ftp, and also extra-port transfers outside the control + connections as ftp-data. This is a standard base internet protocol and + should probably be included. + +config HIPPIE_SMTP + tristate "SMTP Protocol" + ---help--- + This match function will identify traffic in the Simple Mail Transfer + Protocol (SMTP) with type smtp. This is the standard for mail transfer + across the internet, and should be included. + +config HIPPIE_POP3 + tristate "POP3 Protocol" + ---help--- + This match function will identify traffic of the POP3 E-mail prootocol + with type pop3. This is a very standard mail retrieval protocol, and + should likely be included. + +config HIPPIE_SSH + tristate "SSH Protocol" + ---help--- + This match function will identify traffic of the SSH protocol, or Secure + Shell with type ssh. This is the standard for secure communications with + unix systems for shell control, and should be included. + +config HIPPIE_IRC + tristate "IRC Protocol" + ---help--- + This match function will identify traffic in the Internet Relay Chat (IRC) + protocol with the type irc, and also external traffic on the Direct Client + Connection (DCC) as irc-dcc. This is a standard base internet protocol and + should probably be included. + +config HIPPIE_SOCKS + tristate "SOCKS Tunneling Protocol" + ---help--- + This match function will identify traffic of the SOCKS v4 or v5 tunneling + protocol with the type socks, and also allow for inspection of the tunnel to + determine the protocols operating within the tunnel. This is a fairly standard + tunneling protocol, and is also heavily used for malicious intent. + +config HIPPIE_NNTP + tristate "NNTP Protocol" + ---help--- + This match function will identiy traffic of the Net News Transfer Protocol (NNTP) + with the type nntp. This is a rather old protocol, but a core standard. + +config HIPPIE_RDESKTOP + tristate "Remote Desktop Protocol" + ---help--- + This match function will identify traffic of the Remote Desktop Protocol (RDP) + with the type rdp. This is the remote control protocol included in Microsoft + Windows in recent years. + +config HIPPIE_NOVELLCP + tristate "Novell IP Core Protocol" + ---help--- + This match function will identify traffic of the Novell IP Core Protocol with + the type novellcp. This isn't a very common protocol, unless you are a network + running Novell Netware versions 5 or greater. + +config HIPPIE_RSYNC + tristate "RSync Protocol" + ---help--- + This match function will identify traffic of the RSync protocol used by the + unix command rsync. This is a common way for file synchronization to occur, + especially for things like source and package trees. + +config HIPPIE_NETFLOW + tristate "Cisco Netflow Protocol" + ---help--- + This match function will identify traffic of the Cisco Netflow protocol used + by Cisco routers and other devices/softwares to export network flow information. + This isn't immensely common except in ISPs or large network settings, and isn't + likely to show up for most users. + +endmenu + +menu "Multimedia Protocols" + +config HIPPIE_RTSP + tristate "Real Time Streaming Protocol (RTSP)" + ---help--- + This match function will identify traffic in the Real Time Streaming Protocol + (RTSP) with the type rtsp, from TCP control sessions even to UDP streams + generated outside of them. This is the base protocol for streaming media + from both Real Corporation and Microsoft Streaming Media. + +config HIPPIE_SIP + tristate "Session Initiation Protocol (SIP)" + ---help--- + This match function will identify traffic in the Session Initiation Protocol + (SIP) with the type sip, from UDP control sessions to further extended UDP + sessions which might be started out of this protocol. This is the base protocol + for many implementations of Voice-over-IP (VoIP). + +endmenu + +menu "Instant Messaging Protocols" + +config HIPPIE_MSNIM + tristate "MSN Messenger Protocol" + ---help--- + This match function will identify traffic of the protocol used for the MSN + Messenger client with signature msnim. + +config HIPPIE_AIM + tristate "AOL Instant Messenger Protocol" + ---help--- + This match function will identify traffic of the protocol used for the AOL + Instant Messenger client with signature aim. + +config HIPPIE_YAHOOIM + tristate "Yahoo Instant Messenger Protocol" + ---help--- + This match function will identify traffic of the protocol used for Yahoo + Instant Messenger clients with signature yahooim. + +endmenu + +menu "Peer-to-Peer Protocols" + +config HIPPIE_BITTORRENT + tristate "BitTorrent Protocol" + ---help--- + This match function will identify traffic of the BitTorrent P2P Protocol, both + of the standard BitTorrent TCP variety, as well as BitComet UDP trackerless + variety. + +config HIPPIE_FASTTRACK + tristate "FastTrack Protocol" + ---help--- + This match function will identify traffic of the FastTrack P2P Protocol, used + commonly by the applications KaZaA, Grokster, IMesh, and others. + +config HIPPIE_ARES + tristate "Ares P2P Protocol" + ---help--- + This match function will identify traffic of the Ares and Warez P2P + protocols with the type ares. + +config HIPPIE_EDONKEY + tristate "EDonkey P2P Protocol" + ---help--- + This match function will identify traffic of the EDonkey P2P protocol + with the type edonkey. This protocol is in use by many p2p applications + including EMule, xMule, Shareaza, and many, many more. + +config HIPPIE_GNUTELLA + tristate "Gnutella P2P Protocol" + ---help--- + This match function will identify traffic of the Gnutella P2P protocol + with type gnutella. This protocol is in use by many p2p applications + including Limewire, BearShare, Morpheus, and so on. + +config HIPPIE_MP2P + tristate "MP2P P2P Protocol" + ---help--- + This match function will identify traffic of the MP2P or "Manolito" protocol + with type mp2p. This protocol is in use by applications such as Blubster and + Piolet. + +config HIPPIE_WINMX + tristate "WinMX P2P Protocol" + ---help--- + This match function will identify traffic of the WinMX P2P protocol + with the type winmx. This protocol was thought to be dead for a while, + but applications have surfaced which will use it once again. + +config HIPPIE_XUNLEI + tristate "Xunlei P2P Protocol" + ---help--- + This match function will identify traffic of the Xunlei (meaning Thunder in Japanese) + P2P protocol with the type xunlei. This protocol is not widely used in the United + States, except by Japanese people, considering the application itself does not come + in any language but Japanese. + +config HIPPIE_PPSTREAM + tristate "PPStream P2P TV Protocol" + ---help--- + This match function will identify traffic of the PPStream P2P TV protocol with the type + ppstream. This protocol isn't used a lot in the US except by Chinese-speaking individuals + because the application is only officially available in Chinese. + +endmenu + +menu "Encryption Protocols" + +config HIPPIE_SSL + tristate "Secure Sockets Layer (SSL) Encryption Protocol" + ---help--- + This match function will identify SSL-Encrypted traffic with the type ssl. + Many applications use SSL, of which the most common is HTTPS traffic, or + SSL Encrypted HTTP. This is very common and should likely be included. + +endmenu + +menu "Malware Protocols" + +config HIPPIE_STORM + tristate "Storm Worm Encrypted Overnet Protocol" + ---help--- + This match function will identify Storm worm generated encrypted Overnet traffic + with the type storm. + +endmenu + +endmenu diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/Makefile linux-2.6.27.8-hippie/net/hippie/Makefile --- linux-2.6.27.8/net/hippie/Makefile 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/Makefile 2008-01-30 12:16:06.000000000 -0600 @@ -0,0 +1,4 @@ +obj-y += piecore.o pie_protocol.o pie_sessions.o pie_interface.o pie_proto_ipv4.o pie_proto_tcp.o pie_proto_udp.o pie_proto_icmp.o proto/ +obj-$(CONFIG_HIPPIE_PREDICTION) += pie_prediction.o +obj-$(CONFIG_PROC_FS) += pie_proc.o +obj-$(CONFIG_HIPPIE_HOSTINFO) += pie_hostinfo.o diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_hostinfo.c linux-2.6.27.8-hippie/net/hippie/pie_hostinfo.c --- linux-2.6.27.8/net/hippie/pie_hostinfo.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_hostinfo.c 2008-03-17 14:27:02.000000000 -0500 @@ -0,0 +1,300 @@ +/* + * Hi-Performance Protocol Identification Engine Host Information DB Functions - pie_hostinfo.c + * $Id: pie_hostinfo.c,v 1.13 2008/03/17 19:27:02 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_PROC_FS +struct proc_dir_entry *proc_net_hippie_hostinfo; +struct proc_dir_entry *proc_net_hippie_hostinfo_detail; +#endif + +struct pie_hostinfo_bucket **pie_hostinfo_hash; + +int pie_hostinfo_init(void) { + int i; + int j; + pie_hostinfo_hash = kmalloc(256 * sizeof(void *),GFP_KERNEL); + if (pie_hostinfo_hash == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to allocate hostinfo structures.\n"); + return -ENOMEM; + } else { + for (i = 0; i < 256; i++) { + pie_hostinfo_hash[i] = kmalloc(256 * sizeof(struct pie_hostinfo_bucket),GFP_KERNEL); + if (pie_hostinfo_hash[i] == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to allocate hostinfo structures.\n"); + kfree(pie_hostinfo_hash); + return -ENOMEM; + } else { + /* Initialize in the hostinfo structure */ + for (j = 0; j < 256; j++) { + pie_hostinfo_hash[i][j].list = NULL; + pie_hostinfo_hash[i][j].lock = RW_LOCK_UNLOCKED; + atomic_set(&pie_hostinfo_hash[i][j].size,0); + } + } + } + } +#ifdef CONFIG_PROC_FS + /* Create proc interfaces */ + proc_net_hippie_hostinfo = create_proc_entry("hostinfo",0400,proc_net_hippie); + if (!proc_net_hippie_hostinfo) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc hostinfo file.\n"); + return -ENOMEM; + } else { + proc_net_hippie_hostinfo->owner = THIS_MODULE; + proc_net_hippie_hostinfo->read_proc = pie_hostinfo_print_proc; + } + proc_net_hippie_hostinfo_detail = create_proc_entry("hostinfo_detail",0400,proc_net_hippie); + if (!proc_net_hippie_hostinfo_detail) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc hostinfo detail file.\n"); + return -ENOMEM; + } else { + proc_net_hippie_hostinfo_detail->owner = THIS_MODULE; + proc_net_hippie_hostinfo_detail->read_proc = pie_hostinfo_print_proc_detail; + } +#endif + printk(KERN_INFO "HiPPIE: Host information database succesfully loaded.\n"); + return 0; +} +EXPORT_SYMBOL(pie_hostinfo_init); + +struct pie_hostinfo_item *pie_hostinfo_new(u_int32_t addr, u_int16_t proto, u_int16_t field, u_int8_t type, u_int16_t timeout) { + u_int8_t hash1 = (addr / 256) % 256; + u_int8_t hash2 = addr % 256; + struct pie_hostinfo_item *newitem = kmalloc(sizeof(struct pie_hostinfo_item),GFP_KERNEL); + if (newitem == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to allocate memory for new hostinfo item.\n"); + return NULL; + } else { + newitem->addr = addr; + newitem->proto = proto; + newitem->field = field; + newitem->type = type; + newitem->byte = 0; + newitem->number = 0; + newitem->pointer = NULL; + /* Set up the timeout */ + if (timeout == 0) { + timeout = 60; + } + ktime_t start = ktime_set(timeout,0); + hrtimer_init(&newitem->timeout,CLOCK_MONOTONIC,HRTIMER_MODE_REL); + newitem->timeout.function = pie_hostinfo_cleanup; + /* Put it in the hash */ + write_lock(&pie_hostinfo_hash[hash1][hash2].lock); + newitem->bucket = &pie_hostinfo_hash[hash1][hash2]; + newitem->next = pie_hostinfo_hash[hash1][hash2].list; + pie_hostinfo_hash[hash1][hash2].list = newitem; + atomic_inc(&pie_hostinfo_hash[hash1][hash2].size); + write_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + hrtimer_start(&newitem->timeout,start,HRTIMER_MODE_REL); + return newitem; + } +} + +u_int32_t pie_hostinfo_get_num(u_int32_t addr, u_int16_t proto, u_int16_t field) { + u_int8_t hash1 = (addr / 256) % 256; + u_int8_t hash2 = addr % 256; + read_lock(&pie_hostinfo_hash[hash1][hash2].lock); + struct pie_hostinfo_item *search = pie_hostinfo_hash[hash1][hash2].list; + while (search != NULL) { + if (search->addr == addr && search->proto == proto && search->field == field && search->type == PIE_HOSTINFO_NUM) { + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + return search->number; + } + search = search->next; + } + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + return 0; +} +EXPORT_SYMBOL(pie_hostinfo_get_num); + +u_int8_t pie_hostinfo_get_byte(u_int32_t addr, u_int16_t proto, u_int16_t field) { + u_int8_t hash1 = (addr / 256) % 256; + u_int8_t hash2 = addr % 256; + read_lock(&pie_hostinfo_hash[hash1][hash2].lock); + struct pie_hostinfo_item *search = pie_hostinfo_hash[hash1][hash2].list; + while (search != NULL) { + if (search->addr == addr && search->proto == proto && search->field == field && search->type == PIE_HOSTINFO_BYTE) { + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + return search->byte; + } + search = search->next; + } + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + return 0; +} +EXPORT_SYMBOL(pie_hostinfo_get_byte); + +void *pie_hostinfo_get_pointer(u_int32_t addr, u_int16_t proto, u_int16_t field) { + u_int8_t hash1 = (addr / 256) % 256; + u_int8_t hash2 = addr % 256; + read_lock(&pie_hostinfo_hash[hash1][hash2].lock); + struct pie_hostinfo_item *search = pie_hostinfo_hash[hash1][hash2].list; + while (search != NULL) { + if (search->addr == addr && search->proto == proto && search->field == field && search->type == PIE_HOSTINFO_POINTER) { + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + return search->pointer; + } + search = search->next; + } + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + return NULL; +} +EXPORT_SYMBOL(pie_hostinfo_get_pointer); + +void pie_hostinfo_set_num(u_int32_t addr, u_int16_t proto, u_int16_t field, u_int32_t val, u_int16_t timeout) { + u_int8_t hash1 = (addr / 256) % 256; + u_int8_t hash2 = addr % 256; + read_lock(&pie_hostinfo_hash[hash1][hash2].lock); + struct pie_hostinfo_item *search = pie_hostinfo_hash[hash1][hash2].list; + while (search != NULL) { + if (search->addr == addr && search->proto == proto && search->field == field && search->type == PIE_HOSTINFO_NUM) { + break; + } + search = search->next; + } + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + if (search == NULL) { + search = pie_hostinfo_new(addr,proto,field,PIE_HOSTINFO_NUM,timeout); + } + if (search != NULL) { + write_lock(&pie_hostinfo_hash[hash1][hash2].lock); + ktime_t start = ktime_set(timeout,0); + hrtimer_cancel(&search->timeout); + hrtimer_start(&search->timeout,start,HRTIMER_MODE_REL); + search->number = val; + write_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + } +} +EXPORT_SYMBOL(pie_hostinfo_set_num); + +void pie_hostinfo_set_byte(u_int32_t addr, u_int16_t proto, u_int16_t field, u_int8_t val, u_int16_t timeout) { + u_int8_t hash1 = (addr / 256) % 256; + u_int8_t hash2 = addr % 256; + read_lock(&pie_hostinfo_hash[hash1][hash2].lock); + struct pie_hostinfo_item *search = pie_hostinfo_hash[hash1][hash2].list; + while (search != NULL) { + if (search->addr == addr && search->proto == proto && search->field == field && search->type == PIE_HOSTINFO_BYTE) { + break; + } + search = search->next; + } + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + if (search == NULL) { + search = pie_hostinfo_new(addr,proto,field,PIE_HOSTINFO_BYTE,timeout); + } + if (search != NULL) { + write_lock(&pie_hostinfo_hash[hash1][hash2].lock); + ktime_t start = ktime_set(timeout,0); + hrtimer_cancel(&search->timeout); + hrtimer_start(&search->timeout,start,HRTIMER_MODE_REL); + search->byte = val; + write_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + } +} +EXPORT_SYMBOL(pie_hostinfo_set_byte); + +void pie_hostinfo_set_pointer(u_int32_t addr, u_int16_t proto, u_int16_t field, void *val, u_int16_t timeout) { + u_int8_t hash1 = (addr / 256) % 256; + u_int8_t hash2 = addr % 256; + read_lock(&pie_hostinfo_hash[hash1][hash2].lock); + struct pie_hostinfo_item *search = pie_hostinfo_hash[hash1][hash2].list; + while (search != NULL) { + if (search->addr == addr && search->proto == proto && search->field == field && search->type == PIE_HOSTINFO_POINTER) { + break; + } + search = search->next; + } + read_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + if (search == NULL) { + search = pie_hostinfo_new(addr,proto,field,PIE_HOSTINFO_POINTER,timeout); + } + if (search != NULL) { + write_lock(&pie_hostinfo_hash[hash1][hash2].lock); + ktime_t start = ktime_set(timeout,0); + hrtimer_cancel(&search->timeout); + hrtimer_start(&search->timeout,start,HRTIMER_MODE_REL); + search->pointer = val; + write_unlock(&pie_hostinfo_hash[hash1][hash2].lock); + } +} +EXPORT_SYMBOL(pie_hostinfo_set_pointer); + +enum hrtimer_restart pie_hostinfo_cleanup(struct hrtimer *timer) { + struct pie_hostinfo_item *item = container_of(timer,struct pie_hostinfo_item,timeout); + struct pie_hostinfo_bucket *bucket = item->bucket; + struct pie_hostinfo_item *search = NULL; + //printk(KERN_INFO "HiPPIE: Terminating hostinfo %u/%u/%u/%u.\n",item->addr,item->proto,item->field,item->number); + write_lock(&bucket->lock); + if (bucket->list == item) { + bucket->list = item->next; + } else { + search = bucket->list; + while (search != NULL) { + if (search->next == item) { + search->next = item->next; + break; + } + search = search->next; + } + } + atomic_dec(&bucket->size); + write_unlock(&bucket->lock); + kfree(item); + return HRTIMER_NORESTART; +} + +int pie_hostinfo_print_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + int len = 0; + int i = 0; + int j = 0; + int total_host_info = 0; + int max_host_info = 0; + int active_buckets = 0; + len += sprintf(buffer+len,"HiPPIE Host Information Database Stats\n"); + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + int val = 0; + read_lock(&pie_hostinfo_hash[i][j].lock); + val = atomic_read(&pie_hostinfo_hash[i][j].size); + if (val > 0) { + total_host_info += val; + active_buckets++; + if (val > max_host_info) { + max_host_info = val; + } + } + read_unlock(&pie_hostinfo_hash[i][j].lock); + } + } + len += sprintf(buffer+len,"Active Hostinfo Buckets: %d\n",active_buckets); + len += sprintf(buffer+len,"Active Hostinfo Values: %d\n",total_host_info); + if (active_buckets > 0) { + len += sprintf(buffer+len,"Average Active Bucket Size: %d\n",(int) total_host_info / active_buckets); + } + len += sprintf(buffer+len,"Maximum Bucket Size: %d\n",max_host_info); + *eof = 1; + return len; +} + +int pie_hostinfo_print_proc_detail(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + *eof = 1; + return 0; +} diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_interface.c linux-2.6.27.8-hippie/net/hippie/pie_interface.c --- linux-2.6.27.8/net/hippie/pie_interface.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_interface.c 2008-06-28 20:33:53.000000000 -0500 @@ -0,0 +1,171 @@ +/* + * Hi-Performance Protocol Identification Engine Network Interface Code - pie_interface.c + * $Id: pie_interface.c,v 1.10 2008/06/29 01:33:53 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct pie_interface *pie_interfaces; + +struct notifier_block pie_device_notifier = { + .notifier_call = pie_interface_notifier +}; + +struct proc_dir_entry *proc_net_hippie_interfaces = NULL; + +u_int8_t pie_interfaces_init(void) { + pie_interfaces = NULL; + proc_net_hippie_interfaces = proc_mkdir("interfaces",proc_net_hippie); + int result = register_netdevice_notifier(&pie_device_notifier); + if (result != 0) { + /* Failed to register ourselves to listen for devices */ + printk(KERN_ALERT "HiPPIE: Failed to register for network interface updates!\n"); + return result; + } + return 0; +} +EXPORT_SYMBOL(pie_interfaces_init); + +/* This call handles network device change notifications, in order to keep up the list of interfaces + * that are being monitored by HiPPIE */ +int pie_interface_notifier(struct notifier_block *unused, unsigned long event, void *ptr) { + struct net_device *dev = ptr; + switch (event) { + case NETDEV_UP: + pie_interface_up(dev); + break; + case NETDEV_DOWN: + pie_interface_down(dev); + break; + case NETDEV_UNREGISTER: + pie_rem_interface(dev); + break; + } + return NOTIFY_DONE; +} + +int pie_interface_up(struct net_device *dev) { + struct pie_interface *search = pie_interfaces; + struct pie_interface *interface = NULL; + while (search != NULL) { + if (search->device == dev) { + interface = search; + break; + } + search = search->next_int; + } + if (interface == NULL) { + /* Add this device, it doesn't exist */ + interface = pie_add_interface(dev); + dev->hippie_read = 0; + } + return 0; +} + +int pie_interface_down(struct net_device *dev) { + struct pie_interface *search = pie_interfaces; + struct pie_interface *interface = NULL; + while (search != NULL) { + if (search->device == dev) { + interface = search; + break; + } + search = search->next_int; + } + if (interface == NULL) { + /* Add this device, it doesn't exist */ + interface = pie_add_interface(dev); + } + return 0; +} + +struct pie_interface *pie_add_interface(struct net_device *dev) { + struct pie_interface *newint = kmalloc(sizeof(struct pie_interface),GFP_KERNEL); + if (newint == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for new interface!\n"); + return NULL; + } + newint->device = dev; + newint->next_int = pie_interfaces; +#ifdef CONFIG_PROC_FS + /* Add proc stuff */ + newint->proc = create_proc_entry(newint->device->name,0600,proc_net_hippie_interfaces); + if (!newint->proc) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc for new network interface %s.\n",newint->device->name); + kfree(newint); + return NULL; + } else { + newint->proc->owner = THIS_MODULE; + newint->proc->read_proc = &pie_interface_proc_read; + newint->proc->write_proc = &pie_interface_proc_write; + newint->proc->data = (void *)newint; + } +#endif + pie_interfaces = newint; + return newint; +} + +void pie_rem_interface(struct net_device *dev) { + /* Delete this interface */ + +} + +int pie_int_packet_read_skb(struct net_device *dev, struct sk_buff *skb) { + return pie_packet_read_skb(skb); +} + +int pie_int_packet_read(struct net_device *dev, u_int8_t *packet, u_int32_t len) { + /* Received a packet from dev, check if dev is listening */ + return pie_packet_read(packet,len); +} +EXPORT_SYMBOL(pie_int_packet_read); + +int pie_interface_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + struct pie_interface *interface = (struct pie_interface *)data; + int len = 0; + len += sprintf(buffer,"%d\n", interface->device->hippie_read); + *eof = 1; + return len; +} + +int pie_interface_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) { + int len; + struct pie_interface *interface = (struct pie_interface *)data; + + char lbuffer[513]; + if (count > 512) { + len = 512; + } else { + len = count; + } + + if (copy_from_user(lbuffer,buffer,len)) { + printk(KERN_ALERT "HiPPIE-DBG: Faulted reading copy_from_user.\n"); + return -EFAULT; + } + + lbuffer[len] = '\0'; + u_int8_t opt = simple_strtoul(lbuffer, NULL, 10); + if (interface->device->hippie_read == 0 && opt > 0) { + interface->device->hippie_read = opt % 3; + } else if (interface->device->hippie_read > 0 && opt == 0) { + interface->device->hippie_read = opt; + } else if (interface->device->hippie_read > 0 && opt > 0) { + interface->device->hippie_read = opt % 3; + } + return len; +} diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_prediction.c linux-2.6.27.8-hippie/net/hippie/pie_prediction.c --- linux-2.6.27.8/net/hippie/pie_prediction.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_prediction.c 2008-03-17 14:27:02.000000000 -0500 @@ -0,0 +1,255 @@ +/* + * Hi-Performance Protocol Identification Engine Session Prediction Code - pie_prediction.c + * $Id: pie_prediction.c,v 1.19 2008/03/17 19:27:02 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct pie_sess_hdr pie_prediction_table; +atomic_t pie_predict_add; +atomic_t pie_predict_used; +#ifdef CONFIG_PROC_FS +struct proc_dir_entry *proc_net_hippie_sessions_predictions; +#endif + +int pie_prediction_init(void) { + atomic_set(&pie_predict_add,0); + atomic_set(&pie_predict_used,0); + + /* Set up prediction table */ + pie_prediction_table.lock = RW_LOCK_UNLOCKED; + pie_prediction_table.sessions = NULL; + atomic_set(&pie_prediction_table.sesscount,0); +#ifdef CONFIG_PROC_FS + /* Create the /proc/net/hippie/sessions/predictions file */ + proc_net_hippie_sessions_predictions = create_proc_entry("predictions",0400,proc_net_hippie_sessions); + if (!proc_net_hippie_sessions_predictions) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc predictions list.\n"); + return -ENOMEM; + } else { + proc_net_hippie_sessions_predictions->owner = THIS_MODULE; + proc_net_hippie_sessions_predictions->read_proc = pie_proc_print_predictions; + } +#endif + return 0; +} + +struct pie_sess_info *pie_prediction_create(void) { + struct pie_sess_info *sess = kmalloc(sizeof(struct pie_sess_info),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to allocate memory for predicted session.\n"); + return NULL; + } + sess->sessid = 0; + /* Set the base options */ + atomic_set(&sess->packets,0); + atomic_set(&sess->bytes,0); + atomic_set(&sess->state,PIE_STATE_PREDICTED); + sess->caninspect = 1; + sess->persist = 0; + sess->sigdata = NULL; + sess->next = NULL; + sess->prev = NULL; + sess->lock = NULL; + sess->bucket = NULL; + pie_session_timeout_init(sess); + /* NULL the headers */ + sess->network_sess = NULL; + sess->transport_sess = NULL; + sess->first_sess = NULL; + sess->last_sess = NULL; + atomic_inc(&pie_predict_add); + return sess; +} + +u_int8_t pie_prediction_schedule(struct pie_sess_info *sess) { + /* Validate that all the headers in the session have appropriate parameters. */ + struct pie_protocol_sess *search = sess->first_sess; + while (search != NULL) { + if (pie_protocols[search->protoindex] != NULL) { + if (pie_protocols[search->protoindex]->validate_prediction) { + if (pie_protocols[search->protoindex]->validate_prediction(search) == 0) { + printk(KERN_INFO "HiPPIE: Failed validating prediction of session. Unable to schedule.\n"); + /* Clean this thing up right now... */ + pie_session_timeout_cancel(sess); + pie_free_session_header(sess->first_sess); + kfree(sess); + return 0; + } + } + } + search = search->next_sess; + } + /* Add the session to the proper buckets */ + sess->lock = &pie_prediction_table.lock; + sess->bucket = &pie_prediction_table; + write_lock(&pie_prediction_table.lock); + sess->next = pie_prediction_table.sessions; + if (pie_prediction_table.sessions != NULL) { + pie_prediction_table.sessions->prev = sess; + } + pie_prediction_table.sessions = sess; + atomic_inc(&pie_prediction_table.sesscount); + write_unlock(&pie_prediction_table.lock); + return 1; +} + +struct pie_protocol_sess *pie_prediction_add_header(struct pie_sess_info *sess, u_int16_t protocol) { + if (sess != NULL && protocol != 0 && pie_protocols[protocol] != NULL) { + struct pie_protocol_sess *predhdr = NULL; + if (pie_protocols[protocol]->create_predict != NULL) { + /* Call the module's header function */ + predhdr = pie_protocols[protocol]->create_predict(); + } else { + /* Create the header ourselves */ + predhdr = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (predhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for prediction session header information.\n"); + return NULL; + } + predhdr->protoindex = protocol; + predhdr->next_sess = NULL; + predhdr->proto_info = NULL; + } + if (predhdr != NULL) { + if (sess->first_sess == NULL) { + sess->first_sess = predhdr; + } + if (sess->last_sess != NULL) { + sess->last_sess->next_sess = predhdr; + } + sess->last_sess = predhdr; + if (pie_protocols[protocol]->prototype == PIE_PROTOTYPE_NETWORK && sess->network_sess == NULL) { + sess->network_sess = predhdr; + } + if (pie_protocols[protocol]->prototype == PIE_PROTOTYPE_TRANSPORT && sess->transport_sess == NULL) { + sess->transport_sess = predhdr; + } + atomic_inc(&pie_protocols[protocol]->predicts); + return predhdr; + } else { + printk(KERN_ALERT "HiPPIE: Protocol ID %d returned a NULL prediction session header.\n",protocol); + return NULL; + } + } else { + printk(KERN_ALERT "HiPPIE: Received invalid options to add prediction header.\n"); + return NULL; + } +} + +u_int8_t pie_prediction_parameter(struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data) { + if (pie_protocols[hdr->protoindex] != NULL) { + if (pie_protocols[hdr->protoindex]->add_predict_option != NULL) { + if (pie_protocols[hdr->protoindex]->add_predict_option(hdr,name,dtype,data) != 0) { + return 1; + } else { + printk(KERN_INFO "HiPPIE: Protocol ID %d failed to add parameter %s.\n",hdr->protoindex,name); + return 0; + } + } else { + printk(KERN_INFO "HiPPIE: Protocol ID %d doesn't seem to support prediction parameters.\n", hdr->protoindex); + return 0; + } + } else { + printk(KERN_ALERT "HiPPIE: Protocol ID %d doesn't seem to exist.\n",hdr->protoindex); + return 0; + } +} + +struct pie_sess_info *pie_use_prediction(struct pie_packet_info *packet, struct pie_sess_info *predsess) { + struct pie_protocol_hdr *pkthdr = packet->network_hdr; + struct pie_protocol_sess *pktsess = predsess->network_sess; + struct pie_protocol_sess *search; + while (pktsess != NULL) { + if (pie_protocols[pktsess->protoindex] != NULL) { + if (pie_protocols[pktsess->protoindex]->convert_prediction != NULL) { + pie_protocols[pktsess->protoindex]->convert_prediction(pkthdr,pktsess); + } + } + pktsess = pktsess->next_sess; + if (pkthdr != NULL) { + pkthdr = pkthdr->next_hdr; + } + } + /* Now move it into the appropriate buckets */ + /* Remove it from the prediction table */ + write_lock(&pie_prediction_table.lock); + if (pie_prediction_table.sessions == predsess) { + pie_prediction_table.sessions = predsess->next; + } else if (predsess->prev != NULL) { + predsess->prev->next = predsess->next; + } else { + printk(KERN_ALERT "HiPPIE: Uh oh, found predicted session with null previous that isn't root session in bucket.\n"); + } + if (predsess->next != NULL) { + predsess->next->prev = predsess->prev; + } + /*if (pie_prediction_table.sessions == predsess) { + pie_prediction_table.sessions = predsess->next; + } else { + struct pie_sess_info *search = pie_prediction_table.sessions; + while (search != NULL) { + if (search->next == predsess) { + search->next = predsess->next; + break; + } + search = search->next; + } + }*/ + atomic_dec(&pie_prediction_table.sesscount); + write_unlock(&pie_prediction_table.lock); + predsess->next = NULL; + /* Insert it into the appropriate bucket. */ + u_int8_t hash1 = 255; + u_int8_t hash2 = 255; + if (predsess->network_sess != NULL && pie_protocols[predsess->network_sess->protoindex] != NULL && pie_protocols[predsess->network_sess->protoindex]->get_sess_bucket != NULL) { + hash1 = pie_protocols[predsess->network_sess->protoindex]->get_sess_bucket(packet->network_hdr,0); + if (predsess->transport_sess != NULL && pie_protocols[predsess->transport_sess->protoindex] != NULL && pie_protocols[predsess->transport_sess->protoindex]->get_sess_bucket != NULL) { + hash2 = pie_protocols[predsess->transport_sess->protoindex]->get_sess_bucket(packet->transport_hdr,0); + } + } + predsess->lock = &pie_session_table[hash1][hash2].lock; + predsess->bucket = &pie_session_table[hash1][hash2]; + write_lock(&pie_session_table[hash1][hash2].lock); + predsess->next = pie_session_table[hash1][hash2].sessions; + if (pie_session_table[hash1][hash2].sessions != NULL) { + pie_session_table[hash1][hash2].sessions->prev = predsess; + } + pie_session_table[hash1][hash2].sessions = predsess; + atomic_inc(&pie_session_table[hash1][hash2].sesscount); + write_unlock(&pie_session_table[hash1][hash2].lock); + /* This is a newly created session, and no longer a prediction */ + atomic_set(&predsess->state,PIE_STATE_NEW); + /* Allocate a session, adjust counters*/ + predsess->sessid = atomic_read(&pie_session_count); + atomic_inc(&pie_session_count); + atomic_inc(&pie_session_countactive); + atomic_inc(&pie_predict_used); + /* Recursively make sure each protocol knows it's prediction was used */ + search = predsess->first_sess; + while (search != NULL) { + atomic_inc(&pie_protocols[search->protoindex]->predicts_used); + search = search->next_sess; + } + return predsess; +} + +EXPORT_SYMBOL(pie_prediction_create); +EXPORT_SYMBOL(pie_prediction_add_header); +EXPORT_SYMBOL(pie_prediction_parameter); +EXPORT_SYMBOL(pie_prediction_schedule); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_proc.c linux-2.6.27.8-hippie/net/hippie/pie_proc.c --- linux-2.6.27.8/net/hippie/pie_proc.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_proc.c 2008-12-06 21:00:12.000000000 -0600 @@ -0,0 +1,431 @@ +/* + * Hi-Performance Protocol Identification Engine Proc Filesystem Code - pie_proc.c + * $Id: pie_proc.c,v 1.27 2008/12/07 03:00:12 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#ifdef CONFIG_HIPPIE_PREDICTION +#include +#endif +#include +#include + +//static struct proc_dir_entry *proc_net_hippie = NULL; + +struct proc_dir_entry *proc_net_hippie = NULL; +struct proc_dir_entry *proc_net_hippie_proto = NULL; +extern char *pie_sessions_pbuffer; + +struct proc_dir_entry *proc_net_hippie_modules_list; +struct proc_dir_entry *proc_net_hippie_sessions_all; +struct proc_dir_entry *proc_net_hippie_protocols; +struct proc_dir_entry *proc_net_hippie_stat; +struct proc_dir_entry *proc_net_hippie_sessions_buckets_stat; +struct proc_dir_entry *proc_net_hippie_stat_reset; + +char *pie_sessions_pbuffer = NULL; +u_int32_t pie_sessions_pbuffer_size; + +char *pie_bucketstat_buffer = NULL; +u_int32_t pie_bucketstat_buffer_size; + +int pie_proc_init(void) { + /* Create directory entries to put proc "files" in */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) + proc_net_hippie = proc_mkdir("hippie",init_net.proc_net); +#else + proc_net_hippie = proc_mkdir("hippie",proc_net); +#endif + if(!proc_net_hippie) return -ENOMEM; + proc_net_hippie_proto = proc_mkdir("proto",proc_net_hippie); + if (!proc_net_hippie_proto) return -ENOMEM; + /* Create the /proc/net/hippie/stat file */ + proc_net_hippie_stat = create_proc_entry("stat",0400,proc_net_hippie); + if (!proc_net_hippie_stat) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc stat file.\n"); + return -ENOMEM; + } else { + proc_net_hippie_stat->owner = THIS_MODULE; + proc_net_hippie_stat->read_proc = pie_proc_print_stat; + } + proc_net_hippie_stat_reset = create_proc_entry("stat_reset",0600,proc_net_hippie); + if (!proc_net_hippie_stat_reset) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc stat_reset file.\n"); + return -ENOMEM; + } else { + proc_net_hippie_stat_reset->owner = THIS_MODULE; + proc_net_hippie_stat_reset->write_proc = pie_proc_stat_reset; + } + return 0; +} + +int pie_proc_stat_reset(struct file *file, const char *buffer, unsigned long count, void *data) { + int len; + int i; + + char lbuffer[513]; + if (count > 512) { + len = 512; + } else { + len = count; + } + + if (copy_from_user(lbuffer,buffer,len)) { + printk(KERN_ALERT "HiPPIE-DBG: Faulted reading copy_from_user.\n"); + return -EFAULT; + } + + lbuffer[len] = '\0'; + u_int8_t opt = simple_strtoul(lbuffer, NULL, 10); + if (opt > 0) { + /* Loop through and reset statistics! */ + atomic_set(&pie_session_count,0); + atomic_set(&pie_session_countactive,0); + atomic_set(&pie_packet_count,0); + atomic_set(&pie_byte_count,0); + atomic_set(&pie_inspect_count,0); +#ifdef CONFIG_HIPPIE_PREDICTION + atomic_set(&pie_predict_add,0); + atomic_set(&pie_predict_used,0); +#endif + for (i = 1;i < 256;i++) { + if (pie_protocols[i] != NULL) { + atomic_set(&pie_protocols[i]->packets_ins,0); + atomic_set(&pie_protocols[i]->all_packets,0); + atomic_set(&pie_protocols[i]->all_conns,0); + atomic_set(&pie_protocols[i]->all_bytes,0); + atomic_set(&pie_protocols[i]->packets,0); + atomic_set(&pie_protocols[i]->conns,0); + atomic_set(&pie_protocols[i]->bytes,0); + atomic_set(&pie_protocols[i]->predicts,0); + atomic_set(&pie_protocols[i]->predicts_used,0); + } + } + } else { + return len; + } + return len; +} + +int pie_proc_print_stat(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + int len = 0; + int i = 0; + int j = 0; + int bucket_avg_count = 0; + int bucket_nonz_avg_count = 0; + int bucket_nonz_avg_bcount = 0; + int bucket_max = 0; + int bucket_max_i = 0; + int bucket_max_j = 0; + int bucket_over10 = 0; + int bucket_over25 = 0; + int bucket_over50 = 0; + len += sprintf(buffer,"HiPPIE Statistics\n"); + + len += sprintf(buffer+len, "Total Sessions Processed: %u\n", atomic_read(&pie_session_count)); + len += sprintf(buffer+len, "Current Active Sessions: %u\n", atomic_read(&pie_session_countactive)); + len += sprintf(buffer+len, "Total Packets Processed: %u\n", atomic_read(&pie_packet_count)); + len += sprintf(buffer+len, "Total Bytes Processed: %u\n", atomic_read(&pie_byte_count)); + len += sprintf(buffer+len, "Total Packets Inspected: %u\n", atomic_read(&pie_inspect_count)); +#ifdef CONFIG_HIPPIE_PREDICTION + len += sprintf(buffer+len, "Total Sessions Predicted: %u\n", atomic_read(&pie_predict_add)); + len += sprintf(buffer+len, "Total Predictions Converted: %u\n", atomic_read(&pie_predict_used)); +#endif + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + int lcount = atomic_read(&pie_session_table[i][j].sesscount); + bucket_avg_count += lcount; + if (lcount > bucket_max) { + bucket_max = lcount; + bucket_max_i = i; + bucket_max_j = j; + } + if (lcount > 0) { + bucket_nonz_avg_count += lcount; + bucket_nonz_avg_bcount++; + } + if (lcount > 10) { + bucket_over10++; + } + if (lcount > 25) { + bucket_over25++; + } + if (lcount > 50) { + bucket_over50++; + } + } + } + len += sprintf(buffer+len,"Active Buckets: %u\n",bucket_nonz_avg_bcount); + len += sprintf(buffer+len,"Max session bucket size: %u (%u/%u)\n",bucket_max,bucket_max_i,bucket_max_j); + len += sprintf(buffer+len,"Avg session bucket size: %u\n",(int)(bucket_avg_count / 65536)); + if (bucket_nonz_avg_bcount > 0) { + len += sprintf(buffer+len,"Avg non-zero bucket size: %u\n",(int)(bucket_nonz_avg_count / bucket_nonz_avg_bcount)); + } else { + len += sprintf(buffer+len,"Avg non-zero bucket size: 0\n"); + } + len += sprintf(buffer+len,"Buckets over 10 sessions: %u\n",bucket_over10); + len += sprintf(buffer+len,"Buckets over 25 sessions: %u\n",bucket_over25); + len += sprintf(buffer+len,"Buckets over 50 sessions: %u\n",bucket_over50); + *eof = 1; + return len; +} + +int pie_proc_print_protocols(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + int len = 0, i; + len += sprintf(buffer,"ID\tProto\t\tType\tEncap\tPersist\tInsps\t[Pkts\tConns\tBytes]\t[Pkts\tConns\tBytes]\t[Preds\tUsed]\n"); + for (i = 1;i < 256;i++) { + if (pie_protocols[i] != NULL) { + if (strlen(pie_protocols[i]->name) < 8) { + len += sprintf(buffer+len,"%u\t%s\t\t",i,pie_protocols[i]->name); + } else { + len += sprintf(buffer+len,"%u\t%s\t",i,pie_protocols[i]->name); + } + switch (pie_protocols[i]->prototype) { + case PIE_PROTOTYPE_LINK: + len += sprintf(buffer+len,"LINK"); + break; + case PIE_PROTOTYPE_NETWORK: + len += sprintf(buffer+len,"NET"); + break; + case PIE_PROTOTYPE_TRANSPORT: + len += sprintf(buffer+len,"TRANS"); + break; + case PIE_PROTOTYPE_ENCAP: + len += sprintf(buffer+len,"ENCAP"); + break; + case PIE_PROTOTYPE_APP: + len += sprintf(buffer+len,"APP"); + break; + default: + len += sprintf(buffer+len,"UNK"); + break; + } + switch(pie_protocols[i]->encapsulation) { + case PIE_ENCAP_NONE: + len += sprintf(buffer+len,"\tNONE"); + break; + case PIE_ENCAP_UNTAGGED: + len += sprintf(buffer+len,"\tNOTAG"); + break; + case PIE_ENCAP_TAGGED: + len += sprintf(buffer+len,"\tTAG"); + break; + case PIE_ENCAP_MULTIPLEX: + len += sprintf(buffer+len,"\tMULTI"); + break; + default: + len += sprintf(buffer+len,"\tUNK"); + break; + } + if (pie_protocols[i]->persist == NULL) { + len += sprintf(buffer+len,"\tNo"); + } else { + len += sprintf(buffer+len,"\tYes"); + } + len += sprintf(buffer+len,"\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n",atomic_read(&pie_protocols[i]->packets_ins),atomic_read(&pie_protocols[i]->all_packets),atomic_read(&pie_protocols[i]->all_conns),atomic_read(&pie_protocols[i]->all_bytes),atomic_read(&pie_protocols[i]->packets),atomic_read(&pie_protocols[i]->conns),atomic_read(&pie_protocols[i]->bytes),atomic_read(&pie_protocols[i]->predicts),atomic_read(&pie_protocols[i]->predicts_used)); + } + } + *eof = 1; + return len; +} + +#ifdef CONFIG_HIPPIE_PREDICTION +int pie_proc_print_predictions(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + int len = 0; + struct pie_sess_info *search; + struct pie_protocol_sess *protosess; + read_lock(&pie_prediction_table.lock); + search = pie_prediction_table.sessions; + while (search != NULL) { + len += pie_session_print(buffer+len,search); + search=search->next; + } + read_unlock(&pie_prediction_table.lock); + *eof = 1; + return len; +} +#endif + +int pie_proc_print_session_bucket(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + struct pie_sess_hdr *bucket = (struct pie_sess_hdr *)data; + int len = 0; + int i = 0, printlen = 0; + struct pie_sess_info *search; + struct pie_protocol_sess *protosess; + if (offset == 0) { + if (bucket->procbuffer != NULL) { + vfree(bucket->procbuffer); + bucket->procbuffer = NULL; + } + if (atomic_read(&bucket->sesscount) == 0) { + return 0; + } + bucket->procbuffer = vmalloc(atomic_read(&bucket->sesscount) * sizeof(char *) * 200); + if (bucket->procbuffer == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for the proc session bucket printout.\n"); + return -ENOMEM; + } + read_lock(&bucket->lock); + search = bucket->sessions; + while (search != NULL) { + len += pie_session_print(bucket->procbuffer+len,search); + search=search->next; + } + read_unlock(&bucket->lock); + bucket->procbuffersize = len; + } + *eof = 0; + *start = buffer; + for (i = 0; i < length; i++) { + if (offset + i < bucket->procbuffersize) { + buffer[i] = bucket->procbuffer[offset + i]; + printlen++; + } else { + *eof = 1; + break; + } + } + return printlen; +} + +int pie_proc_print_proto_stats(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + struct pie_protocol *mod = (struct pie_protocol *) data; + int len = 0; + if (data == NULL) { + return 0; + } + len += sprintf(buffer+len, "Protocol Name: %s\n",mod->name); + //len += sprintf(buffer+len, "Protocol Index: %d\n",mod->protoindex); + //len += sprintf(buffer+len, "Version: %d\n",mod->ver); + if (mod->persist != NULL) { + len += sprintf(buffer+len, "Persistance: On\n"); + } else { + len += sprintf(buffer+len, "Persistance: Off\n"); + } + len += sprintf(buffer+len, "Signature N-Packets Value: %d\n",mod->n_packets); + len += sprintf(buffer+len, "[ Classifications ]\n"); + len += sprintf(buffer+len, "Classified Connections: %d\n",atomic_read(&mod->conns)); + len += sprintf(buffer+len, "Classified Packets: %d\n",atomic_read(&mod->packets)); + len += sprintf(buffer+len, "Classified Bytes: %d\n",atomic_read(&mod->bytes)); + len += sprintf(buffer+len, "[ Encapsulations ]\n"); + len += sprintf(buffer+len, "Encapsulated Connections: %d\n",atomic_read(&mod->all_conns)); + len += sprintf(buffer+len, "Encapsulated Packets: %d\n",atomic_read(&mod->all_packets)); + len += sprintf(buffer+len, "Encapsulated Bytes: %d\n",atomic_read(&mod->all_bytes)); + len += sprintf(buffer+len, "\n"); + len += sprintf(buffer+len, "Inspected Packets: %d\n",atomic_read(&mod->packets_ins)); + len += sprintf(buffer+len, "Predictions Made: %d\n",atomic_read(&mod->predicts)); + len += sprintf(buffer+len, "Predictions Used: %d\n",atomic_read(&mod->predicts_used)); + *eof = 1; + return len; +} + +int pie_proc_print_bucket_stats(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + int len = 0; + int i = 0; + int j = 0; + int printlen = 0; + if (offset == 0) { + if (pie_bucketstat_buffer != NULL) { + vfree(pie_bucketstat_buffer); + pie_bucketstat_buffer = NULL; + } + pie_bucketstat_buffer = vmalloc(65536 * 50 * sizeof(char *)); + if (pie_bucketstat_buffer == NULL) { + printk(KERN_WARNING "HiPPIE: Failed to allocate memory for proc bucket stats printout.\n"); + return -ENOMEM; + } + len += sprintf(pie_bucketstat_buffer+len,"BucketID\tSize\n"); + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + len += sprintf(pie_bucketstat_buffer+len,"[%d][%d]\t%d\n",i,j,atomic_read(&pie_session_table[i][j].sesscount)); + } + } + pie_bucketstat_buffer_size = len; + } + + *eof = 0; + *start = buffer; + for (i = 0;i < length;i++) { + if (offset + i < pie_bucketstat_buffer_size) { + buffer[i] = pie_bucketstat_buffer[offset + i]; + printlen++; + } else { + *eof = 1; + break; + } + } + return printlen; +} + +int pie_proc_print_sessions(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { + int len = 0; + int i = 0, printlen = 0; + int j = 0; + if (offset == 0) { + struct pie_sess_info *search = NULL; + if (pie_sessions_pbuffer != NULL) { + vfree(pie_sessions_pbuffer); + pie_sessions_pbuffer = NULL; + } + pie_sessions_pbuffer = vmalloc(atomic_read(&pie_session_countactive) * sizeof(char *) * 200); + if (pie_sessions_pbuffer == NULL) { + printk(KERN_WARNING "HiPPIE: Failed to allocate memory for the proc sessions table printout.\n"); + return -ENOMEM; + } + len += sprintf(pie_sessions_pbuffer,"SessID\tProto\tPackets\tTimeout\tState\tProtocol Information\n"); + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + read_lock(&pie_session_table[i][j].lock); + search = pie_session_table[i][j].sessions; + while (search != NULL) { + len += pie_session_print(pie_sessions_pbuffer+len,search); + search=search->next; + } + read_unlock(&pie_session_table[i][j].lock); + } + } +#ifdef CONFIG_HIPPIE_PREDICTION + len += sprintf(pie_sessions_pbuffer+len,"\nPredicted Sessions:\n"); + read_lock(&pie_prediction_table.lock); + search = pie_prediction_table.sessions; + while (search != NULL) { + len += pie_session_print(pie_sessions_pbuffer+len,search); + search=search->next; + } + read_unlock(&pie_prediction_table.lock); +#endif + pie_sessions_pbuffer_size = len; + } + + *eof = 0; + *start = buffer; + for (i = 0;i < length;i++) { + if (offset + i < pie_sessions_pbuffer_size) { + buffer[i] = pie_sessions_pbuffer[offset + i]; + printlen++; + } else { + *eof = 1; + break; + } + } + return printlen; +} diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_proto_icmp.c linux-2.6.27.8-hippie/net/hippie/pie_proto_icmp.c --- linux-2.6.27.8/net/hippie/pie_proto_icmp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_proto_icmp.c 2008-03-17 14:27:02.000000000 -0500 @@ -0,0 +1,473 @@ +/* + * Hi-Performance Protocol Identification Engine ICMP Protocol Handling Code - pie_proto_icmp.c + * $Id: pie_proto_icmp.c,v 1.21 2008/03/17 19:27:02 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef CONFIG_HIPPIE_PREDICTION +#include +#endif +#include +#include + +u_int16_t pie_proto_icmp_fd = 0; +u_int16_t pie_proto_ipv4_fd_icmp; + +u_int8_t pie_icmp_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess, u_int8_t direction) { + /*if (sess == NULL && pkthdr == NULL) { + printk(KERN_ALERT "HiPPIE: ICMP Session Compare caught NULL session or packet header.\n"); + return 0; + }*/ + struct pie_protosess_icmp *icmpsess = (struct pie_protosess_icmp *) sess->proto_info; + struct pie_protohdr_icmp *icmphdr = (struct pie_protohdr_icmp *) pkthdr->proto_info; + /*if (icmpsess == NULL || icmphdr == NULL) { + printk(KERN_ALERT "HiPPIE: ICMP Session Compare caught NULL packet header or session header.\n"); + return 0; + }*/ + switch (icmphdr->type) { + /* Error messages */ + case 3: + /* Destination Unreachable */ + if (icmpsess->type == icmphdr->type) { + return 1; + } + break; + case 4: + /* Source Quench */ + if (icmpsess->type == icmphdr->type) { + return 1; + } + break; + case 5: + /* Redirect */ + if (icmpsess->type == icmphdr->type) { + return 1; + } + break; + case 11: + /* TTL Expired */ + if (icmpsess->type == icmphdr->type) { + return 1; + } + break; + case 12: + /* Parameter Problem */ + if (icmpsess->type == icmphdr->type) { + return 1; + } + break; + /* Information/Query messages */ + case 0: + /* Echo Reply */ + if (icmpsess->type == 8 || icmpsess->type == 0) { + return 1; + } + break; + case 8: + /* Echo Request */ + if (icmpsess->type == 8 || icmpsess->type == 0) { + return 1; + } + break; + case 9: + /* Router Advertisement */ + if (icmpsess->type == 9 || icmpsess->type == 10) { + return 1; + } + break; + case 10: + /* Router soliciation */ + if (icmpsess->type == 9 || icmpsess->type == 10) { + return 1; + } + break; + case 13: + /* Timestamp Request */ + if (icmpsess->type == 13 || icmpsess->type == 14) { + return 1; + } + break; + case 14: + /* Timestamp Reply */ + if (icmpsess->type == 13 || icmpsess->type == 14) { + return 1; + } + break; + case 15: + /* Information Request */ + if (icmpsess->type == 15 || icmpsess->type == 16) { + return 1; + } + break; + case 16: + /* Information Reply */ + if (icmpsess->type == 15 || icmpsess->type == 16) { + return 1; + } + break; + case 17: + /* Address Mask Request */ + if (icmpsess->type == 17 || icmpsess->type == 18) { + return 1; + } + break; + case 18: + /* Address Mask Reply */ + if (icmpsess->type == 17 || icmpsess->type == 18) { + return 1; + } + break; + case 30: + /* Enchanced Traceroute */ + if (icmpsess->type == 30) { + return 1; + } + break; + } + return 0; +} + +struct pie_protocol_sess *pie_icmp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_icmp *icmpsess; + struct pie_protohdr_icmp *icmphdr = (struct pie_protohdr_icmp *) pkthdr->proto_info; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for ICMP session header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_icmp_fd; + sess->next_sess = NULL; + icmpsess = kmalloc(sizeof(struct pie_protosess_icmp),GFP_KERNEL); + if (icmpsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for ICMP session information.\n"); + kfree(sess); + return NULL; + } + icmpsess->type = icmphdr->type; + sess->proto_info = (void *)icmpsess; + return sess; +} + +int pie_icmp_proc_packet(struct pie_sess_info *sess, struct pie_protocol_hdr *pkthdr) { + struct pie_protohdr_icmp *icmpinfo = (struct pie_protohdr_icmp *)pkthdr->proto_info; + read_lock(sess->lock); + if (icmpinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Proc_packet on ICMP packet with no ICMP info!\n"); + return -1; + } + if (icmpinfo->type == 3) { + /* Destination Unreachable Message - Terminate the contained session */ + struct pie_packet_info *original = pie_packet_mockup(pkthdr->data,pkthdr->datalen); + if (original->session == NULL) { + //printk(KERN_ALERT "HiPPIE: Received ICMP Termination message for session that cannot be found.\n"); + } else { + //printk(KERN_INFO "HiPPIE: Terminating session ID %d upon receiving ICMP error message.\n",original->session->sessid); + atomic_set(&original->session->state,PIE_STATE_EXTERNAL_TERM); + pie_session_timeout_reset(original->session,PIE_STATE_TIMEOUT_EXTERNAL_TERM); + } + } + pie_session_timeout_reset(sess,PIE_STATE_TIMEOUT_ICMP); + atomic_set(&sess->state,PIE_STATE_ICMP); + read_unlock(sess->lock); + return 0; +} + +int pie_icmp_ipv4find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr == NULL) { + /* This shouldn't ever happen! */ + printk(KERN_ALERT "HiPPIE: ICMP IPv4 Packet detection was passed a NULL header.\n"); + return 0; + } + if (curhdr->protoindex == pie_proto_ipv4_fd_icmp) { + struct pie_protohdr_ipv4 *ipv4hdr = (struct pie_protohdr_ipv4 *) curhdr->proto_info; + //printk(KERN_INFO "HiPPIE: ICMP Packet - %.02x\n",ipv4hdr); + if (ipv4hdr != NULL && ipv4hdr->proto == 1) { + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_icmp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *icmp_hdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + struct pie_protohdr_icmp *protoinfo; + if (icmp_hdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate ICMP Session Header Information.\n"); + return NULL; + } + icmp_hdr->protoindex = pie_proto_icmp_fd; + + if (curhdr == NULL) { + /* This should NEVER happen */ + printk(KERN_INFO "HiPPIE: ICMP - This should never happen.\n"); + kfree(icmp_hdr); + return NULL; + } + icmp_hdr->header = curhdr->data; + icmp_hdr->hlen = 8; + icmp_hdr->datalen = curhdr->datalen - icmp_hdr->hlen; + if (icmp_hdr->datalen > 0) { + icmp_hdr->data = &curhdr->data[icmp_hdr->hlen]; + } else { + icmp_hdr->data = NULL; + } + icmp_hdr->next_hdr = NULL; + protoinfo = kmalloc(sizeof(struct pie_protohdr_icmp),GFP_KERNEL); + if (protoinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate ICMP Session Information.\n"); + kfree(icmp_hdr); + return NULL; + } + protoinfo->type = icmp_hdr->header[0]; + protoinfo->code = icmp_hdr->header[1]; + protoinfo->chksum = make_int16(&icmp_hdr->header[2]); + protoinfo->ident = make_int16(&icmp_hdr->header[4]); + protoinfo->sequence = make_int16(&icmp_hdr->header[6]); + //protoinfo->chksum = icmp_hdr->header[2] * 256 + icmp_hdr->header[3]; + //protoinfo->ident = icmp_hdr->header[4] * 256 + icmp_hdr->header[5]; + //protoinfo->sequence = icmp_hdr->header[6] * 256 + icmp_hdr->header[7]; + icmp_hdr->proto_info = protoinfo; + return icmp_hdr; +} + +int pie_icmp_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer) { + struct pie_protosess_icmp *icmpinfo = (struct pie_protosess_icmp *) psess->proto_info; + int len = 0; + switch (icmpinfo->type) { + /* Error Messages */ + case 3: + /* Destination Unreachable */ + len += sprintf(buffer+len,"type: Destination Unreachable(3)"); + break; + case 4: + /* Source Quench */ + len += sprintf(buffer+len,"type: Source Quench(4)"); + break; + case 5: + /* Redirect */ + len += sprintf(buffer+len,"type: Redirect(5)"); + break; + case 11: + /* TTL Expired */ + len += sprintf(buffer+len,"type: TTL Expired(11)"); + break; + case 12: + /* Parameter Problem */ + len += sprintf(buffer+len,"type: Parameter Problem(12)"); + break; + /* Informational/Query Messages */ + case 0: + /* Echo Reply */ + len += sprintf(buffer+len,"type: Echo Reply(0)"); + break; + case 8: + /* Echo Request */ + len += sprintf(buffer+len,"type: Echo Request(8)"); + break; + case 9: + /* Router Advertisement */ + len += sprintf(buffer+len,"type: Router Advertisement(9)"); + break; + case 10: + /* Router Solicitation */ + len += sprintf(buffer+len,"type: Router Solicit(10)"); + break; + case 13: + /* Timestamp Request */ + len += sprintf(buffer+len,"type: Timestamp(13)"); + break; + case 14: + /* Timestamp Reply */ + len += sprintf(buffer+len,"type: Timestamp Reply(14)"); + break; + case 15: + /* Information Request */ + len += sprintf(buffer+len,"type: Info Request(15)"); + break; + case 16: + /* Information Reply */ + len += sprintf(buffer+len,"type: Info Reply(16)"); + break; + case 17: + /* Addr Mask Requst */ + len += sprintf(buffer+len,"type: Addr Mask Req(17)"); + break; + case 18: + /* Addr Mask Reply */ + len += sprintf(buffer+len,"type: Addr Mask Reply(18)"); + break; + case 30: + /* Enhanced Traceroute */ + len += sprintf(buffer+len,"type: Advanced Traceroute(30)"); + break; + } + return len; +} + +/*struct pie_protocol_sess *pie_icmp_create_predict(void) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_icmp *icmpsess; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for TCP session header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_icmp_fd; + sess->next_sess = NULL; + icmpsess = kmalloc(sizeof(struct pie_protosess_icmp),GFP_KERNEL); + if (icmpsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for TCP session information.\n"); + kfree(sess); + return NULL; + } + icmpsess->sport = 0; + icmpsess->dport = 0; + sess->proto_info = (void *) icmpsess; + return sess; +}*/ + +/*u_int8_t pie_icmp_add_predict_option(struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data) { + struct pie_protosess_icmp *icmpsess = hdr->proto_info; + if (strcmp(name,"sport") == 0) { + if (dtype == PIE_DTYPE_NUM) { + icmpsess->sport = (int) data; + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received TCP source port in unknown format.\n"); + return 0; + } + } + if (strcmp(name,"dport") == 0) { + if (dtype == PIE_DTYPE_NUM) { + icmpsess->dport = (int) data; + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received TCP destination port in unknown format.\n"); + return 0; + } + } + printk(KERN_INFO "HiPPIE: TCP add_predict_option failed to gobble parameter %s with dtype %d.\n",name,dtype); + return 0; +}*/ + +/*u_int8_t pie_icmp_validate_prediction(struct pie_protocol_sess *hdr) { + struct pie_protosess_icmp *icmpsess = hdr->proto_info; + if (icmpsess->sport != 0 || icmpsess->dport != 0) { + return 1; + } + printk(KERN_INFO "HiPPIE: TCP prediction header failed to validation because neither the source nor destination ports were set.\n"); + return 0; +}*/ + +/*u_int8_t pie_icmp_convert_prediction(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess) { + struct pie_protosess_icmp *sessinfo = sess->proto_info; + struct pie_protohdr_icmp *hdrinfo = pkthdr->proto_info; + sessinfo->sport = hdrinfo->sport; + sessinfo->dport = hdrinfo->dport; + return 1; +}*/ + +u_int8_t pie_icmp_get_sess_bucket(struct pie_protocol_hdr *pkthdr, u_int8_t direction) { + struct pie_protohdr_icmp *icmphdr = (struct pie_protohdr_icmp *) pkthdr->proto_info; + if (icmphdr != NULL) { + switch (icmphdr->type) { + /* Error Messages */ + case 3: + case 4: + case 5: + case 11: + case 12: + return icmphdr->chksum % 256; + break; + /* Informational/Query Messages */ + case 0: + /* Echo Reply */ + //return 0; + return (icmphdr->ident % 16) * 16 + ((icmphdr->ident / 256) % 16); + break; + case 8: + /* Echo Request */ + //return 0; + return (icmphdr->ident % 16) * 16 + ((icmphdr->ident / 256) % 16); + break; + case 9: + /* Router Advertisement */ + return 9; + break; + case 10: + /* Router Solicitation */ + return 9; + break; + case 13: + /* Timestamp Request */ + return 13; + break; + case 14: + /* Timestamp Reply */ + return 13; + break; + case 15: + /* Information Request */ + return 15; + break; + case 16: + /* Information Reply */ + return 15; + break; + case 17: + /* Address Mask Request */ + return 17; + break; + case 18: + /* Address Mask Reply */ + return 18; + break; + case 30: + /* Enhanced Traceroute */ + return 30; + break; + } + } + return 0; +} + +void pie_icmp_session_cleanup(struct pie_protocol_sess *sess) { + struct pie_protosess_icmp *icmpsess = (struct pie_protosess_icmp *) sess->proto_info; + kfree(icmpsess); + kfree(sess); +} + +void pie_icmp_packet_cleanup(struct pie_protocol_hdr *hdr) { + struct pie_protohdr_icmp *icmphdr = (struct pie_protohdr_icmp *) hdr->proto_info; + kfree(icmphdr); + kfree(hdr); +} + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("Hi-Performance Protocol Identification Engine ICMP Protocol Packet Analysis and Sessioning Handler"); +MODULE_LICENSE("GPL"); + +static int __init init(void) { + pie_proto_icmp_fd = pie_reg_protocol("icmp",PIE_PROTOTYPE_TRANSPORT,PIE_ENCAP_TAGGED,0,&pie_icmp_get_sess_bucket,&pie_icmp_session_compare,&pie_icmp_new_session,&pie_icmp_packet_mockup,NULL,NULL,NULL,NULL,&pie_icmp_proc_packet,&pie_icmp_proc_print,&pie_icmp_session_cleanup,&pie_icmp_packet_cleanup); + pie_reg_subprotocol("ipv4",pie_proto_icmp_fd,&pie_icmp_ipv4find); + pie_proto_ipv4_fd_icmp = pie_get_protocolid("ipv4"); + return 0; +} + +static void __exit fini(void) { + pie_unreg_protocol("icmp",pie_proto_icmp_fd); +} + +module_init(init); +module_exit(fini); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_proto_ipv4.c linux-2.6.27.8-hippie/net/hippie/pie_proto_ipv4.c --- linux-2.6.27.8/net/hippie/pie_proto_ipv4.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_proto_ipv4.c 2008-03-17 14:27:02.000000000 -0500 @@ -0,0 +1,378 @@ +/* + * Hi-Performance Protocol Identification Engine IP Version 4 Protocol Handling Code - pie_proto_ipv4.c + * $Id: pie_proto_ipv4.c,v 1.16 2008/03/17 19:27:02 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +u_int16_t pie_proto_ipv4_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("Hi-Performance Protocol Identification Engine IPv4 Protocol Packet Analysis and Sessioning Handler"); +MODULE_LICENSE("GPL"); + +/* IP Header Checksum */ +u_int16_t pie_checksum_calc(u_int16_t bytes, u_int8_t *header) { + u_int16_t word; + u_int32_t chksum = 0; + u_int16_t i; + + for (i = 0; i < bytes / 2; i++) { + if (i != 5) { + /* Ignore the checksum location */ + word = make_int16(&header[2 * i]); + //word = header[2 * i] * 256 + header[2 * i + 1]; + chksum += word; + } + } + word = 0xFFFF - (chksum / 65536 + chksum % 65536); + return word; +} + +char *pie_ipv4_addr_read(char *start, u_int8_t format, u_int8_t iparray[]) { + /* Formats: + * 0 = Straight text x.x.x.x + * 1 = Comma separated x,x,x,x + * 2 = Integer x + */ + char *search = start; + int i = 0; + u_int32_t addr = 0; + switch (format) { + case 0: + case 1: + for (i = 0;i < 4; i++) { + iparray[i] = simple_strtoul(search,&search,10); + if (i < 3) { + search++; + } + } + return search; + break; + case 2: + addr = simple_strtoul(search,&search,10); + for (i = 3;i >= 0; i--) { + iparray[i] = addr % 256; + addr = addr / 256; + } + break; + default: + return start; + } + return search; +} + +u_int8_t pie_ipv4_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess, u_int8_t direction) { + struct pie_protosess_ipv4 *ipsess = (struct pie_protosess_ipv4 *) sess->proto_info; + struct pie_protohdr_ipv4 *iphdr = (struct pie_protohdr_ipv4 *) pkthdr->proto_info; + int i; + switch (direction) { + case 0: + for (i = 3; i >= 0; i--) { + if (ipsess->srcip[i] != iphdr->srcip[i]) { + return 0; + } + if (ipsess->dstip[i] != iphdr->dstip[i]) { + return 0; + } + } + break; + case 1: + for (i = 3; i >= 0; i--) { + if (ipsess->srcip[i] != iphdr->dstip[i]) { + return 0; + } + if (ipsess->dstip[i] != iphdr->srcip[i]) { + return 0; + } + } + break; + case 2: + for (i = 3; i >= 0; i--) { + if (ipsess->srcip[i] != 0 && ipsess->srcip[i] != iphdr->srcip[i]) { + return 0; + } + if (ipsess->dstip[i] != 0 && ipsess->dstip[i] != iphdr->dstip[i]) { + return 0; + } + } + break; + default: + return 0; + break; + } + return 1; +} + +struct pie_protocol_sess *pie_ipv4_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_ipv4 *ipsess; + struct pie_protohdr_ipv4 *iphdr = (struct pie_protohdr_ipv4 *) pkthdr->proto_info; + int i; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for IPv4 Session Header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_ipv4_fd; + sess->next_sess = NULL; + ipsess = kmalloc(sizeof(struct pie_protosess_ipv4),GFP_KERNEL); + if (ipsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for IPv4 Session information.\n"); + kfree(sess); + return NULL; + } + ipsess->proto = iphdr->proto; + for (i = 0; i < 4;i++) { + ipsess->srcip[i] = iphdr->srcip[i]; + ipsess->dstip[i] = iphdr->dstip[i]; + } + sess->proto_info = (void *) ipsess; + return sess; +} + +struct pie_protocol_sess *pie_ipv4_create_predict(void) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_ipv4 *ipsess; + int i; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for IPv4 Session Header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_ipv4_fd; + sess->next_sess = NULL; + ipsess = kmalloc(sizeof(struct pie_protosess_ipv4),GFP_KERNEL); + if (ipsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for IPv4 Session information.\n"); + kfree(sess); + return NULL; + } + ipsess->proto = 0; + for (i = 0; i < 4;i++) { + ipsess->srcip[i] = 0; + ipsess->dstip[i] = 0; + } + sess->proto_info = (void *) ipsess; + return sess; +} + +u_int8_t pie_ipv4_add_predict_option(struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data) { + struct pie_protosess_ipv4 *ipsess = hdr->proto_info; + int i; + if (strcmp(name,"proto") == 0) { + /* Need to convert this to a number and store in proto */ + if (dtype == PIE_DTYPE_NUM) { + ipsess->proto = (int) data; + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received IPv4 protocol in unknown format.\n"); + return 0; + } + } + if (strcmp(name,"src") == 0) { + /* Need to convert this to a number and store in srcip */ + if (dtype == PIE_DTYPE_POINTER) { + for (i = 0; i < 4;i++) { + ipsess->srcip[i] = ((u_int8_t *) data)[i]; + } + return 1; + } else if (dtype == PIE_DTYPE_CHAR) { + pie_ipv4_addr_read(data,0,ipsess->srcip); + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received IPv4 source address in unknown format.\n"); + return 0; + } + } + if (strcmp(name,"dst") == 0) { + /* Need to convert this to a number and store in dstip */ + if (dtype == PIE_DTYPE_POINTER) { + for (i = 0; i < 4;i++) { + ipsess->dstip[i] = ((u_int8_t *) data)[i]; + } + return 1; + } else if (dtype == PIE_DTYPE_CHAR) { + pie_ipv4_addr_read(data,0,ipsess->dstip); + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received IPv4 dest address in unknown format.\n"); + return 0; + } + } + printk(KERN_INFO "HiPPIE: IPv4 add_predict_option failed to gobble parameter %s with dtype %d.\n",name,dtype); + return 0; +} + +u_int8_t pie_ipv4_validate_prediction(struct pie_protocol_sess *hdr) { + struct pie_protosess_ipv4 *ipsess = hdr->proto_info; + if (ipsess->proto != 0) { + if (ipsess->srcip[0] == 0 && ipsess->srcip[1] == 0 && ipsess->srcip[2] == 0 && ipsess->srcip[3] == 0) { + if (ipsess->dstip[0] == 0 && ipsess->dstip[1] == 0 && ipsess->dstip[2] == 0 && ipsess->dstip[3] == 0) { + printk(KERN_INFO "HiPPIE: IPv4 prediction header failed validation neither address was set.\n"); + return 0; + } else { + return 1; + } + } else { + return 1; + } + } else { + printk(KERN_INFO "HiPPIE: IPv4 prediction header failed validation because IP protocol was not set."); + return 0; + } +} + +u_int8_t pie_ipv4_convert_prediction(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess) { + /* This function needs to put the source and dest addresses of the packet into the source and dest addresses of the session. */ + struct pie_protosess_ipv4 *sessinfo = sess->proto_info; + struct pie_protohdr_ipv4 *hdrinfo = pkthdr->proto_info; + int i; + for (i = 0; i < 4; i++) { + sessinfo->srcip[i] = hdrinfo->srcip[i]; + sessinfo->dstip[i] = hdrinfo->dstip[i]; + } + return 1; +} + +int pie_ipv4_null_find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* WARNING! curhdr should be NULL here... */ + /* There is currently no ethernet or other header already realized... */ + if (pktinfo->rawpacket[0] / 16 == 0x4) { + /* This could be IPv4 Traffic */ + /* Do a checksum check */ + u_int16_t chk = make_int16(&pktinfo->rawpacket[10]); + u_int16_t csum = pie_checksum_calc(pktinfo->rawpacket[0] % 16 * 4, pktinfo->rawpacket); + if (csum == chk) { + /* IP Header Checksum Passes */ + return 1; + } + } + return 0; +} + +int pie_ipv4_nonnull_find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* Check the data section of the last header to see if it's IPv4 data */ + if (curhdr->data[0] / 16 == 0x4) { + /* This could be IPv4 Traffic */ + /* Do a checksum check */ + u_int8_t chk1 = pktinfo->rawpacket[10]; + u_int8_t chk2 = pktinfo->rawpacket[11]; + if (pie_checksum_calc(pktinfo->rawpacket[0] % 16 * 4, pktinfo->rawpacket) == chk1 * 256 + chk2) { + /* IP Header Checksum Passes */ + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_ipv4_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *ipv4_hdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + int i; + struct pie_protohdr_ipv4 *protoinfo; + if (ipv4_hdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate IPv4 packet protocol headaer.\n"); + return NULL; + } + ipv4_hdr->protoindex = pie_proto_ipv4_fd; + + if (curhdr == NULL) { + ipv4_hdr->header = pktinfo->rawpacket; + } else { + ipv4_hdr->header = curhdr->data; + } + ipv4_hdr->hlen = ipv4_hdr->header[0] % 16 * 4; + ipv4_hdr->data = &ipv4_hdr->header[ipv4_hdr->hlen]; + u_int16_t iplen = make_int16(&ipv4_hdr->header[2]); + if (curhdr == NULL) { + if (pktinfo->plen <= iplen) { + ipv4_hdr->datalen = pktinfo->plen - ipv4_hdr->hlen; + } else { + ipv4_hdr->datalen = make_int16(&ipv4_hdr->header[2]) - ipv4_hdr->hlen; + } + } else { + if (curhdr->datalen <= iplen) { + ipv4_hdr->datalen = curhdr->datalen - ipv4_hdr->hlen; + } else { + ipv4_hdr->datalen = iplen- ipv4_hdr->hlen; + } + } + ipv4_hdr->next_hdr = NULL; + protoinfo = kmalloc(sizeof(struct pie_protohdr_ipv4),GFP_KERNEL); + protoinfo->hlen = ipv4_hdr->hlen; + protoinfo->totlen = make_int16(&ipv4_hdr->header[2]); + //protoinfo->totlen = ipv4_hdr->header[2] * 256 + ipv4_hdr->header[3]; + protoinfo->ttl = ipv4_hdr->header[8]; + protoinfo->proto = ipv4_hdr->header[9]; + for (i = 0;i < 4;i++) { + protoinfo->srcip[i] = ipv4_hdr->header[12 + i]; + protoinfo->dstip[i] = ipv4_hdr->header[16 + i]; + } + ipv4_hdr->proto_info = protoinfo; + //printk(KERN_INFO "HiPPIE: TCP Packet with hlen %u, datalen %u, totlen %u, ttl %u, protocol %u.\n",ipv4_hdr->hlen + return ipv4_hdr; +} + +u_int8_t pie_ipv4_get_sess_bucket(struct pie_protocol_hdr *pkthdr, u_int8_t direction) { + struct pie_protohdr_ipv4 *iphdr = (struct pie_protohdr_ipv4 *) pkthdr->proto_info; + switch (direction) { + case 0: + //return iphdr->dstip[3]; + return (iphdr->srcip[3] % 16) * 16 + (iphdr->dstip[3] % 16); + //return (iphdr->srcip[2] % 16) * 16 + (iphdr->srcip[3] % 16); + break; + case 1: + //return iphdr->srcip[3]; + return (iphdr->dstip[3] % 16) * 16 + (iphdr->srcip[3] % 16); + //return (iphdr->dstip[2] % 16) * 16 + (iphdr->dstip[3] % 16); + break; + } + return 0; +} + +int pie_ipv4_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer) { + struct pie_protosess_ipv4 *ipv4info = (struct pie_protosess_ipv4 *) psess->proto_info; + int len = 0; + len += sprintf(buffer+len,"src %u.%u.%u.%u dst %u.%u.%u.%u proto %u",ipv4info->srcip[0],ipv4info->srcip[1],ipv4info->srcip[2],ipv4info->srcip[3],ipv4info->dstip[0],ipv4info->dstip[1],ipv4info->dstip[2],ipv4info->dstip[3],ipv4info->proto); + return len; +} + +void pie_ipv4_session_cleanup(struct pie_protocol_sess *sess) { + struct pie_protosess_ipv4 *ipsess = (struct pie_protosess_ipv4 *) sess->proto_info; + kfree(ipsess); + kfree(sess); +} + +void pie_ipv4_packet_cleanup(struct pie_protocol_hdr *hdr) { + struct pie_protohdr_ipv4 *iphdr = (struct pie_protohdr_ipv4 *) hdr->proto_info; + kfree(iphdr); + kfree(hdr); +} + +static int __init init(void) { + pie_proto_ipv4_fd = pie_reg_protocol("ipv4",PIE_PROTOTYPE_NETWORK,PIE_ENCAP_TAGGED,0,&pie_ipv4_get_sess_bucket,&pie_ipv4_session_compare,&pie_ipv4_new_session,&pie_ipv4_packet_mockup,&pie_ipv4_create_predict,&pie_ipv4_add_predict_option,&pie_ipv4_validate_prediction,&pie_ipv4_convert_prediction,NULL,&pie_ipv4_proc_print,&pie_ipv4_session_cleanup,&pie_ipv4_packet_cleanup); + /* Check if IPv4 is the first packet */ + pie_reg_subprotocol("[root]",pie_proto_ipv4_fd,&pie_ipv4_null_find); + /* Check if IPv4 is under ethernet */ + //pie_reg_subprotocol("ethernet",pie_proto_ipv4_fd,&pie_ipv4_nonnull_find); + return 0; +} + +static void __exit fini(void) { + pie_unreg_protocol("ipv4",pie_proto_ipv4_fd); +} + +module_init(init); +module_exit(fini); +EXPORT_SYMBOL(pie_ipv4_addr_read); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_proto_tcp.c linux-2.6.27.8-hippie/net/hippie/pie_proto_tcp.c --- linux-2.6.27.8/net/hippie/pie_proto_tcp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_proto_tcp.c 2008-03-17 14:27:02.000000000 -0500 @@ -0,0 +1,334 @@ +/* + * Hi-Performance Protocol Identification Engine TCP Protocol Handling Code - pie_proto_tcp.c + * $Id: pie_proto_tcp.c,v 1.16 2008/03/17 19:27:02 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +u_int16_t pie_proto_tcp_fd = 0; +u_int16_t pie_proto_ipv4_fd_tcp; + +u_int8_t pie_tcp_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess, u_int8_t direction) { + struct pie_protosess_tcp *tcpsess = (struct pie_protosess_tcp *) sess->proto_info; + struct pie_protohdr_tcp *tcphdr = (struct pie_protohdr_tcp *) pkthdr->proto_info; + switch (direction) { + case 0: + if (tcpsess->sport == tcphdr->sport && tcpsess->dport == tcphdr->dport) { + return 1; + } + return 0; + case 1: + if (tcpsess->sport == tcphdr->dport && tcpsess->dport == tcphdr->sport) { + return 1; + } + return 0; + case 2: + /* Predicted Session */ + if ((tcpsess->sport == 0 || tcpsess->sport == tcphdr->sport) && (tcpsess->dport == 0 || tcpsess->dport == tcphdr->dport)) { + return 1; + } + return 0; + } + return 0; +} + +struct pie_protocol_sess *pie_tcp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_tcp *tcpsess; + struct pie_protohdr_tcp *tcphdr = (struct pie_protohdr_tcp *) pkthdr->proto_info; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for TCP session header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_tcp_fd; + sess->next_sess = NULL; + tcpsess = kmalloc(sizeof(struct pie_protosess_tcp),GFP_KERNEL); + if (tcpsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for TCP session information.\n"); + kfree(sess); + return NULL; + } + tcpsess->sport = tcphdr->sport; + tcpsess->dport = tcphdr->dport; + sess->proto_info = (void *) tcpsess; + return sess; +} + +int pie_tcp_proc_packet(struct pie_sess_info *session, struct pie_protocol_hdr *pkthdr) { + struct pie_protohdr_tcp *tcpinfo = (struct pie_protohdr_tcp *)pkthdr->proto_info; + int lostconn = 0; + read_lock(session->lock); + if (atomic_read(&session->state) == PIE_STATE_TCP_NORMAL && tcpinfo->tcpflags != 0x11 && tcpinfo->tcpflags != 0x01 && tcpinfo->tcpflags != 0x04 && tcpinfo->tcpflags != 0x14) { + /* Session is still normal, quickpass this */ + } else if (tcpinfo->tcpflags == 0x02 && atomic_read(&session->state) == PIE_STATE_NEW) { + /* Packet is SYN and UNKNOWN (likely new) state. */ + /* Session is just beginning */ + atomic_set(&session->state,PIE_STATE_TCP_SYN); + } else if (tcpinfo->tcpflags == 0x12 && atomic_read(&session->state) == PIE_STATE_TCP_SYN) { + /* Packet is SYN+ACK and state is SYN */ + /* SYN was ACKED */ + atomic_set(&session->state,PIE_STATE_TCP_SYNACK); + } else if (tcpinfo->tcpflags == 0x10 && atomic_read(&session->state) == PIE_STATE_TCP_SYNACK) { + /* Packet is ACK and state is SYN+ACK */ + /* Handshake complete */ + atomic_set(&session->state,PIE_STATE_TCP_NORMAL); + } else if ((tcpinfo->tcpflags == 0x11 || tcpinfo->tcpflags == 0x01) && atomic_read(&session->state) == PIE_STATE_TCP_NORMAL) { + /* Packet is FIN */ + /* Begin Closing Session */ + atomic_set(&session->state,PIE_STATE_TCP_FIN); + } else if (tcpinfo->tcpflags == 0x11 && atomic_read(&session->state) == PIE_STATE_TCP_FIN) { + /* Packet is FIN+ACK and state FIN */ + /* Close session */ + atomic_set(&session->state,PIE_STATE_TCP_CLOSED); + } else if (tcpinfo->tcpflags == 0x10 && atomic_read(&session->state) == PIE_STATE_TCP_CLOSED) { + /* ACK to a FIN+ACK */ + /* Leave as CLOSED */ + } else if (tcpinfo->tcpflags == 0x04 || tcpinfo->tcpflags == 0x14) { + /* Packet is RST */ + /* Close session */ + atomic_set(&session->state,PIE_STATE_TCP_CLOSED); + } else if ((tcpinfo->tcpflags == 0x18 || tcpinfo->tcpflags == 0x10) && atomic_read(&session->state) == PIE_STATE_NEW) { + /* Lost the connection mid session - resume to normal */ + atomic_set(&session->state,PIE_STATE_TCP_NORMAL); + lostconn = 1; + } else { + //printk(KERN_DEBUG "HiPPIE: TCP_proc_packet unknown info Session ID: %d State: %d TCP Flags Octet: %x\n",session->sessid,atomic_read(&session->state),tcpinfo->tcpflags); + } + switch (atomic_read(&session->state)) { + case PIE_STATE_TCP_SYN: + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_TCP_SYN); + break; + case PIE_STATE_TCP_SYNACK: + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_TCP_SYNACK); + break; + case PIE_STATE_TCP_NORMAL: + if (lostconn) { + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_TCP_UNKNOWN); + } else { + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_TCP_NORMAL); + } + break; + case PIE_STATE_TCP_FIN: + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_TCP_CLOSED); + break; + case PIE_STATE_TCP_CLOSED: + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_TCP_CLOSED); + break; + case PIE_STATE_TCP_UNKNOWN: + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_TCP_UNKNOWN); + break; + default: + pie_session_timeout_reset(session,15); + break; + } + read_unlock(session->lock); + return 0; +} + +int pie_tcp_ipv4find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr == NULL) { + /* This shouldn't ever happen! */ + printk(KERN_ALERT "HiPPIE: TCP IPv4 Packet detection was passed a NULL header.\n"); + return 0; + } + if (curhdr->protoindex == pie_proto_ipv4_fd_tcp) { + struct pie_protohdr_ipv4 *ipv4hdr = (struct pie_protohdr_ipv4 *) curhdr->proto_info; + if (ipv4hdr != NULL && ipv4hdr->proto == 6) { + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_tcp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *tcp_hdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + struct pie_protohdr_tcp *protoinfo; + if (tcp_hdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate TCP Session Header Information.\n"); + return NULL; + } + tcp_hdr->protoindex = pie_proto_tcp_fd; + + if (curhdr == NULL) { + /* This should NEVER happen */ + printk(KERN_ALERT "HiPPIE: TCP Mockup received a NULL protocol header!\n"); + return NULL; + } + tcp_hdr->header = curhdr->data; + tcp_hdr->hlen = tcp_hdr->header[12] / 16 * 4; + tcp_hdr->datalen = curhdr->datalen - tcp_hdr->hlen; + if (tcp_hdr->datalen > 0) { + tcp_hdr->data = &curhdr->data[tcp_hdr->hlen]; + } else { + tcp_hdr->data = NULL; + } + tcp_hdr->next_hdr = NULL; + protoinfo = kmalloc(sizeof(struct pie_protohdr_tcp),GFP_KERNEL); + if (protoinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate TCP Session Information.\n"); + kfree(tcp_hdr); + return NULL; + } + protoinfo->hlen = tcp_hdr->hlen; + protoinfo->sport = make_int16(&tcp_hdr->header[0]); + protoinfo->dport = make_int16(&tcp_hdr->header[2]); + protoinfo->tcpflags = tcp_hdr->header[13]; + tcp_hdr->proto_info = protoinfo; + return tcp_hdr; +} + +int pie_tcp_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer) { + struct pie_protosess_tcp *tcpinfo = (struct pie_protosess_tcp *) psess->proto_info; + if (tcpinfo == NULL) { + printk(KERN_ALERT "HiPPIE: TCP session is missing session information!\n"); + return 0; + } + int len = 0; + len += sprintf(buffer+len,"sport %u dport: %u",tcpinfo->sport,tcpinfo->dport); + switch(atomic_read(&sess->state)) { + case PIE_STATE_TCP_SYN: + len += sprintf(buffer+len," state TCP_SYN"); + break; + case PIE_STATE_TCP_SYNACK: + len += sprintf(buffer+len," state TCP_SYNACK"); + break; + case PIE_STATE_TCP_NORMAL: + len += sprintf(buffer+len," state TCP_NORMAL"); + break; + case PIE_STATE_TCP_FIN: + len += sprintf(buffer+len," state TCP_FIN"); + break; + case PIE_STATE_TCP_CLOSED: + len += sprintf(buffer+len," state TCP_CLOSED"); + break; + case PIE_STATE_TCP_UNKNOWN: + len += sprintf(buffer+len," state TCP_UNKNOWN"); + break; + case PIE_STATE_PREDICTED: + len += sprintf(buffer+len," state Prediction"); + break; + } + return len; +} + +struct pie_protocol_sess *pie_tcp_create_predict(void) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_tcp *tcpsess; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for TCP session header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_tcp_fd; + sess->next_sess = NULL; + tcpsess = kmalloc(sizeof(struct pie_protosess_tcp),GFP_KERNEL); + if (tcpsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for TCP session information.\n"); + kfree(sess); + return NULL; + } + tcpsess->sport = 0; + tcpsess->dport = 0; + sess->proto_info = (void *) tcpsess; + return sess; +} + +u_int8_t pie_tcp_add_predict_option(struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data) { + struct pie_protosess_tcp *tcpsess = hdr->proto_info; + if (strcmp(name,"sport") == 0) { + /* Need to convert this to a number and store in sport */ + if (dtype == PIE_DTYPE_NUM) { + tcpsess->sport = (int) data; + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received TCP source port in unknown format.\n"); + return 0; + } + } + if (strcmp(name,"dport") == 0) { + /* Need to convert this to a number and store in dport. */ + if (dtype == PIE_DTYPE_NUM) { + tcpsess->dport = (int) data; + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received TCP destination port in unknown format.\n"); + return 0; + } + } + printk(KERN_INFO "HiPPIE: TCP add_predict_option failed to gobble parameter %s with dtype %d.\n",name,dtype); + return 0; +} + +u_int8_t pie_tcp_validate_prediction(struct pie_protocol_sess *hdr) { + struct pie_protosess_tcp *tcpsess = hdr->proto_info; + if (tcpsess->sport != 0 || tcpsess->dport != 0) { + return 1; + } + printk(KERN_INFO "HiPPIE: TCP prediction header failed to validation because neither the source nor destination ports were set.\n"); + return 0; +} + +u_int8_t pie_tcp_convert_prediction(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess) { + struct pie_protosess_tcp *sessinfo = sess->proto_info; + struct pie_protohdr_tcp *hdrinfo = pkthdr->proto_info; + sessinfo->sport = hdrinfo->sport; + sessinfo->dport = hdrinfo->dport; + return 1; +} + +u_int8_t pie_tcp_get_sess_bucket(struct pie_protocol_hdr *pkthdr, u_int8_t direction) { + struct pie_protohdr_tcp *tcphdr = (struct pie_protohdr_tcp *) pkthdr->proto_info; + switch (direction) { + case 0: + return tcphdr->sport % 256; + break; + case 1: + return tcphdr->dport % 256; + break; + } + return 0; +} + +void pie_tcp_session_cleanup(struct pie_protocol_sess *sess) { + struct pie_protosess_tcp *tcpsess = (struct pie_protosess_tcp *) sess->proto_info; + kfree(tcpsess); + kfree(sess); +} + +void pie_tcp_packet_cleanup(struct pie_protocol_hdr *hdr) { + struct pie_protohdr_tcp *tcphdr = (struct pie_protohdr_tcp *) hdr->proto_info; + kfree(tcphdr); + kfree(hdr); +} + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("Hi-Performance Protocol Identification Engine TCP Protocol Packet Analysis and Sessioning Handler"); +MODULE_LICENSE("GPL"); + +static int __init init(void) { + pie_proto_tcp_fd = pie_reg_protocol("tcp",PIE_PROTOTYPE_TRANSPORT,PIE_ENCAP_TAGGED,0,&pie_tcp_get_sess_bucket,&pie_tcp_session_compare,&pie_tcp_new_session,&pie_tcp_packet_mockup,&pie_tcp_create_predict,&pie_tcp_add_predict_option,&pie_tcp_validate_prediction,&pie_tcp_convert_prediction,&pie_tcp_proc_packet,&pie_tcp_proc_print,&pie_tcp_session_cleanup,&pie_tcp_packet_cleanup); + pie_reg_subprotocol("ipv4",pie_proto_tcp_fd,&pie_tcp_ipv4find); + pie_proto_ipv4_fd_tcp = pie_get_protocolid("ipv4"); + return 0; +} + +static void __exit fini(void) { + pie_unreg_protocol("tcp",pie_proto_tcp_fd); +} + +module_init(init); +module_exit(fini); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_proto_udp.c linux-2.6.27.8-hippie/net/hippie/pie_proto_udp.c --- linux-2.6.27.8/net/hippie/pie_proto_udp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_proto_udp.c 2008-03-17 14:27:02.000000000 -0500 @@ -0,0 +1,269 @@ +/* + * Hi-Performance Protocol Identification Engine UDP Protocol Handling Code - pie_proto_udp.c + * $Id: pie_proto_udp.c,v 1.20 2008/03/17 19:27:02 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +u_int16_t pie_proto_udp_fd = 0; +u_int16_t pie_proto_ipv4_fd_udp; + +u_int8_t pie_udp_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess, u_int8_t direction) { + struct pie_protosess_udp *udpsess = (struct pie_protosess_udp *) sess->proto_info; + struct pie_protohdr_udp *udphdr = (struct pie_protohdr_udp *) pkthdr->proto_info; + switch (direction) { + case 0: + if (udpsess->sport == udphdr->sport && udpsess->dport == udphdr->dport) { + return 1; + } + return 0; + case 1: + if (udpsess->sport == udphdr->dport && udpsess->dport == udphdr->sport) { + return 1; + } + return 0; + case 2: + /* Predicted Session */ + if ((udpsess->sport == 0 || udpsess->sport == udphdr->sport) && (udpsess->dport == udphdr->dport)) { + return 1; + } + return 0; + } + return 0; +} + +struct pie_protocol_sess *pie_udp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_udp *udpsess; + struct pie_protohdr_udp *udphdr = (struct pie_protohdr_udp *) pkthdr->proto_info; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for UDP session header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_udp_fd; + sess->next_sess = NULL; + udpsess = kmalloc(sizeof(struct pie_protosess_udp),GFP_KERNEL); + if (udpsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for UDP session information.\n"); + kfree(sess); + return NULL; + } + udpsess->sport = udphdr->sport; + udpsess->dport = udphdr->dport; + sess->proto_info = (void *) udpsess; + return sess; +} + +int pie_udp_proc_packet(struct pie_sess_info *sess, struct pie_protocol_hdr *pkthdr) { + //struct pie_protohdr_udp *udpinfo = (struct pie_protohdr_udp *)pkthdr->proto_info; + read_lock(sess->lock); + switch (atomic_read(&sess->state)) { + case PIE_STATE_NEW: + atomic_set(&sess->state,PIE_STATE_UDP_UNANS); + pie_session_timeout_reset(sess,PIE_STATE_TIMEOUT_UDP_UNANS); + break; + case PIE_STATE_UDP_UNANS: + pie_session_timeout_reset(sess,PIE_STATE_TIMEOUT_UDP_UNANS); + break; + case PIE_STATE_UDP_BIDIR: + pie_session_timeout_reset(sess,PIE_STATE_TIMEOUT_UDP_BIDIR); + break; + case PIE_STATE_EXTERNAL_TERM: + pie_session_timeout_reset(sess,PIE_STATE_TIMEOUT_EXTERNAL_TERM); + break; + default: + //printk(KERN_INFO "HiPPIE: UDP Packet in odd state: %d.\n",atomic_read(&sess->state)); + break; + } + read_unlock(sess->lock); + return 0; +} + +int pie_udp_ipv4find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr == NULL) { + /* This shouldn't ever happen! */ + printk(KERN_ALERT "HiPPIE: UDP IPv4 Packet detection was passed a NULL header.\n"); + return 0; + } + if (curhdr->protoindex == pie_proto_ipv4_fd_udp) { + struct pie_protohdr_ipv4 *ipv4hdr = (struct pie_protohdr_ipv4 *) curhdr->proto_info; + if (ipv4hdr != NULL && ipv4hdr->proto == 17) { + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_udp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *udp_hdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + struct pie_protohdr_udp *protoinfo; + if (udp_hdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate UDP Session Header Information.\n"); + return NULL; + } + udp_hdr->protoindex = pie_proto_udp_fd; + + if (curhdr == NULL) { + /* This should NEVER happen */ + printk(KERN_ALERT "HiPPIE: UDP header received a null header.\n"); + return NULL; + } + udp_hdr->header = curhdr->data; + udp_hdr->hlen = 8; + udp_hdr->datalen = curhdr->datalen - udp_hdr->hlen; + if (udp_hdr->datalen > 0) { + udp_hdr->data = &curhdr->data[udp_hdr->hlen]; + } else { + udp_hdr->data = NULL; + } + udp_hdr->next_hdr = NULL; + protoinfo = kmalloc(sizeof(struct pie_protohdr_udp),GFP_KERNEL); + if (protoinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate UDP Session Information.\n"); + kfree(udp_hdr); + return NULL; + } + protoinfo->sport = make_int16(&udp_hdr->header[0]); + protoinfo->dport = make_int16(&udp_hdr->header[2]); + udp_hdr->proto_info = protoinfo; + return udp_hdr; +} + +int pie_udp_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer) { + struct pie_protosess_udp *udpinfo = (struct pie_protosess_udp *) psess->proto_info; + int len = 0; + len += sprintf(buffer+len,"sport %u dport: %u",udpinfo->sport,udpinfo->dport); + switch(atomic_read(&sess->state)) { + case PIE_STATE_UDP_UNANS: + len += sprintf(buffer+len," State: UDP_UNANS"); + break; + case PIE_STATE_UDP_BIDIR: + len += sprintf(buffer+len," State: UDP_BIDIR"); + break; + } + return len; +} + +struct pie_protocol_sess *pie_udp_create_predict(void) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_udp *udpsess; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for TCP session header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_udp_fd; + sess->next_sess = NULL; + udpsess = kmalloc(sizeof(struct pie_protosess_udp),GFP_KERNEL); + if (udpsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for TCP session information.\n"); + kfree(sess); + return NULL; + } + udpsess->sport = 0; + udpsess->dport = 0; + sess->proto_info = (void *) udpsess; + return sess; +} + +u_int8_t pie_udp_add_predict_option(struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data) { + struct pie_protosess_udp *udpsess = hdr->proto_info; + if (strcmp(name,"sport") == 0) { + /* Need to convert this to a number and store in sport */ + if (dtype == PIE_DTYPE_NUM) { + udpsess->sport = (int) data; + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received TCP source port in unknown format.\n"); + return 0; + } + } + if (strcmp(name,"dport") == 0) { + /* Need to convert this to a number and store in dport. */ + if (dtype == PIE_DTYPE_NUM) { + udpsess->dport = (int) data; + return 1; + } else { + printk(KERN_INFO "HiPPIE: Prediction received TCP destination port in unknown format.\n"); + return 0; + } + } + printk(KERN_INFO "HiPPIE: TCP add_predict_option failed to gobble parameter %s with dtype %d.\n",name,dtype); + return 0; +} + +u_int8_t pie_udp_validate_prediction(struct pie_protocol_sess *hdr) { + struct pie_protosess_udp *udpsess = hdr->proto_info; + if (udpsess->sport != 0 || udpsess->dport != 0) { + return 1; + } + printk(KERN_INFO "HiPPIE: TCP prediction header failed to validation because neither the source nor destination ports were set.\n"); + return 0; +} + +u_int8_t pie_udp_convert_prediction(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess) { + struct pie_protosess_udp *sessinfo = sess->proto_info; + struct pie_protohdr_udp *hdrinfo = pkthdr->proto_info; + sessinfo->sport = hdrinfo->sport; + sessinfo->dport = hdrinfo->dport; + return 1; +} + +u_int8_t pie_udp_get_sess_bucket(struct pie_protocol_hdr *pkthdr, u_int8_t direction) { + struct pie_protohdr_udp *udphdr = (struct pie_protohdr_udp *) pkthdr->proto_info; + switch (direction) { + case 0: + return udphdr->sport % 256; + //return (udphdr->dport % 16) * 16 + (udphdr->sport % 16); + break; + case 1: + return udphdr->dport % 256; + //return (udphdr->sport % 16) * 16 + (udphdr->dport % 16); + break; + } + return 0; +} + +void pie_udp_session_cleanup(struct pie_protocol_sess *sess) { + struct pie_protosess_udp *udpsess = (struct pie_protosess_udp *) sess->proto_info; + kfree(udpsess); + kfree(sess); +} + +void pie_udp_packet_cleanup(struct pie_protocol_hdr *hdr) { + struct pie_protohdr_udp *udphdr = (struct pie_protohdr_udp *) hdr->proto_info; + kfree(udphdr); + kfree(hdr); +} + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("Hi-Performance Protocol Identification Engine UDP Protocol Packet Analysis and Sessioning Handler"); +MODULE_LICENSE("GPL"); + +static int __init init(void) { + pie_proto_udp_fd = pie_reg_protocol("udp",PIE_PROTOTYPE_TRANSPORT,PIE_ENCAP_TAGGED,0,&pie_udp_get_sess_bucket,&pie_udp_session_compare,&pie_udp_new_session,&pie_udp_packet_mockup,&pie_udp_create_predict,&pie_udp_add_predict_option,&pie_udp_validate_prediction,&pie_udp_convert_prediction,&pie_udp_proc_packet,&pie_udp_proc_print,&pie_udp_session_cleanup,&pie_udp_packet_cleanup); + pie_reg_subprotocol("ipv4",pie_proto_udp_fd,&pie_udp_ipv4find); + pie_proto_ipv4_fd_udp = pie_get_protocolid("ipv4"); + return 0; +} + +static void __exit fini(void) { + pie_unreg_protocol("udp",pie_proto_udp_fd); +} + +module_init(init); +module_exit(fini); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_protocol.c linux-2.6.27.8-hippie/net/hippie/pie_protocol.c --- linux-2.6.27.8/net/hippie/pie_protocol.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_protocol.c 2008-03-17 14:27:02.000000000 -0500 @@ -0,0 +1,342 @@ +/* + * Hi-Performance Protocol Identification Engine Protocol/Encapsulation Module Handling Code - pie_protocol.c + * $Id: pie_protocol.c,v 1.21 2008/03/17 19:27:02 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct pie_protocol *pie_protocols[512]; +struct pie_protocol *pie_protocols_namehash[26]; + +u_int16_t pie_reg_protocol(char *name, u_int8_t prototype, u_int8_t encap, u_int8_t npkt, + u_int8_t (*get_sess_bucket) (struct pie_protocol_hdr *, u_int8_t direction), + u_int8_t (*session_compare) (struct pie_protocol_hdr *, struct pie_protocol_sess *, u_int8_t direction), + struct pie_protocol_sess *(*new_session) (struct pie_protocol_hdr *), + struct pie_protocol_hdr *(*packet_mockup) (struct pie_packet_info *, struct pie_protocol_hdr *curhdr), + struct pie_protocol_sess *(*create_predict) (void), + u_int8_t (*add_predict_option) (struct pie_protocol_sess *hdr, char *name, u_int8_t dtype, void *data), + u_int8_t (*validate_prediction) (struct pie_protocol_sess *hdr), + u_int8_t (*convert_prediction) (struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess), + int (*proc_packet) (struct pie_sess_info *sess, struct pie_protocol_hdr *pkthdr), + int (*proc_print) (struct pie_sess_info *sess, struct pie_protocol_sess *, char *buffer), + void (*session_cleanup) (struct pie_protocol_sess *), + void (*packet_cleanup) (struct pie_protocol_hdr *) +) { + int i = 0; + for (i = 0; i < PIE_PROTO_MAXCOUNT; i++) { + if (pie_protocols[i] != NULL && strcmp(name,pie_protocols[i]->name) == 0 && pie_protocols[i]->status != PIE_PROTO_INACTIVE) { + printk(KERN_ALERT "HiPPIE: Protocol %s is already registered!\n",name); + } + } + for (i = 0; i < PIE_PROTO_MAXCOUNT; i++) { + if (pie_protocols[i] == NULL || (strcmp(name,pie_protocols[i]->name) == 0 && pie_protocols[i]->status == PIE_PROTO_INACTIVE)) { + //pie_proto_handlers[proto] = kmalloc(sizeof(struct pie_proto_handler),GFP_KERNEL); + u_int8_t hashindex = ((u_int8_t) name[0]) % 26; + if (pie_protocols[i] == NULL) { + /* It's new */ + pie_protocols[i] = kmalloc(sizeof(struct pie_protocol),GFP_KERNEL); + if (pie_protocols[i] == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to allocate memory for protocol handler.\n"); + return 0; + } + pie_protocols[i]->fd = i; + strncpy(pie_protocols[i]->name,name,PIE_PROTO_MAX_NAMELEN); + pie_protocols[i]->prototype = prototype; + /* Stats */ + atomic_set(&pie_protocols[i]->packets_ins,0); + atomic_set(&pie_protocols[i]->packets,0); + atomic_set(&pie_protocols[i]->conns,0); + atomic_set(&pie_protocols[i]->bytes,0); + atomic_set(&pie_protocols[i]->all_packets,0); + atomic_set(&pie_protocols[i]->all_conns,0); + atomic_set(&pie_protocols[i]->all_bytes,0); + atomic_set(&pie_protocols[i]->predicts,0); + atomic_set(&pie_protocols[i]->predicts_used,0); + } + pie_protocols[i]->encapsulation = encap; + pie_protocols[i]->n_packets = npkt; + pie_protocols[i]->subchecks = NULL; + pie_protocols[i]->persist = NULL; + pie_protocols[i]->parentlist = NULL; + pie_protocols[i]->tunnel_types = NULL; + pie_protocols[i]->next = pie_protocols_namehash[hashindex]; + pie_protocols_namehash[hashindex] = pie_protocols[i]; + /* Functions */ + pie_protocols[i]->get_sess_bucket = get_sess_bucket; + pie_protocols[i]->session_compare = session_compare; + pie_protocols[i]->new_session = new_session; + pie_protocols[i]->packet_mockup = packet_mockup; +#ifdef CONFIG_HIPPIE_PREDICTION + pie_protocols[i]->create_predict = create_predict; + pie_protocols[i]->add_predict_option = add_predict_option; + pie_protocols[i]->validate_prediction = validate_prediction; + pie_protocols[i]->convert_prediction = convert_prediction; +#else + pie_protocols[i]->create_predict = NULL; + pie_protocols[i]->add_predict_option = NULL; + pie_protocols[i]->validate_prediction = NULL; + pie_protocols[i]->convert_prediction = NULL; +#endif + pie_protocols[i]->proc_packet = proc_packet; + pie_protocols[i]->proc_print = proc_print; + pie_protocols[i]->session_cleanup = session_cleanup; + pie_protocols[i]->packet_cleanup = packet_cleanup; +#ifdef CONFIG_PROC_FS + pie_protocols[i]->procentry = create_proc_entry(name,0400,proc_net_hippie_proto); + if (!pie_protocols[i]->procentry) { + printk(KERN_ALERT "HiPPIE: Unable to allocate module %s proc entry.\n",name); + } else { + pie_protocols[i]->procentry->owner = THIS_MODULE; + pie_protocols[i]->procentry->read_proc = pie_proc_print_proto_stats; + pie_protocols[i]->procentry->data = (void *) pie_protocols[i]; + } +#endif + pie_protocols[i]->status = PIE_PROTO_ACTIVE; + return i; + } + } + printk(KERN_ALERT "HiPPIE: Reached maximum number of registered protocols!\n"); + return 0; +} + +u_int16_t pie_unreg_protocol(char *name, u_int16_t fd) { + int i = 0; + for (i = 0; i < PIE_PROTO_MAXCOUNT;i++) { + if (pie_protocols[i]->fd == fd && strcmp(name,pie_protocols[i]->name) == 0) { + + printk(KERN_INFO "HiPPIE: Unregistering protocol %s(%d).\n",name,i); + /* Unregister any protocol parents pointing at me */ + while (pie_protocols[i]->subchecks != NULL) { + struct pie_subprotocol_check *former = pie_protocols[i]->subchecks; + pie_protocols[i]->subchecks = former->next; + struct pie_protocol_list *parent = pie_protocols[former->protoindex]->parentlist; + struct pie_protocol_list *lastparent = NULL; + while (parent != NULL) { + if (parent->index == i) { + if (lastparent == NULL) { + pie_protocols[former->protoindex]->parentlist = parent->next; + } else { + lastparent->next = parent->next; + } + kfree(parent); + if (lastparent == NULL) { + parent = pie_protocols[former->protoindex]->parentlist; + } else { + parent = lastparent->next; + } + } else { + lastparent = parent; + parent = parent->next; + } + } + kfree(former); + } + + /* Unregister from any of my parents */ + while (pie_protocols[i]->parentlist != NULL) { + struct pie_protocol_list *former = pie_protocols[i]->parentlist; + pie_protocols[i]->parentlist = former->next; + struct pie_subprotocol_check *sub = pie_protocols[former->index]->subchecks; + struct pie_subprotocol_check *lastsub = NULL; + while (sub != NULL) { + if (sub->protoindex == i) { + if (lastsub == NULL) { + pie_protocols[former->index]->subchecks = sub->next; + } else { + lastsub->next = sub->next; + } + kfree(sub); + if (lastsub == NULL) { + sub = pie_protocols[former->index]->subchecks; + } else { + sub = lastsub->next; + } + } else { + lastsub = sub; + sub = sub->next; + } + } + kfree(former); + } + + /* Unregister any persistence checks */ + while (pie_protocols[i]->persist != NULL) { + struct pie_persist_list *former = pie_protocols[i]->persist; + pie_protocols[i]->persist = former->next; + kfree(former); + } + /* Free encapsulation types */ + while (pie_protocols[i]->tunnel_types != NULL) { + struct pie_protocol_list *former = pie_protocols[i]->tunnel_types; + pie_protocols[i]->tunnel_types = former->next; + kfree(former); + } + /* Unregister all the functions */ + pie_protocols[i]->get_sess_bucket = NULL; + pie_protocols[i]->session_compare = NULL; + pie_protocols[i]->new_session = NULL; + pie_protocols[i]->packet_mockup = NULL; + pie_protocols[i]->create_predict = NULL; + pie_protocols[i]->add_predict_option = NULL; + pie_protocols[i]->validate_prediction = NULL; + pie_protocols[i]->convert_prediction = NULL; + pie_protocols[i]->proc_packet = NULL; + pie_protocols[i]->proc_print = NULL; + pie_protocols[i]->session_cleanup = NULL; + pie_protocols[i]->packet_cleanup = NULL; + +#ifdef CONFIG_PROC_FS + if (pie_protocols[i]->procentry) { + remove_proc_entry(pie_protocols[i]->name,proc_net_hippie_proto); + } +#endif + /* Unregister me from protocol list */ + //pie_protocols[i] = NULL; + pie_protocols[i]->status = PIE_PROTO_INACTIVE; + return 1; + } + } + printk(KERN_ALERT "HiPPIE: Unable to find protocol %s registered.\n",name); + return 0; +} + +int16_t pie_get_protocolid(char *name) { + u_int8_t hashindex = ((u_int8_t) name[0]) % 26; + struct pie_protocol *search = pie_protocols_namehash[hashindex]; + while (search != NULL) { + if (strcmp(name,search->name) == 0) { + return search->fd; + } + search = search->next; + } + return -1; +} + +u_int16_t pie_reg_subprotocol(char *parentname, u_int16_t subprotoid, pie_protocheck_func *check) { + if (check == NULL) { + printk(KERN_ALERT "HiPPIE: Not registering subprotocol check with NULL check function.\n"); + return 0; + } else { + if (pie_protocols[subprotoid] == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to register subprotocol %d to parent %s because protocol %d is NULL.\n",subprotoid,parentname,subprotoid); + return 0; + } + int16_t parent = pie_get_protocolid(parentname); + if (parent < 0 || pie_protocols[parent]->status == PIE_PROTO_INACTIVE) { + printk(KERN_ALERT "HiPPIE: Unable to register subprotocol %s to parent %s because parent didn't exist.\n",pie_protocols[subprotoid]->name,parentname); + return 0; + } + struct pie_subprotocol_check *subproto = kmalloc(sizeof(struct pie_subprotocol_check),GFP_KERNEL); + if (subproto != NULL) { + subproto->next = NULL; + subproto->protoindex = subprotoid; + subproto->check = check; + if (pie_protocols[parent]->subchecks != NULL) { + struct pie_subprotocol_check *search = pie_protocols[parent]->subchecks; + while (search->next != NULL) { + search = search->next; + } + search->next = subproto; + } else { + pie_protocols[parent]->subchecks = subproto; + } + //subproto->next = pie_protocols[parent]->subchecks; + //pie_protocols[parent]->subchecks = subproto; + struct pie_protocol_list *parentnode = kmalloc(sizeof(struct pie_subprotocol_check),GFP_KERNEL); + if (parentnode != NULL) { + parentnode->index = parent; + parentnode->next = pie_protocols[subprotoid]->parentlist; + pie_protocols[subprotoid]->parentlist = parentnode; + } else { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for parent node.\n"); + } + return 1; + } else { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for subprotocol check!\n"); + return 0; + } + } +} + +u_int16_t pie_reg_tunnel_type(u_int16_t me, char *encapname) { + if (pie_protocols[me] == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to register tunnel type of protocol %s within NULL protocol.\n",encapname); + return 0; + } + int16_t encapproto = pie_get_protocolid(encapname); + if (encapproto < 0 || pie_protocols[encapproto]->status == PIE_PROTO_INACTIVE) { + printk(KERN_ALERT "HiPPIE: Unable to register tunnel type of protocol %s within %s because the encapsulated protocol didn't exist.\n",encapname,pie_protocols[me]->name); + return 0; + } + struct pie_protocol_list *encaplist = kmalloc(sizeof(struct pie_protocol_list),GFP_KERNEL); + if (encaplist != NULL) { + encaplist->index = encapproto; + encaplist->next = pie_protocols[me]->tunnel_types; + pie_protocols[me]->tunnel_types = encaplist; + return 1; + } else { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for tunnel_type list.\n"); + return 0; + } +} + +u_int16_t pie_reg_persist(/*char *parent, */u_int16_t protoid, piepersistfunc *func) { + if (pie_protocols[protoid] != NULL && protoid > 0 && pie_protocols[protoid]->status != PIE_PROTO_INACTIVE) { + struct pie_persist_list *persist = kmalloc(sizeof(struct pie_persist_list),GFP_KERNEL); + if (persist != NULL) { + persist->func = func; + persist->next = pie_protocols[protoid]->persist; + pie_protocols[protoid]->persist = persist; + return 1; + } else { + printk(KERN_ALERT "HiPPIE: Unable to allocate memory for persistance function.\n"); + return 0; + } + } else { + printk(KERN_ALERT "HiPPIE: Unable to register persistance function to protocol that doesn't exist.\n"); + return 0; + } +} + +int pie_protocols_init(void) { + int i = 0; + int j = 0; + for(i = 0;i < PIE_PROTO_MAXCOUNT;i++) { + pie_protocols[i] = NULL; + } + for (j = 0; j < 26; j++) { + pie_protocols_namehash[j] = NULL; + } + /* Create the /proc/net/hippie/protocols file */ + proc_net_hippie_protocols = create_proc_entry("protocols",0400,proc_net_hippie); + if (!proc_net_hippie_protocols) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc protocols list.\n"); + return -ENOMEM; + } else { + proc_net_hippie_protocols->owner = THIS_MODULE; + proc_net_hippie_protocols->read_proc = pie_proc_print_protocols; + } + /* Need to allocate a root protocol that actually is nothing */ + pie_reg_protocol("[root]",0,PIE_ENCAP_NONE,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + return 0; +} + +EXPORT_SYMBOL(pie_reg_protocol); +EXPORT_SYMBOL(pie_unreg_protocol); +EXPORT_SYMBOL(pie_get_protocolid); +EXPORT_SYMBOL(pie_reg_subprotocol); +EXPORT_SYMBOL(pie_reg_tunnel_type); +EXPORT_SYMBOL(pie_reg_persist); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/pie_sessions.c linux-2.6.27.8-hippie/net/hippie/pie_sessions.c --- linux-2.6.27.8/net/hippie/pie_sessions.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/pie_sessions.c 2008-03-17 14:27:02.000000000 -0500 @@ -0,0 +1,551 @@ +/* + * Hi-Performance Protocol Identification Engine Core Code and Sessioning Code - piecore.c + * $Id: pie_sessions.c,v 1.11 2008/03/17 19:27:02 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#ifdef CONFIG_HIPPIE_PREDICTION +#include +#endif +#include +#include + +struct pie_sess_hdr **pie_session_table; +atomic_t pie_session_count; +atomic_t pie_session_countactive; + +struct proc_dir_entry *proc_net_hippie_sessions = NULL; +struct proc_dir_entry *proc_net_hippie_sessions_buckets = NULL; +struct proc_dir_entry *proc_net_hippie_sessions_buckets_inst[256]; +extern char *pie_sessions_pbuffer; /* Move this to proc.h? */ + +int pie_sessions_init(void) { + u_int16_t i, j; + + atomic_set(&pie_session_count,0); + atomic_set(&pie_session_countactive,0); + +#ifdef CONFIG_PROC_FS + proc_net_hippie_sessions = proc_mkdir("sessions",proc_net_hippie); + if (!proc_net_hippie_sessions) return -ENOMEM; + proc_net_hippie_sessions_buckets = proc_mkdir("buckets",proc_net_hippie_sessions); + if (!proc_net_hippie_sessions_buckets) return -ENOMEM; + /* Create the /proc/net/hippie/sessions/buckets/stat file */ + proc_net_hippie_sessions_buckets_stat = create_proc_entry("stat",0400,proc_net_hippie_sessions_buckets); + if (!proc_net_hippie_sessions_buckets_stat) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc bucket stats file.\n"); + return -ENOMEM; + } else { + proc_net_hippie_sessions_buckets_stat->owner = THIS_MODULE; + proc_net_hippie_sessions_buckets_stat->read_proc = pie_proc_print_bucket_stats; + } + /* Create the /proc/net/hippie/sessions/all file */ + proc_net_hippie_sessions = create_proc_entry("all",0400,proc_net_hippie_sessions); + if (!proc_net_hippie_sessions) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc session table.\n"); + return -ENOMEM; + } else { + proc_net_hippie_sessions->owner = THIS_MODULE; + proc_net_hippie_sessions->read_proc = pie_proc_print_sessions; + } + pie_sessions_pbuffer = NULL; +#endif + + /* Allocate the space for the session table */ + pie_session_table = kmalloc(256 * sizeof(void*),GFP_KERNEL); + if (pie_session_table == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to allocate session table structures.\n"); + return -ENOMEM; + } else { + for (i = 0;i < 256;i++) { +#ifdef CONFIG_PROC_FS + char procdirname[4]; + sprintf(procdirname,"%d",i); + proc_net_hippie_sessions_buckets_inst[i] = proc_mkdir(procdirname,proc_net_hippie_sessions_buckets); + if (!proc_net_hippie_sessions_buckets_inst[i]) return -ENOMEM; +#endif + pie_session_table[i] = kmalloc(256 * sizeof(struct pie_sess_hdr),GFP_KERNEL); + if (pie_session_table[i] == NULL) { + printk(KERN_ALERT "HiPPIE: Unable to allcoate session table structures.\n"); + kfree(pie_session_table); + return -ENOMEM; + } else { + /* Initialize the pie_sess_hdr for each bucket */ + for (j = 0;j < 256;j++) { + pie_session_table[i][j].lock = RW_LOCK_UNLOCKED; + pie_session_table[i][j].bucketid = i * 256 + j; + pie_session_table[i][j].sessions = NULL; + //pie_session_table[i][j].cleanup = NULL; + atomic_set(&pie_session_table[i][j].sesscount,0); +#ifdef CONFIG_PROC_FS + sprintf(procdirname,"%d",j); + pie_session_table[i][j].proc = create_proc_entry(procdirname,0400,proc_net_hippie_sessions_buckets_inst[i]); + pie_session_table[i][j].procbuffer = NULL; + pie_session_table[i][j].procbuffersize = 0; + if (!pie_session_table[i][j].proc) { + printk(KERN_ALERT "HiPPIE: Unable to allocate proc for session bucket %d/%d.\n",i,j); + return -ENOMEM; + } else { + pie_session_table[i][j].proc->owner = THIS_MODULE; + pie_session_table[i][j].proc->read_proc = pie_proc_print_session_bucket; + pie_session_table[i][j].proc->data = (void *)&pie_session_table[i][j]; + } +#endif + } + } + } + } + printk(KERN_INFO "HiPPIE: Created 65536 Buckets for HiPPIE Session Table.\n"); + return 0; +} + +/* pie_free_session_header function - protocol session header cleanup + * This function recurses through all the session headers stored within a session and + * calls the appropriate protocols cleanup functions to allow those modules to release + * any memory that they might have out in the session information. */ +void pie_free_session_header(struct pie_protocol_sess *sess) { + if (sess != NULL) { + pie_free_session_header(sess->next_sess); + if (pie_protocols[sess->protoindex] != NULL && pie_protocols[sess->protoindex]->session_cleanup != NULL) { + pie_protocols[sess->protoindex]->session_cleanup(sess); + } else { + printk(KERN_INFO "HiPPIE: Protocol signature %d does not have a session cleanup function.\n",sess->protoindex); + } + } +} + +struct pie_sess_info *pie_session_find(struct pie_packet_info *packet) { + struct pie_sess_info *finder = NULL; + u_int8_t hash1 = 255; + u_int8_t hash2 = 255; + struct pie_sess_hdr *table = NULL; + u_int8_t direction = 0; + if (packet->network_hdr != NULL && pie_protocols[packet->network_hdr->protoindex] != NULL && pie_protocols[packet->network_hdr->protoindex]->get_sess_bucket != NULL) { + if (packet->transport_hdr != NULL && pie_protocols[packet->transport_hdr->protoindex] != NULL && pie_protocols[packet->transport_hdr->protoindex]->get_sess_bucket != NULL) { +#ifdef CONFIG_HIPPIE_PREDICTION + for (direction = 0; direction <= 2; direction++) { +#else + for (direction = 0; direction < 2; direction++) { +#endif + /* 0 == Forward, 1 == Reverse, 2 == Prediction */ +#ifdef CONFIG_HIPPIE_PREDICTION + if (direction < 2) { +#endif + hash1 = pie_protocols[packet->network_hdr->protoindex]->get_sess_bucket(packet->network_hdr,direction); + hash2 = pie_protocols[packet->transport_hdr->protoindex]->get_sess_bucket(packet->transport_hdr,direction); + table = &pie_session_table[hash1][hash2]; +#ifdef CONFIG_HIPPIE_PREDICTION + } else { + table = &pie_prediction_table; + } +#endif + read_lock(&table->lock); + finder = table->sessions; + while (finder != NULL) { + struct pie_protocol_sess *sesshdr = finder->network_sess; + struct pie_protocol_hdr *pkthdr = packet->network_hdr; + while (pkthdr != NULL && sesshdr != NULL) { + if (pkthdr->protoindex == sesshdr->protoindex) { + if (pie_protocols[pkthdr->protoindex]->session_compare != NULL && pie_protocols[pkthdr->protoindex]->session_compare(pkthdr,sesshdr,direction) == 0) { + /* Packet doesn't match current session */ + break; + } else { + /* Packet matches, move on to the next headers and try them... */ + /* If they are NULL, return this session as it's matched through and through. */ + if (pkthdr->next_hdr == NULL && sesshdr->next_sess == NULL) { + /* Session match */ + read_unlock(&table->lock); +#ifdef CONFIG_HIPPIE_PREDICTION + if (direction == 2) { + packet->direction = 0; + return pie_use_prediction(packet,finder); + } else { +#endif + packet->direction = direction; + return finder; +#ifdef CONFIG_HIPPIE_PREDICTION + } +#endif + } else if (pkthdr->next_hdr == NULL && sesshdr->next_sess != NULL) { + /* This could still match, if the session has a non-encapsulation header such as an application protocol next */ + /* For now, treat this as a non-match until I figure out what to put here. */ + if (pie_protocols[sesshdr->next_sess->protoindex]->encapsulation <= PIE_ENCAP_UNTAGGED) { + /* This session couldn't have been readily identified by the basic mockup process, but still matches all the appropriate prior information + * This is a match. */ + read_unlock(&table->lock); +#ifdef CONFIG_HIPPIE_PREDICTION + if (direction == 2) { + packet->direction = 0; + return pie_use_prediction(packet,finder); + } else { +#endif + packet->direction = direction; + return finder; +#ifdef CONFIG_HIPPIE_PREDICTION + } +#endif + } else { + break; + } + } else if (pkthdr->next_hdr != NULL && sesshdr->next_sess == NULL) { + /* This could still be a match, however we will break here because the packet has more information than the session, + * and we'll let the mockup process determine whether this is correct or not. */ + /*printk(KERN_INFO "HiPPIE: Not matching session in bucket %d/%d because packet has a possible non-encap header and session does not.\n",hash1,hash2);*/ + break; + } + } + /* This means there are more to go, so we should step another set down into the headers. */ + sesshdr = sesshdr->next_sess; + pkthdr = pkthdr->next_hdr; + } else { + break; + } + } + finder = finder->next; + } + read_unlock(&table->lock); + } + } else { + for (direction = 0; direction <= 1; direction++) { + /* 0 == Forward, 1 == Reverse, No Prediction without a Transport */ + hash1 = pie_protocols[packet->network_hdr->protoindex]->get_sess_bucket(packet->network_hdr,direction); + hash2 = 255; + table = &pie_session_table[hash1][hash2]; + read_lock(&table->lock); + finder = table->sessions; + while (finder != NULL) { + struct pie_protocol_sess *sesshdr = finder->network_sess; + struct pie_protocol_hdr *pkthdr = packet->network_hdr; + while (pkthdr != NULL && sesshdr != NULL) { + if (pkthdr->protoindex == sesshdr->protoindex) { + if (pie_protocols[pkthdr->protoindex]->session_compare != NULL && pie_protocols[pkthdr->protoindex]->session_compare(pkthdr,sesshdr,direction) == 0) { + /* Packet doesn't match current session */ + break; + } else { + /* Packet matches, move on to the next headers and try them... */ + /* If they are NULL, return this session as it's matched through and through. */ + if (pkthdr->next_hdr == NULL && sesshdr->next_sess == NULL) { + /* Session match */ + read_unlock(&table->lock); + packet->direction = direction; + return finder; + } else if (pkthdr->next_hdr == NULL && sesshdr->next_sess != NULL) { + /* This could still match, if the session has a non-encapsulation header such as an application protocol next */ + /* For now, treat this as a non-match until I figure out what to put here. */ + if (pie_protocols[sesshdr->next_sess->protoindex]->encapsulation <= PIE_ENCAP_UNTAGGED) { + /* This session couldn't have been readily identified by the basic mockup process, but still matches all the appropriate prior information + * This is a match. */ + read_unlock(&table->lock); + packet->direction = direction; + return finder; + } else { + break; + } + } else if (pkthdr->next_hdr != NULL && sesshdr->next_sess == NULL) { + /* This could still be a match, however we will break here because the packet has more information than the session, + * and we'll let the mockup process determine whether this is correct or not. */ + printk(KERN_INFO "HiPPIE: Not matching session in bucket %d/%d because packet has a possible non-encap header and session does not.\n",hash1,hash2); + break; + } + } + /* This means there are more to go, so we should step another set down into the headers. */ + sesshdr = sesshdr->next_sess; + pkthdr = pkthdr->next_hdr; + } else { + break; + } + } + finder = finder->next; + } + read_unlock(&table->lock); + } + } + } + return NULL; +} + +struct pie_sess_info *pie_create_session(struct pie_packet_info *packet) { + struct pie_sess_info *sess = kmalloc(sizeof(struct pie_sess_info),GFP_KERNEL); + u_int8_t hash1,hash2; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for new session.\n"); + return NULL; + } + /* Allocate a session, adjust counters*/ + sess->sessid = atomic_read(&pie_session_count); + atomic_inc(&pie_session_count); + atomic_inc(&pie_session_countactive); + /* Set the base options */ + atomic_set(&sess->packets,0); + atomic_set(&sess->bytes,0); + atomic_set(&sess->state,PIE_STATE_NEW); + sess->caninspect = 1; + sess->persist = 0; + sess->sigdata = NULL; + sess->next = NULL; + sess->prev = NULL; + pie_session_timeout_init(sess); + /* NULL the headers */ + sess->network_sess = NULL; + sess->transport_sess = NULL; + sess->first_sess = NULL; + sess->last_sess = NULL; + + /* Recurse the packets headers to set up the session */ + sess->first_sess = pie_session_create_subsession(sess,packet->first_hdr); + + /* Add the session to the proper buckets */ + if (sess->network_sess != NULL && pie_protocols[packet->network_hdr->protoindex]->get_sess_bucket != NULL) { + hash1 = pie_protocols[packet->network_hdr->protoindex]->get_sess_bucket(packet->network_hdr,0); + if (sess->transport_sess != NULL && pie_protocols[packet->transport_hdr->protoindex]->get_sess_bucket != NULL) { + hash2 = pie_protocols[packet->transport_hdr->protoindex]->get_sess_bucket(packet->transport_hdr,0); + } else { + hash2 = 255; + } + } else { + pie_session_timeout_cancel(sess); + atomic_dec(&pie_session_countactive); + pie_free_session_header(sess->first_sess); + kfree(sess); + return NULL; + } + sess->lock = &pie_session_table[hash1][hash2].lock; + sess->bucket = &pie_session_table[hash1][hash2]; + write_lock(&pie_session_table[hash1][hash2].lock); + sess->next = pie_session_table[hash1][hash2].sessions; + if (pie_session_table[hash1][hash2].sessions != NULL) { + pie_session_table[hash1][hash2].sessions->prev = sess; + } + pie_session_table[hash1][hash2].sessions = sess; + atomic_inc(&pie_session_table[hash1][hash2].sesscount); + write_unlock(&pie_session_table[hash1][hash2].lock); + return sess; +} + +struct pie_protocol_sess *pie_session_create_subsession(struct pie_sess_info *sess, struct pie_protocol_hdr *packethdr) { + if (packethdr == NULL) { + return NULL; + } + if (pie_protocols[packethdr->protoindex] != NULL) { + if (pie_protocols[packethdr->protoindex]->new_session != NULL) { + struct pie_protocol_sess *protosess = pie_protocols[packethdr->protoindex]->new_session(packethdr); + if (protosess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate session header from protocol %s.\n",pie_protocols[packethdr->protoindex]->name); + return NULL; + } + if (sess->network_sess == NULL && pie_protocols[packethdr->protoindex]->prototype == PIE_PROTOTYPE_NETWORK) { + sess->network_sess = protosess; + } + if (sess->transport_sess == NULL && pie_protocols[packethdr->protoindex]->prototype == PIE_PROTOTYPE_TRANSPORT) { + sess->transport_sess = protosess; + } + atomic_inc(&pie_protocols[protosess->protoindex]->all_conns); + atomic_inc(&pie_protocols[protosess->protoindex]->conns); + if (sess->last_sess != NULL) { + atomic_dec(&pie_protocols[sess->last_sess->protoindex]->conns); + /* Put the packet count and byte count into the appropriate medium */ + atomic_sub(atomic_read(&sess->packets),&pie_protocols[sess->last_sess->protoindex]->packets); + atomic_add(atomic_read(&sess->packets),&pie_protocols[protosess->protoindex]->packets); + atomic_add(atomic_read(&sess->packets),&pie_protocols[protosess->protoindex]->all_packets); + atomic_sub(atomic_read(&sess->bytes),&pie_protocols[sess->last_sess->protoindex]->bytes); + atomic_add(atomic_read(&sess->bytes),&pie_protocols[protosess->protoindex]->bytes); + atomic_add(atomic_read(&sess->bytes),&pie_protocols[protosess->protoindex]->all_bytes); + } + sess->last_sess = protosess; + if (packethdr->next_hdr != NULL) { + protosess->next_sess = pie_session_create_subsession(sess,packethdr->next_hdr); + } else { + protosess->next_sess = NULL; + } + /* Reset the can inspect bit, because the new proto head might be able to be inspected */ + sess->caninspect = 1; + return protosess; + } else { + if (packethdr->next_hdr != NULL) { + return pie_session_create_subsession(sess,packethdr->next_hdr); + } + } + } + return NULL; +} + +void *pie_session_get_value(struct pie_sess_info *sess, u_int16_t sigcode, u_int16_t dataid) { + if (sess != NULL) { + struct pie_sess_sig_data *search = sess->sigdata; + while (search != NULL) { + if (search->sigcode == sigcode && search->dataid == dataid) { + return search->value; + } + search=search->next; + } + } + return NULL; +} + +int pie_session_set_value(struct pie_sess_info *sess, u_int16_t sigcode, u_int16_t dataid, void *value) { + if (sess != NULL) { + struct pie_sess_sig_data *search = sess->sigdata; + struct pie_sess_sig_data *newdata; + while (search != NULL) { + if (search->sigcode == sigcode && search->dataid == dataid) { + search->value = value; + return 0; + } + search=search->next; + } + newdata = kmalloc(sizeof(struct pie_sess_sig_data),GFP_KERNEL); + if (newdata != NULL) { + newdata->sigcode = sigcode; + newdata->dataid = dataid; + newdata->value = value; + newdata->prev = NULL; + newdata->next = sess->sigdata; + if (newdata->next != NULL) { + newdata->next->prev = newdata; + } + sess->sigdata = newdata; + return 0; + } else { + printk(KERN_INFO "HiPPIE: Failed to create session data %u in session %u.\n",dataid,sess->sessid); + return -2; + } + } + printk(KERN_INFO "HiPPIE: Tried setting session value on NULL session.\n"); + return -1; +} + +/* Use high-res timers and initiate a proper timeout for the session as called */ +void pie_session_timeout_cancel(struct pie_sess_info *sess) { + hrtimer_try_to_cancel(&sess->timeout); +} + +void pie_session_timeout_init(struct pie_sess_info *sess) { + ktime_t start = ktime_set(15,0); + hrtimer_init(&sess->timeout,CLOCK_MONOTONIC,HRTIMER_MODE_REL); + sess->timeout.function = pie_session_timeout; + hrtimer_start(&sess->timeout,start,HRTIMER_MODE_REL); +} + +void pie_session_timeout_reset(struct pie_sess_info *sess,u_int16_t timeout) { + ktime_t start = ktime_set(timeout,0); + if (hrtimer_try_to_cancel(&sess->timeout) == 1) { + hrtimer_start(&sess->timeout,start,HRTIMER_MODE_REL); + } +} + +enum hrtimer_restart pie_session_timeout(struct hrtimer *timer) { + struct pie_sess_info *sess = container_of(timer,struct pie_sess_info,timeout); + unsigned long flags; + struct pie_sess_sig_data *datasearch, *todel; + char buffer[1024]; + /* Unbucket the session */ + struct pie_sess_hdr *bucket = (struct pie_sess_hdr *) sess->bucket; + if (bucket != NULL) { + write_lock_irqsave(&bucket->lock,flags); + if (bucket->sessions == sess) { + bucket->sessions = sess->next; + } else if (sess->prev != NULL) { + sess->prev->next = sess->next; + } else { + printk(KERN_ALERT "HiPPIE: Uh oh, found session with null previous that is not root session in bucket.\n"); + } + if (sess->next != NULL) { + sess->next->prev = sess->prev; + } + /*if (bucket->sessions == sess) { + bucket->sessions = sess->next; + } else { + struct pie_sess_info *search = bucket->sessions; + while (search != NULL) { + if (search->next == sess) { + search->next = sess->next; + break; + } + search = search->next; + } + }*/ + atomic_dec(&bucket->sesscount); + } else { + printk(KERN_ALERT "HiPPIE: Oddly timing out session with NULL bucket.\n"); + } +#ifdef CONFIG_HIPPIE_SESSDEBUG + int len = 0; + struct pie_protocol_sess *protosess = sess->first_sess; + len += sprintf(buffer,"HiPPIE: Terminating session %d: ",sess->sessid); + len += pie_session_print(&buffer[len],sess); + printk(KERN_INFO "%s",buffer); +#endif + if (atomic_read(&pie_session_countactive) > 0) { + atomic_dec(&pie_session_countactive); + } + write_unlock_irqrestore(&bucket->lock,flags); + datasearch = sess->sigdata; + while (datasearch != NULL) { + todel = datasearch; + datasearch = datasearch->next; + kfree(todel); + } + pie_free_session_header(sess->first_sess); + kfree(sess); + return HRTIMER_NORESTART; +} + +/* This assumes that a lock is already held on this session table */ +int pie_session_print(char *buffer,struct pie_sess_info *sess) { + int len = 0; + struct pie_protocol_sess *protosess; + struct timeval timeout = ktime_to_timeval(hrtimer_get_remaining(&sess->timeout)); + len += sprintf(buffer+len,"%u\t%s\t%u\t%d\t",sess->sessid,pie_protocols[sess->last_sess->protoindex]->name,atomic_read(&sess->packets),(int)timeout.tv_sec); + switch(atomic_read(&sess->state)) { + case PIE_STATE_NEW: + len += sprintf(buffer+len,"NEW\t"); + break; + case PIE_STATE_UNANS: + len += sprintf(buffer+len,"UNANS\t"); + break; + case PIE_STATE_BIDIR: + len += sprintf(buffer+len,"BIDIR\t"); + break; + case PIE_STATE_PREDICTED: + len += sprintf(buffer+len,"PREDICT\t"); + break; + default: + len += sprintf(buffer+len,"\t"); + break; + } + protosess = sess->first_sess; + while (protosess != NULL) { + if (pie_protocols[protosess->protoindex] != NULL) { + len += sprintf(buffer+len,"[ %s ",pie_protocols[protosess->protoindex]->name); + if (pie_protocols[protosess->protoindex]->proc_print != NULL) { + len += pie_protocols[protosess->protoindex]->proc_print(sess,protosess,buffer+len); + } + len += sprintf(buffer+len," ]"); + } + protosess = protosess->next_sess; + } + len += sprintf(buffer+len,"\n"); + return len; +} + +EXPORT_SYMBOL(pie_sessions_init); +EXPORT_SYMBOL(pie_session_set_value); +EXPORT_SYMBOL(pie_session_get_value); +EXPORT_SYMBOL(pie_session_timeout_init); +EXPORT_SYMBOL(pie_session_timeout_reset); +EXPORT_SYMBOL(pie_session_timeout_cancel); +EXPORT_SYMBOL(pie_session_timeout); +EXPORT_SYMBOL(pie_free_session_header); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/piecore.c linux-2.6.27.8-hippie/net/hippie/piecore.c --- linux-2.6.27.8/net/hippie/piecore.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/piecore.c 2008-06-28 20:33:53.000000000 -0500 @@ -0,0 +1,620 @@ +/* + * Hi-Performance Protocol Identification Engine Core Code and Sessioning Code - piecore.c + * $Id: piecore.c,v 1.64 2008/06/29 01:33:53 baldown Exp $ + * Copyright 2004-2008, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PROC_FS +#include +#endif + +#include +#include +#include +#ifdef CONFIG_HIPPIE_PREDICTION +#include +#endif +#include +#include +#ifdef CONFIG_PROC_FS +#include +#endif + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("Hi-Performance Protocol Identification Engine - packet analysis engine with sessionality for identifying protocols"); +MODULE_LICENSE("GPL"); + +atomic_t pie_packet_count; +atomic_t pie_byte_count; +atomic_t pie_inspect_count; + +static int __init init(void) { + atomic_set(&pie_packet_count,0); + atomic_set(&pie_byte_count,0); + atomic_set(&pie_inspect_count,0); +#ifdef CONFIG_PROC_FS + pie_proc_init(); +#endif + pie_sessions_init(); +#ifdef CONFIG_HIPPIE_PREDICTION + pie_prediction_init(); +#endif + pie_protocols_init(); +#ifdef CONFIG_HIPPIE_INTERFACES + pie_interfaces_init(); +#endif +#ifdef CONFIG_HIPPIE_HOSTINFO + pie_hostinfo_init(); +#endif + printk(KERN_INFO "HiPPIE: Protocol Identification Engine loaded successfully.\n"); + return 0; +} + +static void __exit fini(void) { +#ifdef CONFIG_PROC_FS + /* These need updated to include session table ones as well and the new session buckets */ + if (proc_net_hippie_sessions) { + remove_proc_entry("sessions",proc_net_hippie); + } + if (proc_net_hippie_protocols) { + remove_proc_entry("handlers",proc_net_hippie); + } + if (proc_net_hippie_stat) { + remove_proc_entry("stat",proc_net_hippie); + } + if (proc_net_hippie_proto) { + remove_proc_entry("proto",proc_net_hippie); + } + if (proc_net_hippie) { +//#ifdef CONFIG_NET_NS +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) + remove_proc_entry("hippie",init_net.proc_net); +#else + remove_proc_entry("hippie",proc_net); +#endif + } +#endif + /* Fix this, it doesn't fully clean up the session table */ + if (pie_session_table != NULL) { + int i; + for (i = 0;i < 256;i++) { + if (pie_session_table[i] != NULL) { + kfree(pie_session_table[i]); + } + } + kfree(pie_session_table); + } +} + +/* pie_free_packet_header function - protocol packet header cleanup + * This function recurses through all the packet headers stored within a packet mockup + * and calls the appropriate protocols cleanup function to allow those modules to release + * any memory that they might have out in the packet mockup information. */ +void pie_free_packet_header(struct pie_protocol_hdr *header) { + if (header != NULL) { + pie_free_packet_header(header->next_hdr); + if (pie_protocols[header->protoindex] != NULL && pie_protocols[header->protoindex]->packet_cleanup != NULL) { + pie_protocols[header->protoindex]->packet_cleanup(header); + } else { + printk(KERN_INFO "HiPPIE: Signature module %d does not have a packet cleanup function.\n",header->protoindex); + } + } +} + +/* pie_packet_cleanup function - packet mockup cleanup + * This function is called when a packet mockup is done being used so that all appropriate + * memory can be freed up. */ +void pie_packet_cleanup(struct pie_packet_info *packet) { + pie_free_packet_header(packet->first_hdr); + packet->first_hdr = NULL; + packet->last_hdr = NULL; + packet->network_hdr = NULL; + packet->transport_hdr = NULL; + kfree(packet); +} + +int pie_packet_inspect(u_int8_t *packet, u_int32_t len, u_int16_t protoid) { + struct pie_packet_info *pktinfo = NULL; + pktinfo = pie_packet_mockup(packet,len); + if (pktinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Packet mockup failed to allocate memory.\n"); + return -ENOMEM; + } + if (pktinfo->session == NULL) { + pie_packet_cleanup(pktinfo); + return 0; + } + if (pktinfo->session->last_sess != NULL && pktinfo->session->last_sess->protoindex == protoid) { + pie_packet_cleanup(pktinfo); + return 1; + } + pie_packet_cleanup(pktinfo); + return 0; +} + +int pie_skb_inspect(const struct sk_buff *skb, u_int16_t protoid) { + if (skb->hippie_sess != NULL && skb->hippie_sess->last_sess != NULL && skb->hippie_sess->last_sess->protoindex == protoid) { + return 1; + } + return 0; +} + +int pie_packet_multiinspect(u_int8_t *packet, u_int32_t len, u_int8_t *names) { + struct pie_packet_info *pktinfo = NULL; + pktinfo = pie_packet_mockup(packet,len); + if (pktinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Packet mockup failed to allocate memory.\n"); + return 0; + } + if (pktinfo->session == NULL) { + pie_packet_cleanup(pktinfo); + return 0; + } + u_int8_t plist[512]; + strncpy(plist,names,512); + u_int8_t pcount = 0; + u_int8_t *token, *pname; + do { + /* Find the last entry in the list. */ + token = strrchr(plist,','); + if (token != NULL) { + token[0] = '\0'; + /* Should now point to the last one remaining on the list, terminated by a null character. */ + pname = &(token[1]); + } else { + /* We're looking at the last protocol */ + pname = plist; + } + /* Pointing at some portion of the string, null terminated */ + u_int16_t protoid = pie_get_protocolid(pname); + if (protoid > 0 && pktinfo->session->last_sess != NULL && pktinfo->session->last_sess->protoindex == protoid) { + pie_packet_cleanup(pktinfo); + return 1; + } + pcount++; + } while (token != NULL); + pie_packet_cleanup(pktinfo); + return 0; +} + +int pie_skb_multiinspect(const struct sk_buff *skb, u_int8_t *names) { + if (skb->hippie_sess == NULL) { + return 0; + } + u_int8_t plist[512]; + strncpy(plist,names,512); + u_int8_t pcount = 0; + u_int8_t *token, *pname; + do { + /* Find the last entry in the list. */ + token = strrchr(plist,','); + if (token != NULL) { + token[0] = '\0'; + /* Should now point to the last one remaining on the list, terminated by a null character. */ + pname = &(token[1]); + } else { + /* We're looking at the last protocol */ + pname = plist; + } + /* Pointing at some portion of the string, null terminated */ + u_int16_t protoid = pie_get_protocolid(pname); + if (protoid > 0 && skb->hippie_sess->last_sess != NULL && skb->hippie_sess->last_sess->protoindex == protoid) { + return 1; + } + pcount++; + } while (token != NULL); + return 0; +} + +int pie_packet_checkencap(u_int8_t *packet, u_int32_t len, u_int16_t protoid) { + struct pie_packet_info *pktinfo = NULL; + struct pie_protocol_sess *search = NULL; + + pktinfo = pie_packet_mockup(packet,len); + if (pktinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Packet mockup failed to allocate memory.\n"); + return 0; + } + if (pktinfo->session == NULL) { + //printk(KERN_ALERT "HiPPIE: Packet mockup in checkencap returned a NULL session.\n"); + pie_packet_cleanup(pktinfo); + return 0; + } + search = pktinfo->session->first_sess; + while (search != NULL) { + if (search->protoindex == protoid) { + pie_packet_cleanup(pktinfo); + return 1; + } + search=search->next_sess; + } + pie_packet_cleanup(pktinfo); + return 0; +} + +int pie_skb_checkencap(const struct sk_buff *skb, u_int16_t protoid) { + struct pie_protocol_sess *search = NULL; + if (skb->hippie_sess == NULL) { + return 0; + } + search = skb->hippie_sess->first_sess; + while (search != NULL) { + if (search->protoindex == protoid) { + return 1; + } + search=search->next_sess; + } + return 0; +} + +int pie_packet_read_skb(struct sk_buff *skb) { + /* This used to be ->data, but that contained MAC headers on outbound packets, and not inbound */ + struct pie_sess_info *sess = pie_packet_read(skb->network_header,skb->len); + skb->hippie_sess = sess; + return 0; +} + +/* pie_packet_read function - initial packet processing function + * This function is called by any remote pieces of code which are passing packets into HiPPIE + * to be processed, such as netfilter. This function will take in the raw packet, send it into + * mockup, including tracking any sessions associated with the packet, and do any actual + * processing and inspection of the packet as necessary to determine what it is. */ +struct pie_sess_info *pie_packet_read(u_int8_t *packet, u_int32_t len) { + struct pie_packet_info *pktinfo = NULL; + struct pie_protocol_hdr *search = NULL; + struct pie_protocol_hdr *curhdr = NULL; + struct pie_protocol_sess *sesshdr = NULL; + struct pie_sess_info *retval = NULL; + + pktinfo = pie_packet_mockup(packet,len); + if (pktinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Packet mockup failed to allocate memory.\n"); + return NULL; + } + if (pktinfo->first_hdr == NULL) { + pie_packet_cleanup(pktinfo); + return NULL; + } + if (pktinfo->session == NULL) { + /* Go through the headers, and make sure this packet isn't an add-on to another already existing session that needs tagged... */ + /* and if not, create the session */ + struct pie_sess_info *sess = NULL, *lastsess = NULL; + search = pktinfo->first_hdr; + while (search != NULL) { + sess = pie_session_find(pktinfo); + if (sess == NULL && lastsess != NULL) { + /* Found a session on last headers, but not current... we now know more than the session with this packet */ + /* Add a new session header to this session based on the new information */ + struct pie_protocol_sess *psess; + sess = lastsess; + psess = pie_session_create_subsession(sess,curhdr); + if (sess->last_sess != NULL) { + sess->last_sess->next_sess = psess; + } + sess->last_sess = psess; + } + lastsess = sess; + search = search->next_hdr; + } + if (sess != NULL) { + pktinfo->session = sess; + } else { + /* I think we should create this session here... */ + /* We have all our headers, but no current session, so we must create one. */ + pktinfo->session = pie_create_session(pktinfo); + if (pktinfo->session == NULL) { + //printk(KERN_ALERT "HiPPIE: Unable to create session from packet mockup in pie_packet_read().\n"); + pie_packet_cleanup(pktinfo); + return NULL; + } + } + } + /* This check validates that this looping is needed, as not all packets need this */ + if (pktinfo->session->last_sess->protoindex != pktinfo->last_hdr->protoindex) { + /* Tag up the packet with the non-transport headers already tagged in the session */ + sesshdr = pktinfo->session->first_sess; + curhdr = pktinfo->first_hdr; + while (sesshdr != NULL) { + if (curhdr != NULL) { + if (sesshdr->protoindex != curhdr->protoindex) { + printk(KERN_ALERT "HiPPIE: Packet was mocked up on a protocol that didn't exist in the session!\n"); + break; + } + } else { + if (pie_protocols[sesshdr->protoindex]->packet_mockup != NULL) { + curhdr = pie_protocols[sesshdr->protoindex]->packet_mockup(pktinfo,pktinfo->last_hdr); + if (curhdr != NULL) { + pktinfo->last_hdr->next_hdr = curhdr; + pktinfo->last_hdr = curhdr; + } else { + /* This is an error state... we couldn't mock up a packet that the session knows more about than the packet did. */ + printk(KERN_INFO "HiPPIE: Unable to mockup packet for persistant checks.\n"); + break; + } + } else { + if (pie_protocols[sesshdr->protoindex]->status != PIE_PROTO_INACTIVE) { + /* This is an error state... we couldn't mock up a packet that the session knows more about than the packet did. */ + printk(KERN_INFO "HiPPIE: No mockup function found for peristant checks for %s(%d).\n",pie_protocols[sesshdr->protoindex]->name,sesshdr->protoindex); + break; + } else { + /* It's inactive, can't really do anything right now. */ + break; + } + } + } + sesshdr = sesshdr->next_sess; + if (curhdr != NULL) { + curhdr = curhdr->next_hdr; + } + } + } + + /* Do protocol inspection... */ + //if (atomic_read(&pktinfo->session->caninspect) == 1) { + if (pktinfo->session->caninspect == 1) { + do { + curhdr = pie_packet_protocheck(pktinfo->last_hdr->protoindex,pktinfo,pktinfo->last_hdr,1); + if (curhdr != NULL) { + /* Found additional session information... tag the packet and the session */ + pktinfo->last_hdr->next_hdr = curhdr; + pktinfo->last_hdr = curhdr; + pktinfo->session->last_sess->next_sess = pie_session_create_subsession(pktinfo->session,curhdr); + } + } while (curhdr != NULL && pktinfo->session->caninspect == 1); + } + + /* Do proc_packet on all the headers */ + search = pktinfo->first_hdr; + while (search != NULL) { + if (pie_protocols[search->protoindex] != NULL && pie_protocols[search->protoindex]->proc_packet != NULL) { + pie_protocols[search->protoindex]->proc_packet(pktinfo->session,search); + } + search = search->next_hdr; + } + + /* Statistic gathering */ + /* Core Numbers */ + atomic_inc(&pie_packet_count); + atomic_add(pktinfo->plen,&pie_byte_count); + /* Session Stats */ + atomic_inc(&pktinfo->session->packets); + atomic_add(pktinfo->plen,&pktinfo->session->bytes); + /* Protocol stats */ + atomic_inc(&pie_protocols[pktinfo->session->last_sess->protoindex]->packets); + atomic_add(pktinfo->plen,&pie_protocols[pktinfo->session->last_sess->protoindex]->bytes); + sesshdr = pktinfo->session->first_sess; + while (sesshdr != NULL) { + atomic_inc(&pie_protocols[sesshdr->protoindex]->all_packets); + atomic_add(pktinfo->plen,&pie_protocols[sesshdr->protoindex]->all_bytes); + sesshdr = sesshdr->next_sess; + } + +#ifdef CONFIG_HIPPIE_PERSISTANCE + /* If this is turned on, we should cause any session already classified to still + * undergo inspections if it has persistance available within it's definition */ + //if (atomic_read(&pktinfo->session->persist) == 1) { + if (pktinfo->session->persist == 1) { + struct pie_persist_list *persists; + sesshdr = pktinfo->session->network_sess; + curhdr = pktinfo->network_hdr; + while (sesshdr != NULL) { + persists = pie_protocols[sesshdr->protoindex]->persist; + while (persists != NULL) { + if (persists->func != NULL) { + persists->func(pktinfo->session,curhdr); + } + persists = persists->next; + } + sesshdr = sesshdr->next_sess; + curhdr = curhdr->next_hdr; + } + } +#endif + /* Recursively free space allocated to headers for the packet! */ + retval = pktinfo->session; + pie_packet_cleanup(pktinfo); + return retval; +} + +/* pie_packet_mockup function - packet protocol header processing + * This function takes in a raw packet either from the packet read function or some other function + * and starts processing functions within the protocols to recursively figure out the layout of the + * packet, for example taking a data section and wrapping it in headers for the TCP protocol, which + * could then be wrapped within a header for IPv4, even to the point of possibly being wrapped inside + * Ethernet headers. This will only wrap tagged encapsulation headers, and not application level + * inspection yet. That is handled after this process is done. */ +struct pie_packet_info *pie_packet_mockup(u_int8_t *packet, u_int32_t len) { + struct pie_packet_info *pktinfo = kmalloc(sizeof(struct pie_packet_info),GFP_KERNEL); + if (pktinfo != NULL && packet != NULL) { + struct pie_protocol_hdr *curhdr = NULL; + struct pie_sess_info *sess = NULL, *lastsess = NULL; + pktinfo->rawpacket = packet; + pktinfo->plen = len; + pktinfo->network_hdr = NULL; + pktinfo->transport_hdr = NULL; + pktinfo->last_hdr = NULL; + pktinfo->first_hdr = NULL; + pktinfo->session = NULL; + pktinfo->direction = 0; + do { + /* Check the packet for headers */ + if (curhdr == NULL) { + curhdr = pie_packet_protocheck(0,pktinfo,NULL,0); + pktinfo->first_hdr = curhdr; + } else { + curhdr = pie_packet_protocheck(curhdr->protoindex,pktinfo,curhdr,0); + } + if (curhdr != NULL) { + if (pktinfo->last_hdr != NULL) { + pktinfo->last_hdr->next_hdr = curhdr; + } + pktinfo->last_hdr = curhdr; + if (pktinfo->network_hdr == NULL && pie_protocols[curhdr->protoindex]->prototype == PIE_PROTOTYPE_NETWORK) { + pktinfo->network_hdr = curhdr; + } else if (pktinfo->transport_hdr == NULL && pie_protocols[curhdr->protoindex]->prototype == PIE_PROTOTYPE_TRANSPORT) { + pktinfo->transport_hdr = curhdr; + } + } + lastsess = sess; + } while (curhdr != NULL); + pktinfo->session = pie_session_find(pktinfo); + return pktinfo; + } else { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for a packet mockup.\n"); + return NULL; + } +} + +struct pie_protocol_hdr *pie_packet_protocheck(u_int16_t curproto, struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr, u_int8_t inspopt) { + /* inspopt is a value to specify how deeply to inspect. + * 0 = Headers only, i.e. only tagged encapsulated protocols + * 1 = Thorough application inspection within packet packet count */ + struct pie_subprotocol_check *search; + struct pie_protocol_hdr *protohdr; + struct pie_protocol_list *tunnels; + u_int8_t encapchange = 0; + u_int8_t didinsp = 0; + if (pie_protocols[curproto] == NULL) { + printk(KERN_ALERT "HiPPIE: Tried to do a protocol check on an unregistered protocol.\n"); + return NULL; + } + /* This must either be the first time we've been called on the packet, or we have data left to look at. */ + if (curhdr == NULL || (curhdr->datalen > 0 && curhdr->data != NULL)) { + search = pie_protocols[curproto]->subchecks; + tunnels = pie_protocols[curproto]->tunnel_types; + while (search != NULL || tunnels != NULL) { + while (search == NULL && tunnels != NULL) { + search = pie_protocols[tunnels->index]->subchecks; + if (encapchange != 0) { + tunnels = tunnels->next; + } + encapchange = 1; + } + if (search == NULL) { + break; + } + if (search->check == NULL) { + printk(KERN_ALERT "HiPPIE: Somehow received a NULL check function in pie_packet_protocheck().\n"); + return NULL; + } + /* Check to make sure we're either inspecting tagged encapsulations, or we're in actual packet inspection phase, and the packet count is low enough */ + if ((inspopt != 1 && pie_protocols[search->protoindex]->encapsulation >= PIE_ENCAP_TAGGED) || /* Not inspection, but looking for encapsulations */ + (inspopt == 1 && pktinfo->session != NULL && pie_protocols[search->protoindex]->encapsulation < PIE_ENCAP_TAGGED && /* Do inpsection on non-encapsulations that are left */ + pktinfo->session->last_sess->protoindex != search->protoindex && /* Last session header isn't of current check's type */ + atomic_read(&pktinfo->session->packets) <= pie_protocols[search->protoindex]->n_packets) /* Within packet constraints */) { + if (inspopt == 1) { + didinsp = 1; + } + if (search->check(pktinfo,curhdr) != 0) { + protohdr = pie_protocols[search->protoindex]->packet_mockup(pktinfo,curhdr); + if (protohdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to create protocol header from protocol %s.\n",pie_protocols[search->protoindex]->name); + } +#ifdef CONFIG_HIPPIE_PERSISTANCE + if (pie_protocols[search->protoindex]->persist != NULL) { + //atomic_set(&pktinfo->session->persist,1); + pktinfo->session->persist = 1; + } +#endif + if (inspopt == 1 && pie_protocols[search->protoindex]->encapsulation < PIE_ENCAP_TAGGED && pie_protocols[search->protoindex]->subchecks == NULL && pie_protocols[search->protoindex]->tunnel_types == NULL) { + //atomic_set(&pktinfo->session->caninspect,0); + pktinfo->session->caninspect = 0; + } + return protohdr; + } + } + search = search->next; + } + if (inspopt == 1 && didinsp == 0) { + /* This session passed through all the available searches (maybe none), and none could be used */ + /* Tag this session as no longer being able to be inspected */ + //atomic_set(&pktinfo->session->caninspect,0); + pktinfo->session->caninspect = 0; + } + } + if (didinsp > 0) { + atomic_inc(&pie_protocols[curproto]->packets_ins); + atomic_inc(&pie_inspect_count); + } + return NULL; +} + +u_int8_t *pie_payload_search(u_int8_t *start, u_int8_t *end, u_int8_t *pattern, u_int16_t datalen) { + /* start - pointer to the location within the packet to start the search + * end - pointer to the end of the search + * pattern - what to search for + * datalen - the length of the pattern + */ + u_int8_t *search = start; + int i; + int j = 0; + do { + for (i = 0;i < datalen;i++) { + if (search[i] != pattern[i]) { + break; + } + } + if (i == datalen) return search; + search++; + j++; + } while (&search[datalen] <= end && j < 300); + return NULL; +} + +u_int16_t make_int16(u_int8_t *from) { + u_int16_t ret = from[0] * 256 + from[1]; + return ret; +} + +u_int16_t make_int16_le(u_int8_t *from) { + u_int16_t ret = from[1] * 256 + from[0]; + return ret; +} + +u_int32_t make_int32(u_int8_t *from) { + u_int32_t ret = ((from[0] * 256 + from[1]) * 256 + from[2]) * 256 + from[3]; + return ret; +} + +u_int32_t make_int32_le(u_int8_t *from) { + u_int32_t ret = ((from[3] * 256 + from[2]) * 256 + from[1]) * 256 + from[0]; + return ret; +} +EXPORT_SYMBOL(make_int16); +EXPORT_SYMBOL(make_int16_le); +EXPORT_SYMBOL(make_int32); +EXPORT_SYMBOL(make_int32_le); + +//EXPORT_SYMBOL(pie_inspect_packet); +EXPORT_SYMBOL(pie_packet_read); +EXPORT_SYMBOL(pie_packet_read_skb); +EXPORT_SYMBOL(pie_payload_search); +EXPORT_SYMBOL(pie_packet_inspect); +EXPORT_SYMBOL(pie_packet_multiinspect); +EXPORT_SYMBOL(pie_packet_checkencap); +EXPORT_SYMBOL(pie_skb_inspect); +EXPORT_SYMBOL(pie_skb_multiinspect); +EXPORT_SYMBOL(pie_skb_checkencap); + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/Makefile linux-2.6.27.8-hippie/net/hippie/proto/Makefile --- linux-2.6.27.8/net/hippie/proto/Makefile 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/Makefile 2008-02-04 11:02:21.000000000 -0600 @@ -0,0 +1,37 @@ +obj-$(CONFIG_HIPPIE_GRE) += gre.o +obj-$(CONFIG_HIPPIE_ESP) += esp.o + +obj-$(CONFIG_HIPPIE_DNS) += dns.o +obj-$(CONFIG_HIPPIE_HTTP) += http.o +obj-$(CONFIG_HIPPIE_FTP) += ftp.o +obj-$(CONFIG_HIPPIE_SMTP) += smtp.o +obj-$(CONFIG_HIPPIE_POP3) += pop3.o +obj-$(CONFIG_HIPPIE_SSH) += ssh.o +obj-$(CONFIG_HIPPIE_IRC) += irc.o +obj-$(CONFIG_HIPPIE_NOVELLCP) += novellcp.o +obj-$(CONFIG_HIPPIE_RDESKTOP) += rdp.o +obj-$(CONFIG_HIPPIE_NNTP) += nntp.o +obj-$(CONFIG_HIPPIE_RSYNC) += rsync.o +obj-$(CONFIG_HIPPIE_SOCKS) += socks.o +obj-$(CONFIG_HIPPIE_NETFLOW) += netflow.o + +obj-$(CONFIG_HIPPIE_RTSP) += rtsp.o +obj-$(CONFIG_HIPPIE_SIP) += sip.o + +obj-$(CONFIG_HIPPIE_ARES) += ares.o +obj-$(CONFIG_HIPPIE_EDONKEY) += edonkey.o +obj-$(CONFIG_HIPPIE_BITTORRENT) += bittorrent.o +obj-$(CONFIG_HIPPIE_GNUTELLA) += gnutella.o +obj-$(CONFIG_HIPPIE_FASTTRACK) += fasttrack.o +obj-$(CONFIG_HIPPIE_MP2P) += mp2p.o +obj-$(CONFIG_HIPPIE_WINMX) += winmx.o +obj-$(CONFIG_HIPPIE_XUNLEI) += xunlei.o +obj-$(CONFIG_HIPPIE_PPSTREAM) += ppstream.o + +obj-$(CONFIG_HIPPIE_MSNIM) += msnim.o +obj-$(CONFIG_HIPPIE_AIM) += aim.o +obj-$(CONFIG_HIPPIE_YAHOOIM) += yahooim.o + +obj-$(CONFIG_HIPPIE_SSL) += ssl.o + +obj-$(CONFIG_HIPPIE_STORM) += storm.o diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/aim.c linux-2.6.27.8-hippie/net/hippie/proto/aim.c --- linux-2.6.27.8/net/hippie/proto/aim.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/aim.c 2008-02-08 10:35:52.000000000 -0600 @@ -0,0 +1,92 @@ +/* + * Hi-Performance Protocol Identification Engine AOL Instant Messenger Module - aim.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Instant Messaging Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_aim_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE AOL Instant Messenger Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_aim_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for AIM Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_aim_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_aim_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->data[0] == 0x2a && curhdr->datalen >= 6) { + u_int16_t datalen = 256 * curhdr->data[4] + curhdr->data[5]; + if (curhdr->datalen == datalen + 6) { + if (curhdr->data[1] == 0x01 || curhdr->data[1] == 0x02 || curhdr->data[1] == 0x04 || curhdr->data[1] == 0x05) { + return 1; + } else { + printk(KERN_INFO "HiPPIE: Found likely AIM Connection with Channel ID 0x%02x.\n",curhdr->data[1]); + return 0; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_aim_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *aimhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (aimhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate AIM Session Header.\n"); + return NULL; + } + aimhdr->protoindex = pie_proto_aim_fd; + aimhdr->header = NULL; + aimhdr->hlen = 0; + aimhdr->datalen = curhdr->datalen; + aimhdr->data = curhdr->data; + aimhdr->next_hdr = NULL; + aimhdr->proto_info = NULL; + return aimhdr; +} + +void pie_aim_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_aim_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_aim_fd = pie_reg_protocol("aim",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_aim_new_session,&pie_aim_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_aim_session_cleanup,&pie_aim_packet_cleanup); + if (pie_proto_aim_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_aim_fd,&pie_aim_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load aim module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("aim",pie_proto_aim_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/ares.c linux-2.6.27.8-hippie/net/hippie/proto/ares.c --- linux-2.6.27.8/net/hippie/proto/ares.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/ares.c 2008-02-08 10:35:52.000000000 -0600 @@ -0,0 +1,156 @@ +/* + * Hi-Performance Protocol Identification Engine Ares P2P Module - ares.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_ares_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE Ares P2P Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_ares_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for Ares P2P Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_ares_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_ares_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 3) { + u_int16_t psize = curhdr->data[1] * 256 + curhdr->data[0]; + if (curhdr->datalen == psize + 3) { + /* Here are the opcodes I've seen from Ares clients. It's not exhaustive probably, + * but should catch a significant portion, and help cut down false positives. */ + switch (curhdr->data[2]) { + case 0x00: + //return 1; + break; + case 0x01: + //return 1; + break; + case 0x07: + return 1; + case 0x09: + return 1; + case 0x1e: + return 1; + case 0x5a: + /* This one must be connection initiation... */ + return 1; + case 0x3c: + return 1; + case 0x33: + return 1; + case 0xaa: + return 1; + case 0x67: + return 1; + //default: + //printk(KERN_ALERT "HiPPIE: Found possible ares TCP session with data size %u and opcode 0x%.2x.\n",psize,curhdr->data[2]); + } + } + } + return 0; +} + +int pie_ares_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* Ares Protocol classifiers */ + if (curhdr->datalen >= 2) { + if (curhdr->data[0] == 0xe9) { + /* Found a potential Ares e9 (eDonkey-like) packet */ + u_int8_t rescount; + switch (curhdr->data[1]) { + case 0x60: + /* e9 60 [16 byte hash] [16 byte hash] */ + if (curhdr->datalen == 34) { + return 1; + } + break; + case 0x61: + /* e9 61 [16 byte hash] [1 byte count] [results (25 bytes) * count] */ + if (curhdr->datalen >= 19 && curhdr->datalen == 19 + (curhdr->data[18] * 25)) { + return 1; + } + break; + case 0x76: + /* e9 76 [16 byte hash] */ + if (curhdr->datalen == 18) { + return 1; + } + break; + case 0x55: + case 0x56: + /* e9 55/56 [16 byte hash] [reporting ip] [port (LE)] [port (LE)] 00 */ + if (curhdr->datalen == 27 && curhdr->data[26] == 0x00 && curhdr->data[22] == curhdr->data[24] && curhdr->data[23] == curhdr->data[25]) { + return 1; + } + break; + case 0x75: + break; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_ares_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *areshdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (areshdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate Ares P2P Session Header.\n"); + return NULL; + } + areshdr->protoindex = pie_proto_ares_fd; + areshdr->header = NULL; + areshdr->hlen = 0; + areshdr->datalen = curhdr->datalen; + areshdr->data = curhdr->data; + areshdr->next_hdr = NULL; + areshdr->proto_info = NULL; + return areshdr; +} + +void pie_ares_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_ares_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_ares_fd = pie_reg_protocol("ares",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_ares_new_session,&pie_ares_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_ares_session_cleanup,&pie_ares_packet_cleanup); + if (pie_proto_ares_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_ares_fd,&pie_ares_tcpfind); + pie_reg_subprotocol("udp",pie_proto_ares_fd,&pie_ares_udpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load ares module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("ares",pie_proto_ares_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/bittorrent.c linux-2.6.27.8-hippie/net/hippie/proto/bittorrent.c --- linux-2.6.27.8/net/hippie/proto/bittorrent.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/bittorrent.c 2008-02-08 10:35:52.000000000 -0600 @@ -0,0 +1,171 @@ +/* + * Hi-Performance Protocol Identification Engine BitTorrent Module - bittorrent.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include +#ifdef CONFIG_HIPPIE_HOSTINFO +#include +#endif + +u_int16_t pie_proto_bittorrent_fd = 0; +u_int16_t pie_proto_ipv4_fd_loc = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE BitTorrent Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_bittorrent_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for BitTorrent Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_bittorrent_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_bittorrent_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* Standard TCP BitTorrent Transfer connections */ + u_int8_t bitp[19] = {'B','i','t','T','o','r','r','e','n','t',' ','p','r','o','t','o','c','o','l'}; + if (curhdr->datalen >= 20 && pie_payload_search(curhdr->data + sizeof(u_int8_t),curhdr->data + sizeof(u_int8_t),bitp,19) != NULL) { + return 1; + } + return 0; +} + +int pie_bittorrent_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* UDP Trackerless Connections supported by at least Azureus and uTorrent. */ + u_int8_t udptl1[12] = {'d','1',':','a','d','2',':','i','d','2','0',':'}; + u_int8_t udptlresp[12] = {'d','1',':','r','d','2',':','i','d','2','0',':'}; + if (curhdr->datalen >= 12 && pie_payload_search(curhdr->data,curhdr->data,udptl1,12) != NULL) { + return 1; + } + if (curhdr->datalen >= 12 && pie_payload_search(curhdr->data,curhdr->data,udptlresp,12) != NULL) { + return 1; + } + /* Azureus DHT UDP Support */ + u_int8_t dhtudp1[5] = {0x0e,0x00,0x00,0x00,0x00}; + u_int8_t dhtudp2[5] = {0x0d,0x00,0x00,0x00,0x00}; + u_int8_t dhtudp3[5] = {0x0c,0x00,0x00,0x00,0x00}; + if (curhdr->datalen >= 21 && pie_payload_search(&curhdr->data[16],&curhdr->data[16],dhtudp1,5) != NULL) { + return 1; + } + if (curhdr->datalen >= 21 && pie_payload_search(&curhdr->data[16],&curhdr->data[16],dhtudp2,5) != NULL) { + return 1; + } + if (curhdr->datalen >= 21 && pie_payload_search(&curhdr->data[16],&curhdr->data[16],dhtudp3,5) != NULL) { + return 1; + } +#ifdef CONFIG_HIPPIE_HOSTINFO + if (curhdr->datalen >= 3 && pktinfo->network_hdr->protoindex == pie_proto_ipv4_fd_loc) { + struct pie_protohdr_ipv4 *v4info = (struct pie_protohdr_ipv4 *) pktinfo->network_hdr->proto_info; + u_int32_t srcaddr = ((v4info->srcip[0] * 256 + v4info->srcip[1]) * 256 + v4info->srcip[2]) * 256 + v4info->srcip[3]; + u_int32_t dstaddr = ((v4info->dstip[0] * 256 + v4info->dstip[1]) * 256 + v4info->dstip[2]) * 256 + v4info->dstip[3]; + if (curhdr->data[2] == 0x02) { + /* This could be one of the new BitTorrent UDP packets we're seeing */ + u_int16_t index = make_int16(curhdr->data); + u_int16_t hostindex = pie_hostinfo_get_num(srcaddr,pie_proto_bittorrent_fd,1); + if (hostindex > 0 && index > hostindex - 5 && hostindex + 20 > index) { + /* This looks like it should be proper BitTorrent */ + pie_hostinfo_set_num(srcaddr,pie_proto_bittorrent_fd,1,index,30); + return 1; + } + } + if (curhdr->datalen == 11) { + u_int32_t pktaddr = make_int32(&curhdr->data[3]); + if (pktaddr == dstaddr && curhdr->data[2] % 16 == 5) { + /* Destination IP address is in these octets! */ + /* First two bytes should be the destination hosts current index value */ + u_int16_t index = make_int16(curhdr->data); + //printk(KERN_ALERT "HiPPIE: Setting bittorrent index value of %u to %u.\n",dstaddr,index); + pie_hostinfo_set_num(dstaddr,pie_proto_bittorrent_fd,1,index,30); + return 1; + } + } + } +#endif + + /* Another UDP Trackerless protocol, possibly still part of DHT. */ + //u_int8_t udptl2[4] = {0x00,0x00,0x04,0x01}; /* x byte packets */ + //u_int8_t udptl3[4] = {0x00,0x00,0x04,0x05}; /* x byte packets */ + /*if (curhdr->datalen >= 7 && pie_payload_search(curhdr->data,curhdr->data,cmd,7) != NULL) { + return 1; + }*/ + return 0; +} + +int pie_bittorrent_httpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* HTTP BitTorrent Tracker Connections */ + u_int8_t infohash[11] = {'?','i','n','f','o','_','h','a','s','h','='}; + u_int8_t http[6] = {' ','H','T','T','P','/'}; + if (curhdr->datalen > 11) { + u_int8_t *hashloc = pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],infohash,11); + if (hashloc != NULL) { + if (pie_payload_search(hashloc,&curhdr->data[curhdr->datalen - 1],http,6) != NULL) { + return 1; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_bittorrent_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *bittorrenthdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (bittorrenthdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate BitTorrent Session Header.\n"); + return NULL; + } + bittorrenthdr->protoindex = pie_proto_bittorrent_fd; + bittorrenthdr->header = NULL; + bittorrenthdr->hlen = 0; + bittorrenthdr->datalen = curhdr->datalen; + bittorrenthdr->data = curhdr->data; + bittorrenthdr->next_hdr = NULL; + bittorrenthdr->proto_info = NULL; + return bittorrenthdr; +} + +void pie_bittorrent_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_bittorrent_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_bittorrent_fd = pie_reg_protocol("bittorrent",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_bittorrent_new_session,&pie_bittorrent_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_bittorrent_session_cleanup,&pie_bittorrent_packet_cleanup); + pie_proto_ipv4_fd_loc = pie_get_protocolid("ipv4"); + if (pie_proto_bittorrent_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_bittorrent_fd,&pie_bittorrent_tcpfind); + pie_reg_subprotocol("udp",pie_proto_bittorrent_fd,&pie_bittorrent_udpfind); + pie_reg_subprotocol("http",pie_proto_bittorrent_fd,&pie_bittorrent_httpfind); + //pie_reg_subprotocol("tcp",pie_proto_bittorrent_fd,&pie_bittorrent_httpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load bittorrent module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("bittorrent",pie_proto_bittorrent_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/dns.c linux-2.6.27.8-hippie/net/hippie/proto/dns.c --- linux-2.6.27.8/net/hippie/proto/dns.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/dns.c 2008-02-08 10:35:52.000000000 -0600 @@ -0,0 +1,211 @@ +/* + * Hi-Performance Protocol Identification Engine DNS Module - dns.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_dns_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE DNS Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +/* Allowed query flags (Located at Bytes 2 & 3 of UDP Data and 4 & 5 of TCP Data) */ +#define NUMQFLAGS 3 +u_int16_t qflags[NUMQFLAGS] = { + 0x0000, + 0x0010, /* Non-auth OK standard query */ + 0x0100}; /* Recursive standard query */ + +/* Allowed query types (2 bytes following the null byte after a query) */ +#define NUMQTYPES 7 +u_int16_t qtypes[NUMQTYPES] = { + 0x0000, /* ANY Record */ + 0x0001, /* A Record */ + 0x000C, /* PTR Record */ + 0x000F, /* MX Record */ + 0x0010, /* TXT Record */ + 0x001C, /* AAAA Record */ + 0x0026 /* A6 Record */ +}; + +u_int8_t nullbyte = 0x00; +u_int16_t inclass = 0x0001; + +struct pie_protocol_sess *pie_dns_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for DNS Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_dns_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_dns_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* UDP DNS Query */ + if (curhdr->datalen > 30) { + int foundqflags = 0; + int foundqtype = 0; + int qtypespass = 1; + int i,j; + /* This value is the number of questions being asked by the DNS querier. Each question will meet a criteria */ + u_int16_t qcount = make_int16(&curhdr->data[4]); + u_int16_t cursor; + u_int16_t pktqflag = make_int16(&curhdr->data[2]); + /* Query Flags checking... verifying that the query flags of the DNS query fall within space. */ + for (i = 0; i < NUMQFLAGS; i++) { + /* Check for request */ + //u_int16_t pktqflag = 256 * curhdr->data[2] + curhdr->data[3]; //(u_int16_t *)&curhdr->data[2]; + if (pktqflag == qflags[i]) { + foundqflags = 1; + break; + } + } + if (foundqflags != 1 || qcount > 3 || curhdr->data[12] == nullbyte) { + return 0; + } + cursor = 12; + if (curhdr->datalen < (12 + (qcount * 15))) { + /* Packet isn't long enough to support sufficiently long queries. */ + return 0; + } + //printk(KERN_ALERT "HiPPIE: DNS Check - qcount %u qflags %u/%u pktlen %u\n",qcount,pktqflag,foundqflags,curhdr->datalen); + for (i = 0; i < qcount; i++) { + while (curhdr->data[cursor] != nullbyte) { + u_int8_t lcount = curhdr->data[cursor]; + if (cursor + lcount + 6 > curhdr->datalen) { + return 0; + } + cursor += lcount + 1; + } + // Now we should be at the cursor of the end of the query + u_int16_t pktqtype = make_int16(&curhdr->data[cursor + 1]); + u_int16_t pktclass = make_int16(&curhdr->data[cursor + 3]); + for (j = 0; j < NUMQTYPES; j++) { + // Check for Query Types + if (pktqtype == qtypes[j] && pktclass == inclass) { + foundqtype = 1; + break; + } + } + if (foundqtype == 0) { + return 0; + } + cursor += 6; + } + return 1; + } + return 0; +} + +int pie_dns_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen > 32) { + if (curhdr->data[0] * 256 + curhdr->data[1] + 2 == curhdr->datalen) { + int foundqflags = 0; + int foundqtype = 0; + int qtypespass = 1; + int i,j; + /* This value is the number of questions being asked by the DNS querier. Each question will meet a criteria */ + u_int16_t qcount = make_int16(&curhdr->data[6]); + u_int16_t cursor; + u_int16_t pktqflag = make_int16(&curhdr->data[4]); + /* Query Flags checking... verifying that the query flags of the DNS query fall within space. */ + for (i = 0; i < NUMQFLAGS; i++) { + /* Check for request */ + if (pktqflag == qflags[i]) { + foundqflags = 1; + break; + } + } + if (foundqflags != 1 || qcount > 3 || curhdr->data[14] == nullbyte) { + return 0; + } + cursor = 14; + if (curhdr->datalen < (14 + (qcount * 15))) { + return 0; + } + for (i = 0; i < qcount; i++) { + while (curhdr->data[cursor] != nullbyte) { + u_int8_t lcount = curhdr->data[cursor]; + cursor += lcount + 1; + if (cursor + 5 > curhdr->datalen) { + return 0; + } + } + u_int16_t pktqtype = make_int16(&curhdr->data[cursor + 1]); + u_int16_t pktclass = make_int16(&curhdr->data[cursor + 3]); + for (j = 0; j < NUMQTYPES; j++) { + /* Check for Query Types */ + if (pktqtype == qtypes[j] && pktclass == inclass) { + foundqtype = 1; + break; + } + } + if (foundqtype == 0) { + return 0; + } + cursor += 5; + } + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_dns_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *dnshdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (dnshdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate DNS Session Header.\n"); + return NULL; + } + dnshdr->protoindex = pie_proto_dns_fd; + dnshdr->header = NULL; + dnshdr->hlen = 0; + dnshdr->datalen = curhdr->datalen; + dnshdr->data = curhdr->data; + dnshdr->next_hdr = NULL; + dnshdr->proto_info = NULL; + return dnshdr; +} + +void pie_dns_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_dns_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_dns_fd = pie_reg_protocol("dns",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_dns_new_session,&pie_dns_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_dns_session_cleanup,&pie_dns_packet_cleanup); + if (pie_proto_dns_fd > 0) { + pie_reg_subprotocol("udp",pie_proto_dns_fd,&pie_dns_udpfind); + pie_reg_subprotocol("tcp",pie_proto_dns_fd,&pie_dns_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load dns module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("dns",pie_proto_dns_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/edonkey.c linux-2.6.27.8-hippie/net/hippie/proto/edonkey.c --- linux-2.6.27.8/net/hippie/proto/edonkey.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/edonkey.c 2008-02-21 11:32:51.000000000 -0600 @@ -0,0 +1,331 @@ +/* + * Hi-Performance Protocol Identification Engine eDonkey Module - edonkey.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_edonkey_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE eDonkey Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_edonkey_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for eDonkey Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_edonkey_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_edonkey_tagdataparse(struct pie_protocol_hdr *curhdr, int offset, int taglistlen) { + int search = offset; + int i; + for (i = 0; i < taglistlen; i++) { + u_int8_t tagtype = curhdr->data[search]; + switch(tagtype) { + case 0x02: + if (curhdr->datalen >= search + 2) { + u_int16_t tagnamesize = make_int16_le(&curhdr->data[search + 1]); + if (curhdr->datalen >= search + 3 + tagnamesize + 2) { + u_int16_t valsize = make_int16_le(&curhdr->data[search + 3 + tagnamesize]); + if (curhdr->datalen >= search + 3 + tagnamesize + 2 + valsize) { + search += 3 + tagnamesize + 2 + valsize; + break; + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + break; + case 0x03: + if (curhdr->datalen >= search + 2) { + u_int16_t tagnamesize = make_int16_le(&curhdr->data[search + 1]); + if (curhdr->datalen >= search + 3 + tagnamesize + 4) { + search += 3 + tagnamesize + 4; + break; + } else { + return 0; + } + } else { + return 0; + } + break; + case 0x09: + if (curhdr->datalen >= search + 2) { + u_int16_t tagnamesize = make_int16_le(&curhdr->data[search + 1]); + if (curhdr->datalen >= search + 3 + tagnamesize + 1) { + search += 3 + tagnamesize + 1; + break; + } else { + return 0; + } + } else { + return 0; + } + break; + case 0x00: + if (curhdr->datalen >= search + 2) { + search += 3; + break; + } else { + return 0; + } + break; + case 0x08: + if (curhdr->datalen >= search + 2) { + u_int16_t tagnamesize = make_int16_le(&curhdr->data[search + 1]); + if (curhdr->datalen >= search + 3 + tagnamesize + 2) { + search += 3 + tagnamesize + 2; + break; + } else { + return 0; + } + } else { + return 0; + } + break; + default: + //printk(KERN_INFO "Found potential Edonkey/Overnet/Kad tag type %02x.\n",tagtype); + return 0; + } + } + if (search == curhdr->datalen) { + return 1; + } + return 0; +} + +int pie_edonkey_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 5) { + /* Check for commands */ + if (curhdr->data[0] == 0xe3) { + u_int32_t cmdlen = ((curhdr->data[4] * 256 + curhdr->data[3]) * 256 + curhdr->data[2]) * 256 + curhdr->data[1]; + if (curhdr->datalen == cmdlen + 5) { + return 1; + } + } + } + return 0; +} + +int pie_kademlia_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 4) { + if (curhdr->data[0] == 0xe4) { + switch(curhdr->data[2]) { + case 0x20: + case 0x21: + switch(curhdr->data[3]) { + case 0x01: + case 0x02: + case 0x04: + case 0x0b: + if (curhdr->datalen == 35) { + return 1; + } + break; + case 0x03: + if (curhdr->datalen == 19) { + return 1; + } + break; + } + break; + case 0x11: + case 0x19: + if (curhdr->datalen >= 22) { + u_int8_t taglen = curhdr->data[21]; + if (pie_edonkey_tagdataparse(curhdr,22,taglen)) { + return 1; + } + } + break; + case 0x29: + if (curhdr->datalen >= 19) { + if (curhdr->datalen == 19 + (curhdr->data[18] * 25)) { + return 1; + } + } + break; + case 0x43: + case 0x44: + if (curhdr->datalen >= 37) { + u_int8_t taglen = curhdr->data[36]; + if (pie_edonkey_tagdataparse(curhdr,37,taglen)) { + return 1; + } + } + break; + } + } + if (curhdr->data[0] == 0xe5 && curhdr->data[2] == 0x78 && curhdr->data[3] == 0xda) { + switch(curhdr->data[1]) { + case 0x29: + case 0x44: + case 0x43: + return 1; + } + } + } + return 0; +} + +int pie_overnet_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 2) { + /* Check for commands */ + if (curhdr->data[0] == 0xe3) { + switch (curhdr->data[1]) { + case 0x0a: + /* Connect */ + if (curhdr->datalen == 25) { + return 1; + } + break; + case 0x0b: + /* Connect Reply */\ + if (curhdr->datalen >= 3 && curhdr->datalen == 3 + (23 * curhdr->data[2])) { + return 1; + } + break; + case 0x0c: + /* Publicize */ + if (curhdr->datalen == 25) { + return 1; + } + break; + case 0x0d: + /* Publicize reply */ + if (curhdr->datalen == 2) { + return 1; + } + break; + case 0x0e: + /* Search */ + if (curhdr->datalen == 19) { + return 1; + } + break; + case 0x0f: + /* Search Reply */ + if (curhdr->datalen >= 19 && curhdr->datalen == 19 + (23 * curhdr->data[18])) { + return 1; + } + break; + case 0x10: + /* Get Search Results */ + if (curhdr->datalen == 23) { + return 1; + } + break; + case 0x11: + /* Search Result */ + break; + case 0x12: + /* No Search Result */ + if (curhdr->datalen == 18) { + return 1; + } + break; + case 0x13: + /* Publish */ + /* Wait and see */ + if (curhdr->datalen >= 38) { + u_int32_t taglen = make_int32_le(&curhdr->data[34]); + if (pie_edonkey_tagdataparse(curhdr,38,taglen)) { + return 1; + } + } + break; + case 0x14: + /* Publish Reply */ + if (curhdr->datalen == 18) { + return 1; + } + break; + case 0x1B: + /* Get My IP */ + if (curhdr->datalen == 4) { + return 1; + } + break; + case 0x1C: + /* Get My IP Reply */ + if (curhdr->datalen == 6) { + return 1; + } + break; + case 0x1D: + /* Get My IP Done */ + if (curhdr->datalen == 2) { + return 1; + } + break; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_edonkey_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *edonkeyhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (edonkeyhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate eDonkey Session Header.\n"); + return NULL; + } + edonkeyhdr->protoindex = pie_proto_edonkey_fd; + edonkeyhdr->header = NULL; + edonkeyhdr->hlen = 0; + edonkeyhdr->datalen = curhdr->datalen; + edonkeyhdr->data = curhdr->data; + edonkeyhdr->next_hdr = NULL; + edonkeyhdr->proto_info = NULL; + return edonkeyhdr; +} + +void pie_edonkey_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_edonkey_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_edonkey_fd = pie_reg_protocol("edonkey",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_edonkey_new_session,&pie_edonkey_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_edonkey_session_cleanup,&pie_edonkey_packet_cleanup); + if (pie_proto_edonkey_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_edonkey_fd,&pie_edonkey_tcpfind); + pie_reg_subprotocol("udp",pie_proto_edonkey_fd,&pie_overnet_udpfind); + pie_reg_subprotocol("udp",pie_proto_edonkey_fd,&pie_kademlia_udpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load edonkey module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("edonkey",pie_proto_edonkey_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/esp.c linux-2.6.27.8-hippie/net/hippie/proto/esp.c --- linux-2.6.27.8/net/hippie/proto/esp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/esp.c 2008-01-30 14:41:34.000000000 -0600 @@ -0,0 +1,198 @@ +/* + * Hi-Performance Protocol Identification Engine ESP Protocol Handling Code - pie_proto_esp.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +u_int16_t pie_proto_esp_fd = 0; +u_int16_t pie_proto_ipv4_fd_esp = 0; + +struct pie_protohdr_esp{ + u_int16_t spi; +}; + +struct pie_protosess_esp{ + u_int16_t spi; +}; + +#define PIE_STATE_TIMEOUT_ESP 300 + +#define PIE_STATE_ESP_UP 5000 + +u_int8_t pie_esp_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess, u_int8_t direction) { + struct pie_protosess_esp *espsess = (struct pie_protosess_esp *) sess->proto_info; + struct pie_protohdr_esp *esphdr = (struct pie_protohdr_esp *) pkthdr->proto_info; + switch (direction) { + case 0: + if (espsess->spi == esphdr->spi) { + return 1; + } + break; + case 1: + if (espsess->spi == esphdr->spi) { + return 1; + } + break; + } + return 0; +} + +struct pie_protocol_sess *pie_esp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_esp *espsess; + struct pie_protohdr_esp *esphdr = (struct pie_protohdr_esp *) pkthdr->proto_info; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for ESP session header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_esp_fd; + sess->next_sess = NULL; + espsess = kmalloc(sizeof(struct pie_protosess_esp),GFP_KERNEL); + if (espsess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for ESP session information.\n"); + kfree(sess); + return NULL; + } + espsess->spi = esphdr->spi; + sess->proto_info = (void *) espsess; + return sess; +} + +int pie_esp_proc_packet(struct pie_sess_info *session, struct pie_protocol_hdr *pkthdr) { + struct pie_protohdr_esp *espinfo = (struct pie_protohdr_esp *)pkthdr->proto_info; + read_lock(session->lock); + if (atomic_read(&session->state) == PIE_STATE_NEW) { + atomic_set(&session->state,PIE_STATE_ESP_UP); + } + switch (atomic_read(&session->state)) { + case PIE_STATE_ESP_UP: + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_ESP); + break; + default: + pie_session_timeout_reset(session,15); + break; + } + read_unlock(session->lock); + return 0; +} + +int pie_esp_ipv4find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr == NULL) { + /* This shouldn't ever happen! */ + printk(KERN_ALERT "HiPPIE: ESP IPv4 Packet detection was passed a NULL header.\n"); + return 0; + } + if (curhdr->protoindex == pie_proto_ipv4_fd_esp) { + struct pie_protohdr_ipv4 *ipv4hdr = (struct pie_protohdr_ipv4 *) curhdr->proto_info; + if (ipv4hdr != NULL && ipv4hdr->proto == 50) { + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_esp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *esp_hdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + struct pie_protohdr_esp *protoinfo; + if (esp_hdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate ESP Session Header Information.\n"); + return NULL; + } + esp_hdr->protoindex = pie_proto_esp_fd; + + if (curhdr == NULL) { + /* This should NEVER happen */ + printk(KERN_ALERT "HiPPIE: ESP Mockup received a NULL protocol header!\n"); + return NULL; + } + esp_hdr->header = curhdr->data; + esp_hdr->hlen = 8; + esp_hdr->datalen = curhdr->datalen - esp_hdr->hlen; + if (esp_hdr->datalen > 0) { + esp_hdr->data = &curhdr->data[esp_hdr->hlen]; + } else { + esp_hdr->data = NULL; + } + esp_hdr->next_hdr = NULL; + protoinfo = kmalloc(sizeof(struct pie_protohdr_esp),GFP_KERNEL); + if (protoinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate ESP Session Information.\n"); + kfree(esp_hdr); + return NULL; + } + protoinfo->spi = ((esp_hdr->header[0] * 256 + esp_hdr->header[1]) * 256 + esp_hdr->header[2]) * 256 + esp_hdr->header[3]; + esp_hdr->proto_info = protoinfo; + return esp_hdr; +} + +int pie_esp_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer) { + struct pie_protosess_esp *espinfo = (struct pie_protosess_esp *) psess->proto_info; + if (espinfo == NULL) { + printk(KERN_ALERT "HiPPIE: ESP session is missing session information!\n"); + return 0; + } + int len = 0; + len += sprintf(buffer+len,"spi %u",espinfo->spi); + switch(atomic_read(&sess->state)) { + case PIE_STATE_ESP_UP: + len += sprintf(buffer+len," state ESP_UP"); + break; + } + return len; +} + +u_int8_t pie_esp_get_sess_bucket(struct pie_protocol_hdr *pkthdr, u_int8_t direction) { + struct pie_protohdr_esp *esphdr = (struct pie_protohdr_esp *) pkthdr->proto_info; + switch (direction) { + case 0: + return esphdr->spi % 256; + break; + case 1: + return esphdr->spi % 256; + break; + } + return 0; +} + +void pie_esp_session_cleanup(struct pie_protocol_sess *sess) { + struct pie_protosess_esp *espsess = (struct pie_protosess_esp *) sess->proto_info; + kfree(espsess); + kfree(sess); +} + +void pie_esp_packet_cleanup(struct pie_protocol_hdr *hdr) { + struct pie_protohdr_esp *esphdr = (struct pie_protohdr_esp *) hdr->proto_info; + kfree(esphdr); + kfree(hdr); +} + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("Hi-Performance Protocol Identification Engine ESP Protocol Packet Analysis and Sessioning Handler"); +MODULE_LICENSE("GPL"); + +static int __init init(void) { + pie_proto_esp_fd = pie_reg_protocol("esp",PIE_PROTOTYPE_TRANSPORT,PIE_ENCAP_TAGGED,0,&pie_esp_get_sess_bucket,&pie_esp_session_compare,&pie_esp_new_session,&pie_esp_packet_mockup,NULL,NULL,NULL,NULL,&pie_esp_proc_packet,&pie_esp_proc_print,&pie_esp_session_cleanup,&pie_esp_packet_cleanup); + pie_reg_subprotocol("ipv4",pie_proto_esp_fd,&pie_esp_ipv4find); + pie_proto_ipv4_fd_esp = pie_get_protocolid("ipv4"); + return 0; +} + +static void __exit fini(void) { + pie_unreg_protocol("esp",pie_proto_esp_fd); +} + +module_init(init); +module_exit(fini); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/fasttrack.c linux-2.6.27.8-hippie/net/hippie/proto/fasttrack.c --- linux-2.6.27.8/net/hippie/proto/fasttrack.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/fasttrack.c 2008-02-06 11:45:18.000000000 -0600 @@ -0,0 +1,118 @@ +/* + * Hi-Performance Protocol Identification Engine FastTrack Module - fasttrack.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_fasttrack_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE FastTrack Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_fasttrack_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for FastTrack Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_fasttrack_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_fasttrack_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + u_int8_t ua[23] = {'U','s','e','r','A','g','e','n','t',':',' ','K','a','z','a','a','C','l','i','e','n','t'}; + u_int8_t xkazaa[7] = {'X','-','K','a','z','a','a'}; + if (curhdr->datalen >= 23 && pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],ua,23) != NULL) { + return 1; + } + if (curhdr->datalen >= 7 && pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],xkazaa,7) != NULL) { + return 1; + } + return 0; +} + +int pie_fasttrack_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + u_int8_t udpstart[4] = {0x27, 0x00, 0x00, 0x00}; + u_int8_t kazaa[5] = {'K','a','Z','a','A'}; + if (curhdr->datalen >= 4 && pie_payload_search(curhdr->data,curhdr->data,udpstart,4) != NULL) { + if (curhdr->datalen >= 11 && pie_payload_search(curhdr->data + (sizeof(u_int8_t) * 6),curhdr->data + (sizeof(u_int8_t) * 6),kazaa,5) != NULL) { + return 1; + } + } + /*if (curhdr->datalen >= 4 && pie_payload_search(curhdr->data,curhdr->data,udpresp,4) != NULL) { + if (curhdr->datalen >= 16 && pie_payload_search(curhdr->data + (sizeof(u_int8_t) * 11),curhdr->data + (sizeof(u_int8_t) * 11),kazaa,5) != NULL) { + pie_tcp_predict(PIE_FASTTRACK_SIGCODE,packet->srcip,curhdr->sport,packet->dstip,0); + return 1; + } + }*/ + return 0; +} + +/*static void pie_fasttrack_udppersist(struct pie_packet_info *packet) { + u_int8_t udpresp[4] = {0x28, 0x00, 0x00, 0x00}; + u_int8_t kazaa[5] = {'K','a','Z','a','A'}; + if (curhdr->datalen >= 4 && pie_payload_search(curhdr->data,curhdr->data,udpresp,4) != NULL) { + if (curhdr->datalen >= 16 && pie_payload_search(curhdr->data + (sizeof(u_int8_t) * 11),curhdr->data + (sizeof(u_int8_t) * 11),kazaa,5) != NULL) { + //pie_tcp_predict(PIE_FASTTRACK_SIGCODE,packet->srcip,curhdr->sport,packet->dstip,0); + } + } +}*/ + +struct pie_protocol_hdr *pie_fasttrack_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *fasttrackhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (fasttrackhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate FastTrack Session Header.\n"); + return NULL; + } + fasttrackhdr->protoindex = pie_proto_fasttrack_fd; + fasttrackhdr->header = NULL; + fasttrackhdr->hlen = 0; + fasttrackhdr->datalen = curhdr->datalen; + fasttrackhdr->data = curhdr->data; + fasttrackhdr->next_hdr = NULL; + fasttrackhdr->proto_info = NULL; + return fasttrackhdr; +} + +void pie_fasttrack_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_fasttrack_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_fasttrack_fd = pie_reg_protocol("fasttrack",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_fasttrack_new_session,&pie_fasttrack_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_fasttrack_session_cleanup,&pie_fasttrack_packet_cleanup); + if (pie_proto_fasttrack_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_fasttrack_fd,&pie_fasttrack_tcpfind); + pie_reg_subprotocol("udp",pie_proto_fasttrack_fd,&pie_fasttrack_udpfind); + //pie_reg_persist("udp",pie_proto_fasttrack_fd,&pie_fasttrack_udppersist); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load fasttrack module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("fasttrack",pie_proto_fasttrack_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/ftp.c linux-2.6.27.8-hippie/net/hippie/proto/ftp.c --- linux-2.6.27.8/net/hippie/proto/ftp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/ftp.c 2008-02-06 11:45:18.000000000 -0600 @@ -0,0 +1,233 @@ +/* + * Hi-Performance Protocol Identification Engine FTP Module - ftp.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef CONFIG_HIPPIE_PREDICTION +#include +#endif + +u_int16_t pie_proto_ftp_fd = 0; +u_int16_t pie_proto_ftpdata_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE FTP Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_ftp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for FTP Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_ftp_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +struct pie_protocol_sess *pie_ftpdata_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for FTP-Data Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_ftpdata_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_ftp_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + u_int8_t request[3] = {0x32,0x32,0x30}; /* "220 " */ + u_int8_t response[5] = {0x55,0x53,0x45,0x52,0x20}; /* "USER " */ + /* Check for request */ + if (pie_session_get_value(pktinfo->session,pie_proto_ftp_fd,1) == NULL && curhdr->datalen >= 3) { + if (curhdr->datalen >= 3 && pie_payload_search(curhdr->data,curhdr->data,request,3) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_ftp_fd,1,(void *)1); + return 0; + } + } else if ((int)pie_session_get_value(pktinfo->session,pie_proto_ftp_fd,1) == 1 && curhdr->datalen >= 5) { + if (curhdr->datalen >= 3 && pie_payload_search(curhdr->data,curhdr->data,response,5) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_ftp_fd,1,(void *)2); + return 1; + } + } + return 0; +} + +static void persist(struct pie_sess_info *sess, struct pie_protocol_hdr *curhdr) { + u_int8_t pasvcmd[4] = {0x50,0x41,0x53,0x56}; /* PASV */ + u_int8_t portcmd[5] = {0x50,0x4F,0x52,0x54,0x20}; /* PORT */ + u_int8_t pasv227[27] = {0x32,0x32,0x37,0x20,0x45,0x6e,0x74,0x65,0x72,0x69,0x6e,0x67,0x20,0x50,0x61,0x73,0x73,0x69,0x76,0x65,0x20,0x4d,0x6f,0x64,0x65,0x20,0x28}; + if (curhdr->datalen >= 4 && pie_payload_search(curhdr->data,curhdr->data,pasvcmd,4) != NULL) { + /* Session is switching to PASSIVE FTP. The external connection will be initiated by the client */ + pie_session_set_value(sess,pie_proto_ftp_fd,2,(void *)1); + } + if (curhdr->datalen >= 5 && pie_session_get_value(sess,pie_proto_ftp_fd,2) == NULL && pie_payload_search(curhdr->data,curhdr->data,portcmd,5) != NULL) { + /* Initiating a standard mode FTP session. This external connection will come in from the server to the HOST/PORT we sent here. */ +#ifdef CONFIG_HIPPIE_PREDICTION + /* Create the predicted session */ + struct pie_sess_info *pred = pie_prediction_create(); + u_int8_t oct[4],port1,port2; + /* Add an IPv4 header */ + if (pred != NULL) { + struct pie_protocol_sess *iphdr = pie_prediction_add_header(pred,pie_get_protocolid("ipv4")); + if (iphdr != NULL) { + /* Set the IPv4 Destination Address */ + char *parse = (char *)&curhdr->data[5]; + parse = pie_ipv4_addr_read(parse,1,oct); + pie_prediction_parameter(iphdr,"dst",PIE_DTYPE_POINTER,oct); + /* Set the IP protocol # to TCP (6) */ + pie_prediction_parameter(iphdr,"proto",PIE_DTYPE_NUM,(void *) 6); + /* Create the TCP header */ + struct pie_protocol_sess *tcphdr = pie_prediction_add_header(pred,pie_get_protocolid("tcp")); + if (tcphdr != NULL) { + /* Set the destination port */ + parse++; + port1 = simple_strtoul(parse,&parse,10); + parse++; + port2 = simple_strtoul(parse,&parse,10); + pie_prediction_parameter(tcphdr,"dport",PIE_DTYPE_NUM,(void *) (port1 * 256 + port2)); + if (pie_prediction_add_header(pred,pie_proto_ftpdata_fd) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to add ftp-data header to FTP prediction.\n"); + } else { + pie_prediction_schedule(pred); + } + } else { + printk(KERN_INFO "HiPPIE: FTP Prediction failed to allocate TCP header to prediction.\n"); + } + } else { + printk(KERN_INFO "HiPPIE: FTP Prediction failed to allocate IPv4 header to prediction.\n"); + } + } +#endif + } + if (curhdr->datalen >= 48 && pie_session_get_value(sess,pie_proto_ftp_fd,2) != NULL && pie_payload_search(curhdr->data,curhdr->data,pasv227,27) != NULL) { + /* Initiating a PASSIVE mode FTP session. This external connection will begin from the client and to go the HOST and PORT we are told in this message. */ +#ifdef CONFIG_HIPPIE_PREDICTION + struct pie_sess_info *pred = pie_prediction_create(); + u_int8_t oct[4],port1 = 0,port2 = 0; + if (pred != NULL) { + /* Add an IPv4 header */ + struct pie_protocol_sess *iphdr = pie_prediction_add_header(pred,pie_get_protocolid("ipv4")); + if (iphdr != NULL) { + /* Set the IPv4 Destination Address */ + char *parse = (char *)&curhdr->data[27]; + parse = pie_ipv4_addr_read(parse,1,oct); + pie_prediction_parameter(iphdr,"dst",PIE_DTYPE_POINTER,oct); + /* Set the IP protocol # to TCP (6) */ + pie_prediction_parameter(iphdr,"proto",PIE_DTYPE_NUM,(void *) 6); + /* Create the TCP header */ + struct pie_protocol_sess *tcphdr = pie_prediction_add_header(pred,pie_get_protocolid("tcp")); + if (tcphdr != NULL) { + /* Set the destination port */ + parse++; + port1 = simple_strtoul(parse,&parse,10); + parse++; + port2 = simple_strtoul(parse,&parse,10); + pie_prediction_parameter(tcphdr,"dport",PIE_DTYPE_NUM,(void *) (port1 * 256 + port2)); + if (pie_prediction_add_header(pred,pie_proto_ftpdata_fd) == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to add ftp-data header to FTP prediction.\n"); + } else { + pie_prediction_schedule(pred); + } + } else { + printk(KERN_INFO "HiPPIE: FTP Prediction failed to allocate TCP header to prediction.\n"); + } + } else { + printk(KERN_INFO "HiPPIE: FTP Prediction failed to allocate IPv4 header to prediction.\n"); + } + } +#endif + } +} + +struct pie_protocol_hdr *pie_ftp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *ftphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (ftphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate FTP Session Header.\n"); + return NULL; + } + ftphdr->protoindex = pie_proto_ftp_fd; + ftphdr->header = NULL; + ftphdr->hlen = 0; + ftphdr->datalen = curhdr->datalen; + ftphdr->data = curhdr->data; + ftphdr->next_hdr = NULL; + ftphdr->proto_info = NULL; + return ftphdr; +} + +struct pie_protocol_hdr *pie_ftpdata_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *ftphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (ftphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate FTP-Data Session Header.\n"); + return NULL; + } + ftphdr->protoindex = pie_proto_ftpdata_fd; + ftphdr->header = NULL; + ftphdr->hlen = 0; + ftphdr->datalen = curhdr->datalen; + ftphdr->data = curhdr->data; + ftphdr->next_hdr = NULL; + ftphdr->proto_info = NULL; + return ftphdr; +} + +void pie_ftp_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_ftpdata_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_ftp_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +void pie_ftpdata_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_ftp_fd = pie_reg_protocol("ftp",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_ftp_new_session,&pie_ftp_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_ftp_session_cleanup,&pie_ftp_packet_cleanup); + pie_proto_ftpdata_fd = pie_reg_protocol("ftp-data",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,1,NULL,NULL,&pie_ftpdata_new_session,&pie_ftpdata_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_ftpdata_session_cleanup,&pie_ftpdata_packet_cleanup); + if (pie_proto_ftp_fd > 0 && pie_proto_ftpdata_fd > 0) { + if (pie_reg_subprotocol("tcp",pie_proto_ftp_fd,&pie_ftp_tcpfind) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register FTP as a subprotocol of TCP.\n"); + } +#ifdef CONFIG_HIPPIE_PERSISTANCE + if (pie_reg_persist(pie_proto_ftp_fd,&persist) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register FTP persistant listener.\n"); + } +#endif + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load ftp modules.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("ftp",pie_proto_ftp_fd); + pie_unreg_protocol("ftp-data",pie_proto_ftpdata_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/gnutella.c linux-2.6.27.8-hippie/net/hippie/proto/gnutella.c --- linux-2.6.27.8/net/hippie/proto/gnutella.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/gnutella.c 2008-02-08 10:35:52.000000000 -0600 @@ -0,0 +1,123 @@ +/* + * Hi-Performance Protocol Identification Engine Gnutella Module - gnutella.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_gnutella_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE Gnutella Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_gnutella_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for Gnutella Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_gnutella_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_gnutella_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* Standard TCP Gnutella Transfer connections */ + u_int8_t gnuconn[17] = {'G','N','U','T','E','L','L','A',' ','C','O','N','N','E','C','T','/'}; + if (curhdr->datalen >= 17 && pie_payload_search(curhdr->data,curhdr->data,gnuconn,17) != NULL) { + return 1; + } + return 0; +} + +int pie_gnutella_httpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* HTTP Gnutella Download Connections */ + u_int8_t geturi[26] = {'G','E','T',' ','/','u','r','i','-','r','e','s','/','N','2','R','?','u','r','n',':','s','h','a','1',':'}; + if (curhdr->datalen >= 26 && pie_payload_search(curhdr->data,curhdr->data,geturi,26) != NULL) { + return 1; + } + return 0; +} + +int pie_gnutella_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 20) { + /* Gnutella/Limewire DHT? UDP implementation */ + u_int16_t code1 = make_int16_le(&curhdr->data[15]); //curhdr->data[16] * 256 + curhdr->data[15]; + u_int16_t code2 = make_int16_le(&curhdr->data[17]); //curhdr->data[18] * 256 + curhdr->data[17]; + u_int16_t length = make_int32_le(&curhdr->data[19]); //curhdr->data[20] * 256 + curhdr->data[19]; + if (length + 23 == curhdr->datalen && code1 == 0) { + switch (code2) { + case 0: + /* Valid */ + return 1; + break; + case 1: + /* Valid */ + return 1; + break; + default: + printk(KERN_INFO "HiPPIE: Found potential Gnutella UDP packet with code2 of %u, not classifying.\n",code2); + break; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_gnutella_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *gnutellahdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (gnutellahdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate Gnutella Session Header.\n"); + return NULL; + } + gnutellahdr->protoindex = pie_proto_gnutella_fd; + gnutellahdr->header = NULL; + gnutellahdr->hlen = 0; + gnutellahdr->datalen = curhdr->datalen; + gnutellahdr->data = curhdr->data; + gnutellahdr->next_hdr = NULL; + gnutellahdr->proto_info = NULL; + return gnutellahdr; +} + +void pie_gnutella_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_gnutella_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_gnutella_fd = pie_reg_protocol("gnutella",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_gnutella_new_session,&pie_gnutella_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_gnutella_session_cleanup,&pie_gnutella_packet_cleanup); + if (pie_proto_gnutella_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_gnutella_fd,&pie_gnutella_tcpfind); + pie_reg_subprotocol("http",pie_proto_gnutella_fd,&pie_gnutella_httpfind); + //pie_reg_subprotocol("tcp",pie_proto_gnutella_fd,&pie_gnutella_httpfind); + pie_reg_subprotocol("udp",pie_proto_gnutella_fd,&pie_gnutella_udpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load gnutella module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("gnutella",pie_proto_gnutella_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/gre.c linux-2.6.27.8-hippie/net/hippie/proto/gre.c --- linux-2.6.27.8/net/hippie/proto/gre.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/gre.c 2008-01-30 14:41:34.000000000 -0600 @@ -0,0 +1,198 @@ +/* + * Hi-Performance Protocol Identification Engine GRE Protocol Handling Code - pie_proto_gre.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +u_int16_t pie_proto_gre_fd = 0; +u_int16_t pie_proto_ipv4_fd_gre = 0; + +struct pie_protohdr_gre { + u_int16_t callid; +}; + +struct pie_protosess_gre { + u_int16_t callid; +}; + +#define PIE_STATE_TIMEOUT_GRE 300 + +#define PIE_STATE_GRE_UP 4700 + +u_int8_t pie_gre_session_compare(struct pie_protocol_hdr *pkthdr, struct pie_protocol_sess *sess, u_int8_t direction) { + struct pie_protosess_gre *gresess = (struct pie_protosess_gre *) sess->proto_info; + struct pie_protohdr_gre *grehdr = (struct pie_protohdr_gre *) pkthdr->proto_info; + switch (direction) { + case 0: + if (gresess->callid == grehdr->callid) { + return 1; + } + break; + case 1: + if (gresess->callid == grehdr->callid) { + return 1; + } + break; + } + return 0; +} + +struct pie_protocol_sess *pie_gre_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + struct pie_protosess_gre *gresess; + struct pie_protohdr_gre *grehdr = (struct pie_protohdr_gre *) pkthdr->proto_info; + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for GRE session header information.\n"); + return NULL; + } + sess->protoindex = pie_proto_gre_fd; + sess->next_sess = NULL; + gresess = kmalloc(sizeof(struct pie_protosess_gre),GFP_KERNEL); + if (gresess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for GRE session information.\n"); + kfree(sess); + return NULL; + } + gresess->callid = grehdr->callid; + sess->proto_info = (void *) gresess; + return sess; +} + +int pie_gre_proc_packet(struct pie_sess_info *session, struct pie_protocol_hdr *pkthdr) { + struct pie_protohdr_gre *greinfo = (struct pie_protohdr_gre *)pkthdr->proto_info; + read_lock(session->lock); + if (atomic_read(&session->state) == PIE_STATE_NEW) { + atomic_set(&session->state,PIE_STATE_GRE_UP); + } + switch (atomic_read(&session->state)) { + case PIE_STATE_GRE_UP: + pie_session_timeout_reset(session,PIE_STATE_TIMEOUT_GRE); + break; + default: + pie_session_timeout_reset(session,15); + break; + } + read_unlock(session->lock); + return 0; +} + +int pie_gre_ipv4find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr == NULL) { + /* This shouldn't ever happen! */ + printk(KERN_ALERT "HiPPIE: GRE IPv4 Packet detection was passed a NULL header.\n"); + return 0; + } + if (curhdr->protoindex == pie_proto_ipv4_fd_gre) { + struct pie_protohdr_ipv4 *ipv4hdr = (struct pie_protohdr_ipv4 *) curhdr->proto_info; + if (ipv4hdr != NULL && ipv4hdr->proto == 47) { + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_gre_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *gre_hdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + struct pie_protohdr_gre *protoinfo; + if (gre_hdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate GRE Session Header Information.\n"); + return NULL; + } + gre_hdr->protoindex = pie_proto_gre_fd; + + if (curhdr == NULL) { + /* This should NEVER happen */ + printk(KERN_ALERT "HiPPIE: GRE Mockup received a NULL protocol header!\n"); + return NULL; + } + gre_hdr->header = curhdr->data; + gre_hdr->datalen = curhdr->data[4] * 256 + curhdr->data[5]; + gre_hdr->hlen = curhdr->datalen - gre_hdr->datalen; + if (gre_hdr->datalen > 0) { + gre_hdr->data = &curhdr->data[gre_hdr->hlen]; + } else { + gre_hdr->data = NULL; + } + gre_hdr->next_hdr = NULL; + protoinfo = kmalloc(sizeof(struct pie_protohdr_gre),GFP_KERNEL); + if (protoinfo == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate GRE Session Information.\n"); + kfree(gre_hdr); + return NULL; + } + protoinfo->callid = gre_hdr->header[6] * 256 + gre_hdr->header[7]; + gre_hdr->proto_info = protoinfo; + return gre_hdr; +} + +int pie_gre_proc_print(struct pie_sess_info *sess, struct pie_protocol_sess *psess, char *buffer) { + struct pie_protosess_gre *greinfo = (struct pie_protosess_gre *) psess->proto_info; + if (greinfo == NULL) { + printk(KERN_ALERT "HiPPIE: GRE session is missing session information!\n"); + return 0; + } + int len = 0; + len += sprintf(buffer+len,"callid %u",greinfo->callid); + switch(atomic_read(&sess->state)) { + case PIE_STATE_GRE_UP: + len += sprintf(buffer+len," state GRE_UP"); + break; + } + return len; +} + +u_int8_t pie_gre_get_sess_bucket(struct pie_protocol_hdr *pkthdr, u_int8_t direction) { + struct pie_protohdr_gre *grehdr = (struct pie_protohdr_gre *) pkthdr->proto_info; + switch (direction) { + case 0: + return grehdr->callid % 256; + break; + case 1: + return grehdr->callid % 256; + break; + } + return 0; +} + +void pie_gre_session_cleanup(struct pie_protocol_sess *sess) { + struct pie_protosess_gre *gresess = (struct pie_protosess_gre *) sess->proto_info; + kfree(gresess); + kfree(sess); +} + +void pie_gre_packet_cleanup(struct pie_protocol_hdr *hdr) { + struct pie_protohdr_gre *grehdr = (struct pie_protohdr_gre *) hdr->proto_info; + kfree(grehdr); + kfree(hdr); +} + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("Hi-Performance Protocol Identification Engine GRE Protocol Packet Analysis and Sessioning Handler"); +MODULE_LICENSE("GPL"); + +static int __init init(void) { + pie_proto_gre_fd = pie_reg_protocol("gre",PIE_PROTOTYPE_TRANSPORT,PIE_ENCAP_TAGGED,0,&pie_gre_get_sess_bucket,&pie_gre_session_compare,&pie_gre_new_session,&pie_gre_packet_mockup,NULL,NULL,NULL,NULL,&pie_gre_proc_packet,&pie_gre_proc_print,&pie_gre_session_cleanup,&pie_gre_packet_cleanup); + pie_reg_subprotocol("ipv4",pie_proto_gre_fd,&pie_gre_ipv4find); + pie_proto_ipv4_fd_gre = pie_get_protocolid("ipv4"); + return 0; +} + +static void __exit fini(void) { + pie_unreg_protocol("gre",pie_proto_gre_fd); +} + +module_init(init); +module_exit(fini); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/http.c linux-2.6.27.8-hippie/net/hippie/proto/http.c --- linux-2.6.27.8/net/hippie/proto/http.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/http.c 2008-02-06 11:45:18.000000000 -0600 @@ -0,0 +1,166 @@ +/* + * Hi-Performance Protocol Identification Engine HTTP Module - http.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_http_fd = 0; +u_int16_t pie_proto_httptunnel_fd = 0; + +/* This comes after we've received an HTTP command, followed at this point by 0.9, 1.0, or 1.1 */ +u_int8_t httpprotodec[5] = {'H','T','T','P','/'}; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE HTTP Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_http_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for HTTP Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_http_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +struct pie_protocol_sess *pie_httptunnel_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for HTTP Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_httptunnel_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_http_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* HTTP Protocol classifiers */ + u_int8_t get[4] = {'G','E','T',' '}; + u_int8_t post[5] = {'P','O','S','T',' '}; + u_int8_t head[5] = {'H','E','A','D',' '}; + /* Check for commands */ + if (curhdr->datalen >= 5 && pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],httpprotodec,5) != NULL) { + /* Found HTTP header */ + if (curhdr->datalen >= 10 && pie_payload_search(curhdr->data,curhdr->data,get,4) != NULL) { + return 1; + } + if (curhdr->datalen >= 10 && pie_payload_search(curhdr->data,curhdr->data,post,5) != NULL) { + return 1; + } + if (curhdr->datalen >= 10 && pie_payload_search(curhdr->data,curhdr->data,head,5) != NULL) { + return 1; + } + } + return 0; +} + +int pie_httptunnel_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* HTTP Protocol classifiers */ + u_int8_t connect[8] = {'C','O','N','N','E','C','T',' '}; + /* Check for commands */ + u_int8_t *cmdloc = pie_payload_search(curhdr->data,curhdr->data,connect,8);; + if (cmdloc != NULL) { + /* Found a command, verify it's an HTTP command */ + u_int8_t *httploc = pie_payload_search(cmdloc,&curhdr->data[curhdr->datalen - 1],httpprotodec,5); + if (httploc != NULL) { + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_http_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *httphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (httphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate HTTP Session Header.\n"); + return NULL; + } + httphdr->protoindex = pie_proto_http_fd; + httphdr->header = NULL; + httphdr->hlen = 0; + httphdr->datalen = curhdr->datalen; + httphdr->data = curhdr->data; + httphdr->next_hdr = NULL; + httphdr->proto_info = NULL; + return httphdr; +} + +struct pie_protocol_hdr *pie_httptunnel_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *httphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (httphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate HTTP Session Header.\n"); + return NULL; + } + httphdr->protoindex = pie_proto_httptunnel_fd; + httphdr->header = NULL; + httphdr->hlen = 0; + httphdr->datalen = curhdr->datalen; + httphdr->data = curhdr->data; + httphdr->next_hdr = NULL; + httphdr->proto_info = NULL; + return httphdr; +} + +void pie_http_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_httptunnel_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_http_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +void pie_httptunnel_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + + +static int __init init(void) { + pie_proto_http_fd = pie_reg_protocol("http",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_http_new_session,&pie_http_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_http_session_cleanup,&pie_http_packet_cleanup); + if (pie_proto_http_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_http_fd,&pie_http_tcpfind); + //return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load http module.\n"); + return -1; + } + pie_proto_httptunnel_fd = pie_reg_protocol("httptunnel",PIE_PROTOTYPE_APP,PIE_ENCAP_UNTAGGED,10,NULL,NULL,&pie_httptunnel_new_session,&pie_httptunnel_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_httptunnel_session_cleanup,&pie_httptunnel_packet_cleanup); + if (pie_proto_httptunnel_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_httptunnel_fd,&pie_httptunnel_tcpfind); + if (pie_reg_tunnel_type(pie_proto_httptunnel_fd,"tcp") == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register TCP tunneling within HTTP Tunnel.\n"); + } + //return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load httptunnel module.\n"); + return -1; + } + return 0; +} + +static void __exit fini(void) { + pie_unreg_protocol("http",pie_proto_http_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/irc.c linux-2.6.27.8-hippie/net/hippie/proto/irc.c --- linux-2.6.27.8/net/hippie/proto/irc.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/irc.c 2008-02-06 15:36:45.000000000 -0600 @@ -0,0 +1,245 @@ +/* + * Hi-Performance Protocol Identification Engine IRC Module - irc.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include +#ifdef CONFIG_HIPPIE_PREDICTION +#include +#endif +#include + +u_int16_t pie_proto_irc_fd = 0; +u_int16_t pie_proto_ircdcc_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE IRC Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_irc_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for IRC Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_irc_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +struct pie_protocol_sess *pie_ircdcc_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for IRC-DCC Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_ircdcc_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_irc_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* Make sure it's TCP */ + u_int8_t user[5] = {0x55,0x53,0x45,0x52,0x20}; + u_int8_t nick[5] = {0x4E,0x49,0x43,0x4B,0x20}; + if (curhdr->datalen >= 5) { + /* Check for request */ + void *founduser = pie_session_get_value(pktinfo->session,pie_proto_irc_fd,1); + void *foundnick = pie_session_get_value(pktinfo->session,pie_proto_irc_fd,2); + if (founduser == NULL && pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],user,5) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_irc_fd,1,(void *)1); + founduser = (void *)1; + } + if (foundnick == NULL && pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],nick,5) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_irc_fd,2,(void *)1); + foundnick = (void *)1; + } + if (founduser != NULL && foundnick != NULL) { + return 1; + } + } + return 0; +} + +static void persist(struct pie_sess_info *sess, struct pie_protocol_hdr *curhdr) { +#ifdef CONFIG_HIPPIE_PREDICTION + u_int8_t privmsg[9] = {0x20,0x50,0x52,0x49,0x56,0x4D,0x53,0x47,0x20}; + u_int8_t dccsend[9] = {0x44,0x43,0x43,0x20,0x53,0x45,0x4E,0x44,0x20}; + u_int8_t space[1] = {0x20}; + if (curhdr->datalen >= 9) { + u_int8_t *dccloc = pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],dccsend,9); + if (dccloc != NULL) { + /* Found a DCC request, check the location of the PRIVMSG */ + u_int8_t *pmloc = pie_payload_search(curhdr->data,dccloc,privmsg,9); + if (pmloc == curhdr->data) { + /* PRIVMSG was sent by the client. */ + /* Find the address and port number sent by the client to expect the connection on */ + /* For the case of a client sending this to the server, this should be the client's IP address, + * and we should just predict a connection from *anywhere* to this host port */ + char *parse = pie_payload_search(&dccloc[9],&curhdr->data[curhdr->datalen - 1],space,1); + u_int8_t oct[4]; + parse++; + parse = pie_ipv4_addr_read(parse,2,oct); + parse++; + u_int16_t dstport = simple_strtoul(parse,&parse,10); + + struct pie_sess_info *pred = pie_prediction_create(); + if (pred != NULL) { + /* Add an IPv4 header */ + struct pie_protocol_sess *iphdr = pie_prediction_add_header(pred,pie_get_protocolid("ipv4")); + if (iphdr != NULL) { + /* Set the IPv4 Destination Address */ + pie_prediction_parameter(iphdr,"dst",PIE_DTYPE_POINTER,oct); + /* Cannot set the source address, so don't try */ + /* Set the IP protocol # to TCP (6) */ + pie_prediction_parameter(iphdr,"proto",PIE_DTYPE_NUM,(void *) 6); + /* Create the TCP header */ + struct pie_protocol_sess *tcphdr = pie_prediction_add_header(pred,pie_get_protocolid("tcp")); + if (tcphdr != NULL) { + /* Set the destination port */ + pie_prediction_parameter(tcphdr,"dport",PIE_DTYPE_NUM,(void *) dstport); + if (pie_prediction_add_header(pred,pie_proto_ircdcc_fd) == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to add irc-dcc header to IRC DCC prediction.\n"); + } else { + pie_prediction_schedule(pred); + } + } else { + printk(KERN_INFO "HiPPIE: IRC Prediction failed to allocate TCP header to prediction.\n"); + } + } else { + printk(KERN_INFO "HiPPIE: IRC Prediction failed to allocate IPv4 header to prediction.\n"); + } + } + } else if (pmloc != NULL) { + /* PRIVMSG found further in message, sent by another client through the server. */ + char *parse = pie_payload_search(&dccloc[9],&curhdr->data[curhdr->datalen - 1],space,1); + u_int8_t oct[4]; + parse++; + parse = pie_ipv4_addr_read(parse,2,oct); + parse++; + u_int16_t dstport = simple_strtoul(parse,&parse,10); + + struct pie_sess_info *pred = pie_prediction_create(); + if (pred != NULL) { + /* Add an IPv4 header */ + struct pie_protocol_sess *iphdr = pie_prediction_add_header(pred,pie_get_protocolid("ipv4")); + if (iphdr != NULL) { + /* Set the IPv4 Destination Address */ + pie_prediction_parameter(iphdr,"dst",PIE_DTYPE_POINTER,oct); + /* Set the IPv4 Source Address */ + //pie_prediction_parameter(iphdr,"src",PIE_DTYPE_POINTER,sess->srcip); + /* Set the IP protocol # to TCP (6) */ + pie_prediction_parameter(iphdr,"proto",PIE_DTYPE_NUM,(void *) 6); + /* Create the TCP header */ + struct pie_protocol_sess *tcphdr = pie_prediction_add_header(pred,pie_get_protocolid("tcp")); + if (tcphdr != NULL) { + /* Set the destination port */ + pie_prediction_parameter(tcphdr,"dport",PIE_DTYPE_NUM,(void *) dstport); + if (pie_prediction_add_header(pred,pie_proto_ircdcc_fd) == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to add irc-dcc header to IRC DCC prediction.\n"); + } else { + pie_prediction_schedule(pred); + } + } else { + printk(KERN_INFO "HiPPIE: IRC Prediction failed to allocate TCP header to prediction.\n"); + } + } else { + printk(KERN_INFO "HiPPIE: IRC Prediction failed to allocate IPv4 header to prediction.\n"); + } + } + } else { + printk(KERN_DEBUG "HiPPIE: Found DCC SEND without PRIVMSG. Odd, but ignoring.\n"); + } + } + } +#endif +} + +struct pie_protocol_hdr *pie_irc_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *irchdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (irchdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate IRC Session Header.\n"); + return NULL; + } + irchdr->protoindex = pie_proto_irc_fd; + irchdr->header = NULL; + irchdr->hlen = 0; + irchdr->datalen = curhdr->datalen; + irchdr->data = curhdr->data; + irchdr->next_hdr = NULL; + irchdr->proto_info = NULL; + return irchdr; +} + +struct pie_protocol_hdr *pie_ircdcc_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *irchdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (irchdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate IRC-DCC Session Header.\n"); + return NULL; + } + irchdr->protoindex = pie_proto_ircdcc_fd; + irchdr->header = NULL; + irchdr->hlen = 0; + irchdr->datalen = curhdr->datalen; + irchdr->data = curhdr->data; + irchdr->next_hdr = NULL; + irchdr->proto_info = NULL; + return irchdr; +} + +void pie_irc_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_ircdcc_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_irc_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +void pie_ircdcc_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_irc_fd = pie_reg_protocol("irc",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_irc_new_session,&pie_irc_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_irc_session_cleanup,&pie_irc_packet_cleanup); + pie_proto_ircdcc_fd = pie_reg_protocol("irc-dcc",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,1,NULL,NULL,&pie_ircdcc_new_session,&pie_ircdcc_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_ircdcc_session_cleanup,&pie_ircdcc_packet_cleanup); + if (pie_proto_irc_fd > 0 && pie_proto_ircdcc_fd > 0) { + if (pie_reg_subprotocol("tcp",pie_proto_irc_fd,&pie_irc_tcpfind) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register IRC as a subprotocol of TCP.\n"); + } +#ifdef CONFIG_HIPPIE_PERSISTANCE + if (pie_reg_persist(pie_proto_irc_fd,&persist) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register IRC persistant listener.\n"); + } +#endif + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load IRC modules.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("irc",pie_proto_irc_fd); + pie_unreg_protocol("irc-dcc",pie_proto_ircdcc_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/mp2p.c linux-2.6.27.8-hippie/net/hippie/proto/mp2p.c --- linux-2.6.27.8/net/hippie/proto/mp2p.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/mp2p.c 2008-02-07 12:10:48.000000000 -0600 @@ -0,0 +1,142 @@ +/* + * Hi-Performance Protocol Identification Engine MP2P P2P Module - mp2p.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_mp2p_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE MP2P P2P Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_mp2p_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for MP2P P2P Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_mp2p_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_mp2p_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen > 4) { + u_int8_t sizecmd[4] = {'S','I','Z',' '}; + if (pie_payload_search(curhdr->data,curhdr->data,sizecmd,4) != NULL) { + return 1; + } + } + return 0; +} + +int pie_mp2p_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* MP2P Protocol classifiers */ +#define MP2P_CMD_COUNT 9 + u_int16_t cmds[MP2P_CMD_COUNT] = { + 0x5346, /* SF = Number of files shared */ + 0x534b, /* SK = Number of KB shared */ + 0x4e49, /* NI = Nickname */ + 0x4e43, /* NC = Number of connections */ + 0x4e43, /* CN = Client Name */ + 0x4356, /* CV = Client Version */ + 0x564c, /* VL = Connection Speed */ + 0x4944, /* ID = File hash? */ + 0x464e /* FN = File name? Search? */ + }; + u_int8_t opener[3] = { 0x3d, 0x4b, 0xd9 }; + u_int8_t opener2[3] = { 0x3d, 0x4a, 0xd9 }; + u_int8_t opener3[3] = { 0x3e, 0x4b, 0xd9 }; + u_int8_t body16[2] = { 0xed, 0xbb }; + if (curhdr->datalen >= 20) { + /* New "crypto" MP2P */ + if (curhdr->data[2] == 0xd9 && (pie_payload_search(curhdr->data,curhdr->data,opener,3) != NULL || pie_payload_search(curhdr->data,curhdr->data,opener2,3) != NULL || pie_payload_search(curhdr->data,curhdr->data,opener3,3) != NULL)) { + /* Fits the profile... couple more checks */ + if ((int)(curhdr->data[3] / 16) == 2 || curhdr->data[3] == 0x64) { + return 1; + } + } + /* "Old" MP2P */ + } + if (curhdr->datalen >= 24) { + u_int8_t found = 0; + u_int8_t cursor = 20; + while (cursor <= curhdr->datalen) { + int i; + found = 0; + u_int16_t cmdval = make_int16(&curhdr->data[cursor]); + u_int16_t cmdlen = make_int16(&curhdr->data[cursor + 2]); + for (i = 0; i < MP2P_CMD_COUNT; i++) { + if (cmdval == cmds[i]) { + cursor += 4 + cmdlen; + if (cursor == curhdr->datalen) { + return 1; + } + found = 1; + break; + } + } + if (found == 0) { + return 0; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_mp2p_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *mp2phdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (mp2phdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate MP2P P2P protocol header.\n"); + return NULL; + } + mp2phdr->protoindex = pie_proto_mp2p_fd; + mp2phdr->header = NULL; + mp2phdr->hlen = 0; + mp2phdr->datalen = curhdr->datalen; + mp2phdr->data = curhdr->data; + mp2phdr->next_hdr = NULL; + mp2phdr->proto_info = NULL; + return mp2phdr; +} + +void pie_mp2p_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_mp2p_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_mp2p_fd = pie_reg_protocol("mp2p",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_mp2p_new_session,&pie_mp2p_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_mp2p_session_cleanup,&pie_mp2p_packet_cleanup); + if (pie_proto_mp2p_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_mp2p_fd,&pie_mp2p_tcpfind); + pie_reg_subprotocol("udp",pie_proto_mp2p_fd,&pie_mp2p_udpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load mp2p module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("mp2p",pie_proto_mp2p_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/msnim.c linux-2.6.27.8-hippie/net/hippie/proto/msnim.c --- linux-2.6.27.8/net/hippie/proto/msnim.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/msnim.c 2008-02-04 10:07:34.000000000 -0600 @@ -0,0 +1,109 @@ +/* + * Hi-Performance Protocol Identification Engine MSN Messenger Module - msnim.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Instant Messaging Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_msnim_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE MSN Messenger Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_msnim_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for MSN Messenger Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_msnim_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_msnim_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 18) { + /* Check for commands */ + u_int8_t ver[4] = {'V','E','R',' '}; + u_int8_t msnp[5] = {' ','M','S','N','P'}; + u_int8_t cvr0[5] = {' ','C','V','R','0'}; + u_int8_t *verloc = pie_payload_search(curhdr->data,curhdr->data,ver,4); + if (verloc != NULL) { + u_int8_t *msnploc = pie_payload_search(verloc + (4 * sizeof(u_int8_t)),&curhdr->data[curhdr->datalen - 1],msnp,5); + if (msnploc != NULL) { + u_int8_t *cvr0loc = pie_payload_search(msnploc + (5 * sizeof(u_int8_t)),&curhdr->data[curhdr->datalen - 1],cvr0,5); + if (cvr0loc != NULL) { + return 1; + } + } + } + /*if (cmdloc == NULL) { + cmdloc = pie_payload_search(curhdr->data,curhdr->data,post,5); + } + if (cmdloc == NULL) { + cmdloc = pie_payload_search(curhdr->data,curhdr->data,head,5); + } + if (cmdloc != NULL) {*/ + /* Found a command, verify it's an HTTP command */ + /*u_int8_t *httploc = pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],protodec,5); + if (httploc != NULL) { + return 1; + } + }*/ + } + return 0; +} + +struct pie_protocol_hdr *pie_msnim_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *msnimhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (msnimhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate MSN Messenger Session Header.\n"); + return NULL; + } + msnimhdr->protoindex = pie_proto_msnim_fd; + msnimhdr->header = NULL; + msnimhdr->hlen = 0; + msnimhdr->datalen = curhdr->datalen; + msnimhdr->data = curhdr->data; + msnimhdr->next_hdr = NULL; + msnimhdr->proto_info = NULL; + return msnimhdr; +} + +void pie_msnim_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_msnim_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_msnim_fd = pie_reg_protocol("msnim",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_msnim_new_session,&pie_msnim_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_msnim_session_cleanup,&pie_msnim_packet_cleanup); + if (pie_proto_msnim_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_msnim_fd,&pie_msnim_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load msnim module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("msnim",pie_proto_msnim_fd); +} + +module_init(init); +module_exit(fini); diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/netflow.c linux-2.6.27.8-hippie/net/hippie/proto/netflow.c --- linux-2.6.27.8/net/hippie/proto/netflow.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/netflow.c 2008-02-06 15:36:45.000000000 -0600 @@ -0,0 +1,94 @@ +/* + * Hi-Performance Protocol Identification Engine Netflow Module - netflow.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_netflow_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE Netflow Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_netflow_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for Netflow Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_netflow_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_netflow_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 24) { + u_int16_t version = make_int16(curhdr->data); + u_int16_t flowcount = make_int16(&curhdr->data[2]); + u_int32_t resv = make_int32(&curhdr->data[20]); + if (curhdr->datalen == 24 + (52 * flowcount)) { + if (resv == 0) { + /* This passes, check the version number */ + if (version == 7 || version == 9 || version == 5) { + return 1; + } + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_netflow_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *netflowhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (netflowhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate Netflow protocol header.\n"); + return NULL; + } + netflowhdr->protoindex = pie_proto_netflow_fd; + netflowhdr->header = NULL; + netflowhdr->hlen = 0; + netflowhdr->datalen = curhdr->datalen; + netflowhdr->data = curhdr->data; + netflowhdr->next_hdr = NULL; + netflowhdr->proto_info = NULL; + return netflowhdr; +} + +void pie_netflow_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_netflow_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_netflow_fd = pie_reg_protocol("netflow",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_netflow_new_session,&pie_netflow_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_netflow_session_cleanup,&pie_netflow_packet_cleanup); + if (pie_proto_netflow_fd > 0) { + pie_reg_subprotocol("udp",pie_proto_netflow_fd,&pie_netflow_udpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load netflow module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("netflow",pie_proto_netflow_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/nntp.c linux-2.6.27.8-hippie/net/hippie/proto/nntp.c --- linux-2.6.27.8/net/hippie/proto/nntp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/nntp.c 2008-02-06 11:45:18.000000000 -0600 @@ -0,0 +1,99 @@ +/* + * Hi-Performance Protocol Identification Engine NNTP Module - nntp.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +u_int16_t pie_proto_nntp_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE NNTP Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_nntp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for NNTP Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_nntp_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_nntp_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + u_int8_t request[3] = {0x32,0x32,0x30}; /* "220 " */ + u_int8_t response[11] = {'M','O','D','E',' ','R','E','A','D','E','R'}; + /* Check for request */ + if (curhdr->datalen >= 3 && pie_session_get_value(pktinfo->session,pie_proto_nntp_fd,1) == NULL) { + if (pie_payload_search(curhdr->data,curhdr->data,request,3) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_nntp_fd,1,(void *)1); + return 0; + } + } else if (curhdr->datalen >= 11 && (int)pie_session_get_value(pktinfo->session,pie_proto_nntp_fd,1) == 1) { + if (pie_payload_search(curhdr->data,curhdr->data,response,11) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_nntp_fd,1,(void *)2); + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_nntp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *nntphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (nntphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate NNTP Session Header.\n"); + return NULL; + } + nntphdr->protoindex = pie_proto_nntp_fd; + nntphdr->header = NULL; + nntphdr->hlen = 0; + nntphdr->datalen = curhdr->datalen; + nntphdr->data = curhdr->data; + nntphdr->next_hdr = NULL; + nntphdr->proto_info = NULL; + return nntphdr; +} + +void pie_nntp_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_nntp_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_nntp_fd = pie_reg_protocol("nntp",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_nntp_new_session,&pie_nntp_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_nntp_session_cleanup,&pie_nntp_packet_cleanup); + if (pie_proto_nntp_fd > 0) { + if (pie_reg_subprotocol("tcp",pie_proto_nntp_fd,&pie_nntp_tcpfind) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register NNTP as a subprotocol of TCP.\n"); + } + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load nntp modules.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("nntp",pie_proto_nntp_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/novellcp.c linux-2.6.27.8-hippie/net/hippie/proto/novellcp.c --- linux-2.6.27.8/net/hippie/proto/novellcp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/novellcp.c 2008-02-08 10:35:56.000000000 -0600 @@ -0,0 +1,89 @@ +/* + * Hi-Performance Protocol Identification Engine Novell IP Protocol Module - novellcp.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_novellcp_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE Novell IP Protocol Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_novellcp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for Novell IP Protocol Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_novellcp_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_novellcp_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + u_int32_t cptag = 0x446d6454; + if (curhdr->datalen >= 8) { + u_int32_t startbytes = make_int32(curhdr->data);//((curhdr->data[0] * 256 + curhdr->data[1]) * 256 + curhdr->data[2]) * 256 + curhdr->data[3]; + u_int32_t lenbytes = make_int32(&curhdr->data[4]); //((curhdr->data[4] * 256 + curhdr->data[5]) * 256 + curhdr->data[6]) * 256 + curhdr->data[7]; + if (startbytes == cptag && lenbytes == curhdr->datalen) { + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_novellcp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *novellcphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (novellcphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate Novell IP Protocol Session Header.\n"); + return NULL; + } + novellcphdr->protoindex = pie_proto_novellcp_fd; + novellcphdr->header = NULL; + novellcphdr->hlen = 0; + novellcphdr->datalen = curhdr->datalen; + novellcphdr->data = curhdr->data; + novellcphdr->next_hdr = NULL; + novellcphdr->proto_info = NULL; + return novellcphdr; +} + +void pie_novellcp_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_novellcp_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_novellcp_fd = pie_reg_protocol("novellcp",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_novellcp_new_session,&pie_novellcp_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_novellcp_session_cleanup,&pie_novellcp_packet_cleanup); + if (pie_proto_novellcp_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_novellcp_fd,&pie_novellcp_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load novellcp module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("novellcp",pie_proto_novellcp_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/pop3.c linux-2.6.27.8-hippie/net/hippie/proto/pop3.c --- linux-2.6.27.8/net/hippie/proto/pop3.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/pop3.c 2008-02-06 11:45:18.000000000 -0600 @@ -0,0 +1,99 @@ +/* + * Hi-Performance Protocol Identification Engine POP3 Module - pop3.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +u_int16_t pie_proto_pop3_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE POP3 Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_pop3_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for POP3 Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_pop3_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_pop3_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + u_int8_t request[4] = {'+','O','K',' '}; + u_int8_t response[5] = {'U','S','E','R',' '}; + /* Check for request */ + if (curhdr->datalen >= 4 && pie_session_get_value(pktinfo->session,pie_proto_pop3_fd,1) == NULL) { + if (pie_payload_search(curhdr->data,curhdr->data,request,4) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_pop3_fd,1,(void *)1); + return 0; + } + } else if (curhdr->datalen >= 5 && (int)pie_session_get_value(pktinfo->session,pie_proto_pop3_fd,1) == 1) { + if (pie_payload_search(curhdr->data,curhdr->data,response,5) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_pop3_fd,1,(void *)2); + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_pop3_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *pop3hdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (pop3hdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate POP3 Session Header.\n"); + return NULL; + } + pop3hdr->protoindex = pie_proto_pop3_fd; + pop3hdr->header = NULL; + pop3hdr->hlen = 0; + pop3hdr->datalen = curhdr->datalen; + pop3hdr->data = curhdr->data; + pop3hdr->next_hdr = NULL; + pop3hdr->proto_info = NULL; + return pop3hdr; +} + +void pie_pop3_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_pop3_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_pop3_fd = pie_reg_protocol("pop3",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_pop3_new_session,&pie_pop3_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_pop3_session_cleanup,&pie_pop3_packet_cleanup); + if (pie_proto_pop3_fd > 0) { + if (pie_reg_subprotocol("tcp",pie_proto_pop3_fd,&pie_pop3_tcpfind) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register POP3 as a subprotocol of TCP.\n"); + } + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load pop3 modules.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("pop3",pie_proto_pop3_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/ppstream.c linux-2.6.27.8-hippie/net/hippie/proto/ppstream.c --- linux-2.6.27.8/net/hippie/proto/ppstream.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/ppstream.c 2008-02-04 10:07:34.000000000 -0600 @@ -0,0 +1,113 @@ +/* + * Hi-Performance Protocol Identification Engine PPStream P2P Module - ppstream.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_ppstream_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE PPStream P2P Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_ppstream_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for PPStream P2P Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_ppstream_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_ppstream_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen > 4) { + u_int16_t plen = make_int16(curhdr->data); + u_int16_t ops = make_int16(&curhdr->data[2]); + if (plen == curhdr->datalen) { + /* Sizes match, check some contents */ + if (curhdr->data[curhdr->datalen - 1] == 0x00) { + /* Last byte is 00 */ + if (ops == 0) { + /* This is too loose, tighten up soon. */ + return 1; + } else if (ops == 0x43) { + /* This is too loose, tighten up soon. */ + return 1; + } else { + /* Not matching */ + printk(KERN_DEBUG "HiPPIE: Found potential PPStream packet with ops %.2x%.2x.\n",curhdr->data[2],curhdr->data[3]); + } + } + } + } + return 0; +} + +int pie_ppstream_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen > 10) { + u_int8_t header[10] = {'P','S','P','r','o','t','o','c','o','l'}; + if (pie_payload_search(curhdr->data,curhdr->data,header,10) != NULL) { + /* This is too loose */ + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_ppstream_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *ppstreamhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (ppstreamhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate PPStream P2P Session Header.\n"); + return NULL; + } + ppstreamhdr->protoindex = pie_proto_ppstream_fd; + ppstreamhdr->header = NULL; + ppstreamhdr->hlen = 0; + ppstreamhdr->datalen = curhdr->datalen; + ppstreamhdr->data = curhdr->data; + ppstreamhdr->next_hdr = NULL; + ppstreamhdr->proto_info = NULL; + return ppstreamhdr; +} + +void pie_ppstream_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_ppstream_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_ppstream_fd = pie_reg_protocol("ppstream",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_ppstream_new_session,&pie_ppstream_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_ppstream_session_cleanup,&pie_ppstream_packet_cleanup); + if (pie_proto_ppstream_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_ppstream_fd,&pie_ppstream_tcpfind); + pie_reg_subprotocol("udp",pie_proto_ppstream_fd,&pie_ppstream_udpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load ppstream module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("ppstream",pie_proto_ppstream_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/rdp.c linux-2.6.27.8-hippie/net/hippie/proto/rdp.c --- linux-2.6.27.8/net/hippie/proto/rdp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/rdp.c 2008-02-22 15:34:52.000000000 -0600 @@ -0,0 +1,92 @@ +/* + * Hi-Performance Protocol Identification Engine Remote Desktop Protocol Module - rdp.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: rdp://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_rdp_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE RDP Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_rdp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for RDP Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_rdp_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_rdp_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* RDP Protocol classifiers */ + u_int8_t rdpbegin[3] = {0x03,0x00,0x00}; + u_int8_t rdpnext[5] = {0xe0,0x00,0x00,0x00,0x00}; + if (curhdr->datalen >= 10) { + /* Check for commands */ + if (pie_payload_search(curhdr->data,curhdr->data,rdpbegin,3) != NULL) { + if (pie_payload_search(&curhdr->data[5],&curhdr->data[5],rdpnext,5) != NULL) { + return 1; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_rdp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *rdphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (rdphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate RDP Session Header.\n"); + return NULL; + } + rdphdr->protoindex = pie_proto_rdp_fd; + rdphdr->header = NULL; + rdphdr->hlen = 0; + rdphdr->datalen = curhdr->datalen; + rdphdr->data = curhdr->data; + rdphdr->next_hdr = NULL; + rdphdr->proto_info = NULL; + return rdphdr; +} + +void pie_rdp_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_rdp_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_rdp_fd = pie_reg_protocol("rdp",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_rdp_new_session,&pie_rdp_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_rdp_session_cleanup,&pie_rdp_packet_cleanup); + if (pie_proto_rdp_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_rdp_fd,&pie_rdp_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load rdp module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("rdp",pie_proto_rdp_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/rsync.c linux-2.6.27.8-hippie/net/hippie/proto/rsync.c --- linux-2.6.27.8/net/hippie/proto/rsync.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/rsync.c 2008-02-04 10:07:34.000000000 -0600 @@ -0,0 +1,89 @@ +/* + * Hi-Performance Protocol Identification Engine RSync Protocol Module - rsync.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: rsync://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_rsync_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE RSync Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_rsync_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for RSync Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_rsync_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_rsync_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* RSync Protocol classifiers */ + u_int8_t rsyncbegin[8] = {'@','R','S','Y','N','C','D',':'}; + if (curhdr->datalen >= 8) { + /* Check for commands */ + if (pie_payload_search(curhdr->data,curhdr->data,rsyncbegin,8) != NULL) { + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_rsync_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *rsynchdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (rsynchdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate RSync Session Header.\n"); + return NULL; + } + rsynchdr->protoindex = pie_proto_rsync_fd; + rsynchdr->header = NULL; + rsynchdr->hlen = 0; + rsynchdr->datalen = curhdr->datalen; + rsynchdr->data = curhdr->data; + rsynchdr->next_hdr = NULL; + rsynchdr->proto_info = NULL; + return rsynchdr; +} + +void pie_rsync_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_rsync_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_rsync_fd = pie_reg_protocol("rsync",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_rsync_new_session,&pie_rsync_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_rsync_session_cleanup,&pie_rsync_packet_cleanup); + if (pie_proto_rsync_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_rsync_fd,&pie_rsync_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load rsync module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("rsync",pie_proto_rsync_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/rtsp.c linux-2.6.27.8-hippie/net/hippie/proto/rtsp.c --- linux-2.6.27.8/net/hippie/proto/rtsp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/rtsp.c 2008-02-22 15:34:52.000000000 -0600 @@ -0,0 +1,339 @@ +/* + * Hi-Performance Protocol Identification Engine RTSP Module - rtsp.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Multimedia Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include +#ifdef CONFIG_HIPPIE_PREDICTION +#include +#endif + +u_int16_t pie_proto_rtsp_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE RTSP Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_rtsp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_ATOMIC); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for RTSP Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_rtsp_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_rtsp_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* RTSP Protocol classifiers */ + u_int8_t options[8] = {'O','P','T','I','O','N','S',' '}; + u_int8_t describe[9] = {'D','E','S','C','R','I','B','E',' '}; + u_int8_t announce[9] = {'A','N','N','O','U','N','C','E',' '}; + u_int8_t play[5] = {'P','L','A','Y',' '}; + u_int8_t setup[6] = {'S','E','T','U','P',' '}; + u_int8_t getparam[14] = {'G','E','T','_','P','A','R','A','M','E','T','E','R',' '}; + u_int8_t setparam[14] = {'S','E','T','_','P','A','R','A','M','E','T','E','R',' '}; + u_int8_t teardown[9] = {'T','E','A','R','D','O','W','N',' '}; + /* This comes after we've received an RTSP command, followed at this point by 0.9, 1.0, or 1.1 */ + u_int8_t protodec[5] = {'R','T','S','P','/'}; + if (curhdr->datalen > 5) { + if (pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],protodec,5) != NULL) { + /* Check for commands */ + if (curhdr->datalen >= 13 && pie_payload_search(curhdr->data,curhdr->data,options,8) != NULL) { + return 1; + } + if (curhdr->datalen >= 14 && pie_payload_search(curhdr->data,curhdr->data,describe,9) != NULL) { + return 1; + } + if (curhdr->datalen >= 14 && pie_payload_search(curhdr->data,curhdr->data,announce,9) != NULL) { + return 1; + } + if (curhdr->datalen >= 10 && pie_payload_search(curhdr->data,curhdr->data,play,5) != NULL) { + return 1; + } + if (curhdr->datalen >= 11 && pie_payload_search(curhdr->data,curhdr->data,setup,6) != NULL) { + return 1; + } + if (curhdr->datalen >= 19 && pie_payload_search(curhdr->data,curhdr->data,getparam,14) != NULL) { + return 1; + } + if (curhdr->datalen >= 19 && pie_payload_search(curhdr->data,curhdr->data,setparam,14) != NULL) { + return 1; + } + if (curhdr->datalen >= 14 && pie_payload_search(curhdr->data,curhdr->data,teardown,9) != NULL) { + return 1; + } + } + } + return 0; +} + +static void persist(struct pie_sess_info *sess, struct pie_protocol_hdr *curhdr) { +#ifdef CONFIG_HIPPIE_PREDICTION + if (curhdr->datalen > 15) { + u_int8_t rtspok[15] = {'R','T','S','P','/','1','.','0',' ','2','0','0',' ','O','K'}; + u_int8_t transport[11] = {'T','r','a','n','s','p','o','r','t',':',' '}; + u_int8_t clientport[12] = {'c','l','i','e','n','t','_','p','o','r','t','='}; + u_int8_t serverport[12] = {'s','e','r','v','e','r','_','p','o','r','t','='}; + if (pie_payload_search(curhdr->data,curhdr->data,rtspok,15) != NULL) { + u_int8_t *transloc = pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],transport,11); + if (transloc != NULL) { + u_int8_t *sportloc = pie_payload_search(transloc,&curhdr->data[curhdr->datalen - 1],serverport,12); + if (sportloc != NULL) { + u_int8_t *dportloc; + int sport1 = simple_strtoul((char *)&sportloc[12],(char **) &sportloc,10); + int sport2 = 0; + if (*sportloc == '-') { + sport2 = simple_strtoul((char *)&sportloc[1],(char **) &sportloc,10); + } + dportloc = pie_payload_search(sportloc,&curhdr->data[curhdr->datalen - 1],clientport,12); + if (dportloc != NULL) { + /* Server port then client port, typically MS Media */ + /* Predict from source to destination */ + int dport1 = simple_strtoul((char *)&dportloc[12],(char **) &dportloc,10); + int dport2 = 0; + if (*dportloc == '-') { + dport2 = simple_strtoul((char *)&dportloc[1],(char **) &dportloc,10); + } + /* Should have enough to predict the session now */ + if (sport2 == 0 && dport2 == 0) { + struct pie_sess_info *pred = pie_prediction_create(); + if (pred != NULL) { + /* Check to see if we're being transported IPv4 */ + if (sess->network_sess->protoindex == pie_get_protocolid("ipv4")) { + /* Add an IPv4 header */ + struct pie_protocol_sess *iphdr = pie_prediction_add_header(pred,pie_get_protocolid("ipv4")); + if (iphdr != NULL) { + struct pie_protosess_ipv4 *sessiphdr = (struct pie_protosess_ipv4 *) sess->network_sess->proto_info; + /* Set the IPv4 Destination Address */ + pie_prediction_parameter(iphdr,"dst",PIE_DTYPE_POINTER,sessiphdr->srcip); + /* Set the IPv4 Source Address */ + pie_prediction_parameter(iphdr,"src",PIE_DTYPE_POINTER,sessiphdr->dstip); + /* Set the IP protocol # to UDP (17) */ + pie_prediction_parameter(iphdr,"proto",PIE_DTYPE_NUM,(void *) 17); + /* Create the UDP header */ + struct pie_protocol_sess *udphdr = pie_prediction_add_header(pred,pie_get_protocolid("udp")); + if (udphdr != NULL) { + /* Set the destination port */ + pie_prediction_parameter(udphdr,"dport",PIE_DTYPE_NUM,(void *) dport1); + /* Set the source port */ + pie_prediction_parameter(udphdr,"sport",PIE_DTYPE_NUM,(void *) sport1); + if (pie_prediction_add_header(pred,pie_proto_rtsp_fd) == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to add RTSP header to RTSP prediction.\n"); + } else { + pie_prediction_schedule(pred); + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Prediction failed to allocate UDP header to prediction.\n"); + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Prediction failed to allocate IPv4 header to prediction.\n"); + } + } else { + /* For some reason, we've recognized non IPv4 RTSP traffic */ + printk(KERN_DEBUG "HiPPIE: Persisting and should be predicting on RTSP session, but not IPv4 transported.\n"); + } + } + } else if ((sport2 - sport1) == (dport2 - dport1)) { + int i; + for (i = 0; i < sport2 - sport1; i++) { + struct pie_sess_info *pred = pie_prediction_create(); + if (pred != NULL) { + if (sess->network_sess->protoindex == pie_get_protocolid("ipv4")) { + /* Add an IPv4 header */ + struct pie_protocol_sess *iphdr = pie_prediction_add_header(pred,pie_get_protocolid("ipv4")); + if (iphdr != NULL) { + struct pie_protosess_ipv4 *sessiphdr = (struct pie_protosess_ipv4 *) sess->network_sess->proto_info; + /* Set the IPv4 Destination Address */ + pie_prediction_parameter(iphdr,"dst",PIE_DTYPE_POINTER,sessiphdr->srcip); + /* Set the IPv4 Source Address */ + pie_prediction_parameter(iphdr,"src",PIE_DTYPE_POINTER,sessiphdr->dstip); + /* Set the IP protocol # to UDP (17) */ + pie_prediction_parameter(iphdr,"proto",PIE_DTYPE_NUM,(void *) 17); + /* Create the UDP header */ + struct pie_protocol_sess *udphdr = pie_prediction_add_header(pred,pie_get_protocolid("udp")); + if (udphdr != NULL) { + /* Set the destination port */ + pie_prediction_parameter(udphdr,"dport",PIE_DTYPE_NUM,(void *) (dport1 + i)); + /* Set the source port */ + pie_prediction_parameter(udphdr,"sport",PIE_DTYPE_NUM,(void *) (sport1 + i)); + if (pie_prediction_add_header(pred,pie_proto_rtsp_fd) == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to add RTSP header to RTSP prediction.\n"); + } else { + pie_prediction_schedule(pred); + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Prediction failed to allocate UDP header to prediction.\n"); + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Prediction failed to allocate IPv4 header to prediction.\n"); + } + } else { + /* For some reason, we've recognized non IPv4 RTSP traffic */ + printk(KERN_DEBUG "HiPPIE: Persisting and should be predicting on RTSP session, but not IPv4 transported.\n"); + } + } + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Transport mismatching ports arguments.\n"); + } + } else { + dportloc = pie_payload_search(transloc,&curhdr->data[curhdr->datalen - 1],clientport,12); + if (dportloc != NULL) { + /* Client port and then server port, typically Real */ + /* Predict from destination to source */ + int dport1 = simple_strtoul((char *)&dportloc[12],(char **) &dportloc,10); + int dport2 = 0; + if (*dportloc == '-') { + dport2 = simple_strtoul((char *)&dportloc[1],(char **) &dportloc,10); + } + /* Should have enough to predict the session now */ + if (sport2 == 0 && dport2 == 0) { + struct pie_sess_info *pred = pie_prediction_create(); + if (pred != NULL) { + if (sess->network_sess->protoindex == pie_get_protocolid("ipv4")) { + /* Add an IPv4 header */ + struct pie_protocol_sess *iphdr = pie_prediction_add_header(pred,pie_get_protocolid("ipv4")); + if (iphdr != NULL) { + struct pie_protosess_ipv4 *sessiphdr = (struct pie_protosess_ipv4 *) sess->network_sess->proto_info; + /* Set the IPv4 Destination Address */ + pie_prediction_parameter(iphdr,"dst",PIE_DTYPE_POINTER,sessiphdr->srcip); + /* Set the IPv4 Source Address */ + pie_prediction_parameter(iphdr,"src",PIE_DTYPE_POINTER,sessiphdr->dstip); + /* Set the IP protocol # to UDP (17) */ + pie_prediction_parameter(iphdr,"proto",PIE_DTYPE_NUM,(void *) 17); + /* Create the UDP header */ + struct pie_protocol_sess *udphdr = pie_prediction_add_header(pred,pie_get_protocolid("udp")); + if (udphdr != NULL) { + /* Set the destination port */ + pie_prediction_parameter(udphdr,"dport",PIE_DTYPE_NUM,(void *) sport1); + /* Set the source port */ + pie_prediction_parameter(udphdr,"sport",PIE_DTYPE_NUM,(void *) dport1); + if (pie_prediction_add_header(pred,pie_proto_rtsp_fd) == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to add RTSP header to RTSP prediction.\n"); + } else { + pie_prediction_schedule(pred); + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Prediction failed to allocate UDP header to prediction.\n"); + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Prediction failed to allocate IPv4 header to prediction.\n"); + } + } else { + printk(KERN_DEBUG "HiPPIE: Persisting and should be predicting on RTSP session, but not IPv4 transported.\n"); + } + } + } else if ((sport2 - sport1) == (dport2 - dport1)) { + int i; + for (i = 0; i < sport2 - sport1; i++) { + struct pie_sess_info *pred = pie_prediction_create(); + if (pred != NULL) { + if (sess->network_sess->protoindex == pie_get_protocolid("ipv4")) { + /* Add an IPv4 header */ + struct pie_protocol_sess *iphdr = pie_prediction_add_header(pred,pie_get_protocolid("ipv4")); + if (iphdr != NULL) { + struct pie_protosess_ipv4 *sessiphdr = (struct pie_protsess_ipv4 *) sess->network_sess->proto_info; + /* Set the IPv4 Destination Address */ + pie_prediction_parameter(iphdr,"dst",PIE_DTYPE_POINTER,sessiphdr->srcip); + /* Set the IPv4 Source Address */ + pie_prediction_parameter(iphdr,"src",PIE_DTYPE_POINTER,sessiphdr->dstip); + /* Set the IP protocol # to UDP (17) */ + pie_prediction_parameter(iphdr,"proto",PIE_DTYPE_NUM,(void *) 17); + /* Create the UDP header */ + struct pie_protocol_sess *udphdr = pie_prediction_add_header(pred,pie_get_protocolid("udp")); + if (udphdr != NULL) { + /* Set the destination port */ + pie_prediction_parameter(udphdr,"dport",PIE_DTYPE_NUM,(void *) (sport1 + i)); + /* Set the source port */ + pie_prediction_parameter(udphdr,"sport",PIE_DTYPE_NUM,(void *) (dport1 + i)); + if (pie_prediction_add_header(pred,pie_proto_rtsp_fd) == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to add RTSP header to RTSP prediction.\n"); + } else { + pie_prediction_schedule(pred); + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Prediction failed to allocate UDP header to prediction.\n"); + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Prediction failed to allocate IPv4 header to prediction.\n"); + } + } else { + printk(KERN_DEBUG "HiPPIE: Persisting and should be predicting on RTSP session, but not IPv4 transported.\n"); + } + } + } + } else { + printk(KERN_ALERT "HiPPIE: RTSP Transport mismatching ports arguments.\n"); + } + } + } + } + } + } + } +#endif +} + +struct pie_protocol_hdr *pie_rtsp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *rtsphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (rtsphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate RTSP Session Header.\n"); + return NULL; + } + rtsphdr->protoindex = pie_proto_rtsp_fd; + rtsphdr->header = NULL; + rtsphdr->hlen = 0; + rtsphdr->datalen = curhdr->datalen; + rtsphdr->data = curhdr->data; + rtsphdr->next_hdr = NULL; + rtsphdr->proto_info = NULL; + return rtsphdr; +} + +void pie_rtsp_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_rtsp_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_rtsp_fd = pie_reg_protocol("rtsp",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_rtsp_new_session,&pie_rtsp_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_rtsp_session_cleanup,&pie_rtsp_packet_cleanup); + if (pie_proto_rtsp_fd > 0) { + if (pie_reg_subprotocol("tcp",pie_proto_rtsp_fd,&pie_rtsp_tcpfind) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register RTSP as a subprotocol of TCP.\n"); + } +#ifdef CONFIG_HIPPIE_PERSISTANCE + if (pie_reg_persist(pie_proto_rtsp_fd,&persist) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register RTSP persistant listener.\n"); + } +#endif + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load rtsp modules.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("rtsp",pie_proto_rtsp_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/sip.c linux-2.6.27.8-hippie/net/hippie/proto/sip.c --- linux-2.6.27.8/net/hippie/proto/sip.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/sip.c 2008-02-22 15:34:52.000000000 -0600 @@ -0,0 +1,201 @@ +/* + * Hi-Performance Protocol Identification Engine SIP Module - sip.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Multimedia Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +u_int16_t pie_proto_sip_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE SIP Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +/* SIP Protocol classifiers */ +u_int8_t options[8] = {'O','P','T','I','O','N','S',' '}; +u_int8_t reg[9] = {'R','E','G','I','S','T','E','R',' '}; +u_int8_t invite[7] = {'I','N','V','I','T','E',' '}; +u_int8_t ack[4] = {'A','C','K',' '}; +u_int8_t cancel[7] = {'C','A','N','C','E','L',' '}; +u_int8_t bye[4] = {'B','Y','E',' '}; +u_int8_t refer[6] = {'R','E','F','E','R',' '}; +u_int8_t subscribe[10] = {'S','U','B','S','C','R','I','B','E',' '}; +u_int8_t notify[7] = {'N','O','T','I','F','Y',' '}; +/* This comes after we've received an SIP command, followed at this point by 2.0 only? */ +u_int8_t protodec[4] = {'S','I','P','/'}; + +struct pie_protocol_sess *pie_sip_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for SIP Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_sip_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_sip_find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* Check for commands */ + if (curhdr->datalen >= 4 && pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],protodec,4) != NULL) { + if (curhdr->datalen >= 13 && pie_payload_search(curhdr->data,curhdr->data,options,8) != NULL) { + return 1; + } + if (curhdr->datalen >= 14 && pie_payload_search(curhdr->data,curhdr->data,reg,9) != NULL) { + return 1; + } + if (curhdr->datalen >= 12 && pie_payload_search(curhdr->data,curhdr->data,invite,7) != NULL) { + return 1; + } + if (curhdr->datalen >= 9 && pie_payload_search(curhdr->data,curhdr->data,ack,4) != NULL) { + return 1; + } + if (curhdr->datalen >= 12 && pie_payload_search(curhdr->data,curhdr->data,cancel,7) != NULL) { + return 1; + } + if (curhdr->datalen >= 9 && pie_payload_search(curhdr->data,curhdr->data,bye,4) != NULL) { + return 1; + } + if (curhdr->datalen >= 11 && pie_payload_search(curhdr->data,curhdr->data,refer,6) != NULL) { + return 1; + } + if (curhdr->datalen >= 15 && pie_payload_search(curhdr->data,curhdr->data,subscribe,10) != NULL) { + return 1; + } + if (curhdr->datalen >= 12 && pie_payload_search(curhdr->data,curhdr->data,notify,7) != NULL) { + return 1; + } + } + return 0; +} + +static void persist(struct pie_sess_info *sess, struct pie_protocol_hdr *curhdr) { + u_int8_t sipok[15] = {'R','T','S','P','/','1','.','0',' ','2','0','0',' ','O','K'}; + u_int8_t transport[11] = {'T','r','a','n','s','p','o','r','t',':',' '}; + u_int8_t clientport[12] = {'c','l','i','e','n','t','_','p','o','r','t','='}; + u_int8_t serverport[12] = {'s','e','r','v','e','r','_','p','o','r','t','='}; + if (curhdr->datalen >= 50 && pie_payload_search(curhdr->data,curhdr->data,sipok,15) != NULL) { + u_int8_t *transloc = pie_payload_search(curhdr->data,&curhdr->data[curhdr->datalen - 1],transport,11); + if (transloc != NULL) { + u_int8_t *sportloc = pie_payload_search(transloc,&curhdr->data[curhdr->datalen - 1],serverport,12); + if (sportloc != NULL) { + u_int8_t *dportloc; + int sport1 = simple_strtoul((char *)&sportloc[12],(char **) &sportloc,10); + int sport2 = 0; + if (*sportloc == '-') { + sport2 = simple_strtoul((char *)&sportloc[1],(char **) &sportloc,10); + } + dportloc = pie_payload_search(sportloc,&curhdr->data[curhdr->datalen - 1],clientport,12); + if (dportloc != NULL) { + /* Server port then client port, typically MS Media */ + /* Predict from source to destination */ + int dport1 = simple_strtoul((char *)&dportloc[12],(char **) &dportloc,10); + int dport2 = 0; + if (*dportloc == '-') { + dport2 = simple_strtoul((char *)&dportloc[1],(char **) &dportloc,10); + } + /* Should have enough to predict the session now */ + if (sport2 == 0 && dport2 == 0) { + //pie_udp_predict(sess->sigcode,packet->dstip,dport1,packet->srcip,sport1); + } else if ((sport2 - sport1) == (dport2 - dport1)) { + int i; + for (i = 0; i < sport2 - sport1; i++) { + //pie_udp_predict(sess->sigcode,packet->dstip,dport1 + i,packet->srcip,sport1 + i); + } + } else { + printk(KERN_INFO "HiPPIE: SIP Transport mismatching ports arguments.\n"); + } + } else { + dportloc = pie_payload_search(transloc,&curhdr->data[curhdr->datalen - 1],clientport,12); + if (dportloc != NULL) { + /* Client port and then server port, typically Real */ + /* Predict from destination to source */ + int dport1 = simple_strtoul((char *)&dportloc[12],(char **) &dportloc,10); + int dport2 = 0; + if (*dportloc == '-') { + dport2 = simple_strtoul((char *)&dportloc[1],(char **) &dportloc,10); + } + /* Should have enough to predict the session now */ + if (sport2 == 0 && dport2 == 0) { + //pie_udp_predict(sess->sigcode,packet->srcip,sport1,packet->dstip,dport1); + } else if ((sport2 - sport1) == (dport2 - dport1)) { + int i; + for (i = 0; i < sport2 - sport1; i++) { + //pie_udp_predict(sess->sigcode,packet->srcip,sport1 + i,packet->dstip,dport1 + i); + } + } else { + printk(KERN_INFO "HiPPIE: SIP Transport mismatching ports arguments.\n"); + } + } + } + } + } + } +} + +struct pie_protocol_hdr *pie_sip_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *siphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (siphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate SIP Session Header.\n"); + return NULL; + } + siphdr->protoindex = pie_proto_sip_fd; + siphdr->header = NULL; + siphdr->hlen = 0; + siphdr->datalen = curhdr->datalen; + siphdr->data = curhdr->data; + siphdr->next_hdr = NULL; + siphdr->proto_info = NULL; + return siphdr; +} + +void pie_sip_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_sip_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_sip_fd = pie_reg_protocol("sip",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_sip_new_session,&pie_sip_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_sip_session_cleanup,&pie_sip_packet_cleanup); + if (pie_proto_sip_fd > 0) { + if (pie_reg_subprotocol("tcp",pie_proto_sip_fd,&pie_sip_find) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register SIP as a subprotocol of TCP.\n"); + } + if (pie_reg_subprotocol("udp",pie_proto_sip_fd,&pie_sip_find) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register SIP as a subprotocol of UDP.\n"); + } +#ifdef CONFIG_HIPPIE_PERSISTANCE + // No need to turn on persistance, because the prediction code isn't right currently. + /*if (pie_reg_persist(pie_proto_sip_fd,&persist) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register SIP persistant listener.\n"); + }*/ +#endif + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load sip modules.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("sip",pie_proto_sip_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/smtp.c linux-2.6.27.8-hippie/net/hippie/proto/smtp.c --- linux-2.6.27.8/net/hippie/proto/smtp.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/smtp.c 2008-02-08 10:35:57.000000000 -0600 @@ -0,0 +1,101 @@ +/* + * Hi-Performance Protocol Identification Engine SMTP Module - smtp.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include + +u_int16_t pie_proto_smtp_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE SMTP Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_smtp_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for SMTP Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_smtp_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_smtp_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + u_int8_t req220[4] = {0x32,0x32,0x30,0x20}; + u_int8_t helo[5] = {0x48,0x45,0x4C,0x4F,0x20}; + u_int8_t lhelo[5] = {0x68,0x65,0x6C,0x6F,0x20}; + u_int8_t ehlo[5] = {0x45,0x48,0x4C,0x4F,0x20}; + /* Check for request */ + if (curhdr->datalen >= 4 && pie_session_get_value(pktinfo->session,pie_proto_smtp_fd,1) == NULL) { + if (pie_payload_search(curhdr->data,curhdr->data,req220,4) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_smtp_fd,1,(void *)1); + return 0; + } + } else if (curhdr->datalen >= 5 && (int)pie_session_get_value(pktinfo->session,pie_proto_smtp_fd,1) == 1) { + if (pie_payload_search(curhdr->data,curhdr->data,helo,5) != NULL || pie_payload_search(curhdr->data,curhdr->data,lhelo,5) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_smtp_fd,1,(void *)2); + return 1; + } else if (pie_payload_search(curhdr->data,curhdr->data,ehlo,5) != NULL) { + pie_session_set_value(pktinfo->session,pie_proto_smtp_fd,1,(void *)3); + return 1; + } + } + return 0; +} + +struct pie_protocol_hdr *pie_smtp_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *smtphdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (smtphdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate SMTP Session Header.\n"); + return NULL; + } + smtphdr->protoindex = pie_proto_smtp_fd; + smtphdr->header = NULL; + smtphdr->hlen = 0; + smtphdr->datalen = curhdr->datalen; + smtphdr->data = curhdr->data; + smtphdr->next_hdr = NULL; + smtphdr->proto_info = NULL; + return smtphdr; +} + +void pie_smtp_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_smtp_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_smtp_fd = pie_reg_protocol("smtp",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_smtp_new_session,&pie_smtp_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_smtp_session_cleanup,&pie_smtp_packet_cleanup); + if (pie_proto_smtp_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_smtp_fd,&pie_smtp_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load smtp module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("smtp",pie_proto_smtp_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/socks.c linux-2.6.27.8-hippie/net/hippie/proto/socks.c --- linux-2.6.27.8/net/hippie/proto/socks.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/socks.c 2008-02-22 15:34:52.000000000 -0600 @@ -0,0 +1,147 @@ +/* + * Hi-Performance Protocol Identification Engine SOCKS Module - socks.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include + +u_int16_t pie_proto_socks_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE SOCKS Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_socks_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for SOCKS Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_socks_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_socks_find(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { +#define SOCKS_CMDS 3 + u_int8_t commands[SOCKS_CMDS] = { + 0x01, /* Connect */ + 0x02, /* Bind Port */ + 0x03 /* UDP Assoc */ + }; +#define SOCKS_ADDRTYPE 3 + u_int8_t addrtypes[SOCKS_ADDRTYPE] = { + 0x01, /* IPv4 Addr */ + 0x02, /* DNS Name */ + 0x03 /* IPv6 Addr */ + }; + u_int8_t j, k; + if (curhdr->datalen >= 4) { + u_int8_t j, k; + if (curhdr->data[0] == 0x05 /* SOCKSv5 */) { + /* Packet starts with a SOCKS version number, check the commands field */ + for (j = 0; j < SOCKS_CMDS; j++) { + if (curhdr->data[1] == commands[j]) { + /* Packet has a valid SOCKS command, check the static byte */ + if (curhdr->data[2] == 0x00) { + /* Has a valid null byte, but if it's just this long, it's likely SOCKS, but we'll match even more */ + for (k = 0; k < SOCKS_ADDRTYPE; k++) { + if (curhdr->data[3] == addrtypes[k]) { + /* See which type it is to determine what the packet is supposed to look like. */ + switch (curhdr->data[3]) { + case 0x01: + /* IPv4 */ + if (curhdr->datalen == 10) { + //printk(KERN_ALERT "HiPPIE: SOCKS5 connection tunnel found to %u.%u.%u.%u:%u.\n",curhdr->data[4],curhdr->data[5],curhdr->data[6],curhdr->data[7],curhdr->data[8] * 256 + curhdr->data[9]); + return 1; + } else { + return 0; + } + break; + default: + /* Only IPv4 supported so far */ + printk(KERN_ALERT "HiPPIE: Seemingly valid SOCKS5 connection initiated, but not on a supported address type (%02x).\n",curhdr->data[3]); + return 0; + break; + } + } + } + } else { + return 0; + } + } + } + } else if (curhdr->data[0] == 0x04 /* SOCKSv4 */) { + for (j = 0; j < SOCKS_CMDS; j++) { + if (curhdr->data[1] == commands[j]) { + if (curhdr->datalen == 9 && curhdr->data[8] == 0x00) { + /* This check only works for NULL usernames, but I don't have packets for others right now... */ + //printk(KERN_ALERT "HiPPIE: SOCKS4 connection tunnel to %u.%u.%u.%u:%u.\n",curhdr->data[4],curhdr->data[5],curhdr->data[6],curhdr->data[7],curhdr->data[2] * 256 + curhdr->data[3]); + return 1; + } + } + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_socks_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *sockshdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (sockshdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate SOCKS Session Header.\n"); + return NULL; + } + sockshdr->protoindex = pie_proto_socks_fd; + sockshdr->header = NULL; + sockshdr->hlen = 0; + sockshdr->datalen = curhdr->datalen; + sockshdr->data = curhdr->data; + sockshdr->next_hdr = NULL; + sockshdr->proto_info = NULL; + return sockshdr; +} + +void pie_socks_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_socks_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_socks_fd = pie_reg_protocol("socks",PIE_PROTOTYPE_APP,PIE_ENCAP_UNTAGGED,10,NULL,NULL,&pie_socks_new_session,&pie_socks_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_socks_session_cleanup,&pie_socks_packet_cleanup); + if (pie_proto_socks_fd > 0) { + if (pie_reg_subprotocol("tcp",pie_proto_socks_fd,&pie_socks_find) == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register SOCKS as a subprotocol of TCP.\n"); + } + if (pie_reg_tunnel_type(pie_proto_socks_fd,"tcp") == 0) { + printk(KERN_ALERT "HiPPIE: Failed to register TCP tunneling within SOCKS.\n"); + } + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load socks modules.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("socks",pie_proto_socks_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/ssh.c linux-2.6.27.8-hippie/net/hippie/proto/ssh.c --- linux-2.6.27.8/net/hippie/proto/ssh.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/ssh.c 2008-02-22 15:34:53.000000000 -0600 @@ -0,0 +1,100 @@ +/* + * Hi-Performance Protocol Identification Engine Remote Desktop Protocol Module - ssh.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: ssh://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Standard Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_ssh_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE SSH Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_ssh_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for SSH Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_ssh_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +#define NUM_SSHCODES 1 +u_int8_t sshcodes[NUM_SSHCODES] = { + 0x14 /* Key Exchange */ +}; + +int pie_ssh_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + /* SSH Protocol classifiers */ + if (curhdr->datalen >= 6) { + u_int32_t sshplen = make_int32(curhdr->data); //(((curhdr->data[0] * 256 + curhdr->data[1]) * 256 + curhdr->data[2]) * 256 + curhdr->data[3]); + int i; + if (curhdr->datalen == sshplen + 4) { + /* SSH Packet length is valid, check operation code */ + for (i = 0; i < NUM_SSHCODES; i++) { + if (curhdr->data[5] == sshcodes[i]) { + /* Found a valid SSH session */ + return 1; + } + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_ssh_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *sshhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (sshhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate SSH Session Header.\n"); + return NULL; + } + sshhdr->protoindex = pie_proto_ssh_fd; + sshhdr->header = NULL; + sshhdr->hlen = 0; + sshhdr->datalen = curhdr->datalen; + sshhdr->data = curhdr->data; + sshhdr->next_hdr = NULL; + sshhdr->proto_info = NULL; + return sshhdr; +} + +void pie_ssh_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_ssh_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_ssh_fd = pie_reg_protocol("ssh",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_ssh_new_session,&pie_ssh_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_ssh_session_cleanup,&pie_ssh_packet_cleanup); + if (pie_proto_ssh_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_ssh_fd,&pie_ssh_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load ssh module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("ssh",pie_proto_ssh_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/ssl.c linux-2.6.27.8-hippie/net/hippie/proto/ssl.c --- linux-2.6.27.8/net/hippie/proto/ssl.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/ssl.c 2008-02-06 15:39:47.000000000 -0600 @@ -0,0 +1,111 @@ +/* + * Hi-Performance Protocol Identification Engine SSL Module - ssl.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Encrypted Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_ssl_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE SSL Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_ssl_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for SSL Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_ssl_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +/* SSLv3/TLS1.0 Handshake Check + * Structure: [ Content Type (1) ][ SSL Version (2) ][ Length (2) ][ Handshake Type (1) ][ Unknown (1) ][ Length (2) ][ SSL Version (2) ] + * A Context type of 0x16 is a Handshake. SSL Version of 0x0300 is SSLv3 while 0x0301 is TLS 1.0. The first length value is the length + * of the data section of the packet minus 5 (the 3 header bits). A handshake type of 0x01 is a "Client Hello". The second length is the + * length of the remaining data section of the packet (original length - 9 or First length - 4). The final SSL version follows the same + * standard as the first and will match the first. + */ +int pie_ssl_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 11) { + if (curhdr->data[0] == 0x16) { /* SSL Handshake */ +#define SSL_VERSIONS 3 + u_int16_t versions[SSL_VERSIONS] = { + 0x0300, /* SSLv3 */ + 0x0301, /* TLS 1.0 */ + 0x0302 /* TLS 1.1 */ + }; + u_int16_t version1 = 256 * curhdr->data[1] + curhdr->data[2]; + u_int16_t headerlen = 256 * curhdr->data[3] + curhdr->data[4]; + u_int16_t shakelen = 256 * curhdr->data[7] + curhdr->data[8]; + u_int16_t version2 = 256 * curhdr->data[9] + curhdr->data[10]; + if (curhdr->data[5] == 0x01 && (headerlen == curhdr->datalen - 5) && (shakelen == headerlen - 4) && version1 == version2) { + int i; + for (i = 0; i < SSL_VERSIONS;i++) { + if (version1 == versions[i]) { + return 1; + } + } + printk(KERN_INFO "HiPPIE: Found likely SSL Connection with SSL Version%04x.\n",version1); + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_ssl_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *sslhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (sslhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate SSL Session Header.\n"); + return NULL; + } + sslhdr->protoindex = pie_proto_ssl_fd; + sslhdr->header = NULL; + sslhdr->hlen = 0; + sslhdr->datalen = curhdr->datalen; + sslhdr->data = curhdr->data; + sslhdr->next_hdr = NULL; + sslhdr->proto_info = NULL; + return sslhdr; +} + +void pie_ssl_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_ssl_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_ssl_fd = pie_reg_protocol("ssl",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_ssl_new_session,&pie_ssl_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_ssl_session_cleanup,&pie_ssl_packet_cleanup); + if (pie_proto_ssl_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_ssl_fd,&pie_ssl_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load ssl module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("ssl",pie_proto_ssl_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/storm.c linux-2.6.27.8-hippie/net/hippie/proto/storm.c --- linux-2.6.27.8/net/hippie/proto/storm.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/storm.c 2008-02-08 10:35:58.000000000 -0600 @@ -0,0 +1,168 @@ +/* + * Hi-Performance Protocol Identification Engine Storm worm Module - storm.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_storm_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE Storm worm Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_storm_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for Storm worm Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_storm_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_storm_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 2) { + /* Check for commands */ + if (curhdr->data[0] == 0x10) { + switch (curhdr->data[1]) { + case 0xA0: + /* Connect */ + if (curhdr->datalen == 25) { + return 1; + } + break; + case 0xA1: + /* Connect Reply */\ + if (curhdr->datalen >= 3 && curhdr->datalen == 3 + (23 * curhdr->data[2])) { + return 1; + } + break; + case 0xA6: + /* Publicize */ + if (curhdr->datalen == 25) { + return 1; + } + break; + case 0xA7: + /* Publicize reply */ + if (curhdr->datalen == 2) { + return 1; + } + break; + case 0xA4: + /* Search */ + if (curhdr->datalen == 19) { + return 1; + } + break; + case 0xA5: + /* Search Reply */ + if (curhdr->datalen >= 19 && curhdr->datalen == 19 + (23 * curhdr->data[18])) { + return 1; + } + break; + case 0xBA: + /* Get Search Results */ + if (curhdr->datalen == 23) { + return 1; + } + break; + case 0xBB: + /* Search Result */ + /* Longer process, I'll wait */ + break; + case 0xB8: + /* No Search Result */ + if (curhdr->datalen == 18) { + return 1; + } + break; + case 0xB9: + /* Publish */ + /* Wait and see */ + break; + case 0xBE: + /* Publish Reply */ + if (curhdr->datalen == 18) { + return 1; + } + break; + case 0xB1: + /* Get My IP */ + if (curhdr->datalen == 4) { + return 1; + } + break; + case 0xB6: + /* Get My IP Reply */ + if (curhdr->datalen == 6) { + return 1; + } + break; + case 0xB7: + /* Get My IP Done */ + if (curhdr->datalen == 2) { + return 1; + } + break; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_storm_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *stormhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (stormhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate Storm worm Session Header.\n"); + return NULL; + } + stormhdr->protoindex = pie_proto_storm_fd; + stormhdr->header = NULL; + stormhdr->hlen = 0; + stormhdr->datalen = curhdr->datalen; + stormhdr->data = curhdr->data; + stormhdr->next_hdr = NULL; + stormhdr->proto_info = NULL; + return stormhdr; +} + +void pie_storm_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_storm_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_storm_fd = pie_reg_protocol("storm",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_storm_new_session,&pie_storm_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_storm_session_cleanup,&pie_storm_packet_cleanup); + if (pie_proto_storm_fd > 0) { + pie_reg_subprotocol("udp",pie_proto_storm_fd,&pie_storm_udpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load storm module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("storm",pie_proto_storm_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/winmx.c linux-2.6.27.8-hippie/net/hippie/proto/winmx.c --- linux-2.6.27.8/net/hippie/proto/winmx.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/winmx.c 2008-02-06 11:45:19.000000000 -0600 @@ -0,0 +1,100 @@ +/* + * Hi-Performance Protocol Identification Engine WinMX Module - winmx.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include +#include + +u_int16_t pie_proto_winmx_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE WinMX Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_winmx_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for WinMX Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_winmx_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_winmx_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + u_int8_t sendcmd[4] = {'S','E','N','D'}; + u_int8_t getcmd[3] = {'G','E','T'}; + if (curhdr->datalen == 1 && curhdr->data[0] == 0x31) { + /* Data is simply a 1 */ + pie_session_set_value(pktinfo->session,pie_proto_winmx_fd,1,(void *)1); + } else { + if ((int)pie_session_get_value(pktinfo->session,pie_proto_winmx_fd,1) == 1) { + /* First packet in the session was simply a 1, check for some later commands */ + if (curhdr->datalen >= 4 && pie_payload_search(curhdr->data,curhdr->data,sendcmd,4) != NULL) { + /* Found a SEND command after the 1, it's a WinMX download connection */ + return 1; + } + if (curhdr->datalen >= 3 && pie_payload_search(curhdr->data,curhdr->data,getcmd,3) != NULL) { + /* Found a GET command after the 1, it's a WinMX download connection */ + return 1; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_winmx_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *winmxhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (winmxhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate WinMX Session Header.\n"); + return NULL; + } + winmxhdr->protoindex = pie_proto_winmx_fd; + winmxhdr->header = NULL; + winmxhdr->hlen = 0; + winmxhdr->datalen = curhdr->datalen; + winmxhdr->data = curhdr->data; + winmxhdr->next_hdr = NULL; + winmxhdr->proto_info = NULL; + return winmxhdr; +} + +void pie_winmx_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_winmx_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_winmx_fd = pie_reg_protocol("winmx",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_winmx_new_session,&pie_winmx_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_winmx_session_cleanup,&pie_winmx_packet_cleanup); + if (pie_proto_winmx_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_winmx_fd,&pie_winmx_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load winmx module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("winmx",pie_proto_winmx_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/xunlei.c linux-2.6.27.8-hippie/net/hippie/proto/xunlei.c --- linux-2.6.27.8/net/hippie/proto/xunlei.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/xunlei.c 2008-02-04 10:07:34.000000000 -0600 @@ -0,0 +1,125 @@ +/* + * Hi-Performance Protocol Identification Engine Xunlei P2P Module - xunlei.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Peer-to-Peer Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_xunlei_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE Xunlei P2P Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_xunlei_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for Xunlei P2P Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_xunlei_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_xunlei_udpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen > 12) { + u_int8_t header32[4] = { 0x32, 0x00, 0x00, 0x00 }; + u_int8_t header38[4] = { 0x38, 0x00, 0x00, 0x00 }; + if (pie_payload_search(curhdr->data,curhdr->data,header32,4) != NULL) { + u_int32_t dlen = curhdr->data[26] * 256 + curhdr->data[25]; + if (curhdr->datalen == dlen + 29) { + return 1; + } + } + /*if (pie_payload_search(curhdr->data,curhdr->data,header38,4) != NULL) { + if (curhdr->data[4] == 0xfc && curhdr->datalen >= 45) { + u_int16_t dlen = curhdr->data[45] * 16 + 30; + if (curhdr->datalen == dlen) { + return 1; + } + } + }*/ + } + return 0; +} + +int pie_xunlei_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen > 12) { + u_int8_t header1[4] = { 0x02, 0x00, 0x02, 0x00 }; + u_int8_t header2[4] = { 0x38, 0x00, 0x00, 0x00 }; + u_int8_t header3[4] = { 0x29, 0x00, 0x00, 0x00 }; + u_int8_t header4[4] = { 0x32, 0x00, 0x00, 0x00 }; + if (pie_payload_search(curhdr->data,curhdr->data,header1,4) != NULL || pie_payload_search(curhdr->data,curhdr->data,header3,4) != NULL) { + /* Either 0x02 or 0x29, meaning bytes 8-11 is a 32-bit remaining packet length */ + u_int32_t dlen = ((curhdr->data[11] * 256 + curhdr->data[10]) * 256 + curhdr->data[9]) * 256 + curhdr->data[8]; + if (curhdr->datalen == dlen + 12) { + /* Xunlei contains a packet length field, and in these two op codes, this is bytes 8-11 in big endian. */ + return 1; + } + } + if (pie_payload_search(curhdr->data,curhdr->data,header2,4) != NULL) { + /* 0x38 header, meaning bytes 4-7 is a 32-bit remaining packet length */ + u_int32_t dlen = ((curhdr->data[7] * 256 + curhdr->data[6]) * 256 + curhdr->data[5]) * 256 + curhdr->data[4]; + if (curhdr->datalen == dlen + 8) { + return 1; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_xunlei_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *xunleihdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (xunleihdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate Xunlei P2P Session Header.\n"); + return NULL; + } + xunleihdr->protoindex = pie_proto_xunlei_fd; + xunleihdr->header = NULL; + xunleihdr->hlen = 0; + xunleihdr->datalen = curhdr->datalen; + xunleihdr->data = curhdr->data; + xunleihdr->next_hdr = NULL; + xunleihdr->proto_info = NULL; + return xunleihdr; +} + +void pie_xunlei_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_xunlei_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_xunlei_fd = pie_reg_protocol("xunlei",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_xunlei_new_session,&pie_xunlei_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_xunlei_session_cleanup,&pie_xunlei_packet_cleanup); + if (pie_proto_xunlei_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_xunlei_fd,&pie_xunlei_tcpfind); + pie_reg_subprotocol("udp",pie_proto_xunlei_fd,&pie_xunlei_udpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load xunlei module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("xunlei",pie_proto_xunlei_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/hippie/proto/yahooim.c linux-2.6.27.8-hippie/net/hippie/proto/yahooim.c --- linux-2.6.27.8/net/hippie/proto/yahooim.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/hippie/proto/yahooim.c 2008-02-08 10:35:58.000000000 -0600 @@ -0,0 +1,91 @@ +/* + * Hi-Performance Protocol Identification Engine Yahoo Instant Messenger Module - yahooim.c + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + * Protocol Group: Instant Messaging Protocols + */ + +#include +#include +#include +#include + +#include +#include + +u_int16_t pie_proto_yahooim_fd = 0; + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("HiPPIE Yahoo Instant Messenger Protocol Classification Module"); +MODULE_LICENSE("GPL"); + +struct pie_protocol_sess *pie_yahooim_new_session(struct pie_protocol_hdr *pkthdr) { + struct pie_protocol_sess *sess = kmalloc(sizeof(struct pie_protocol_sess),GFP_KERNEL); + if (sess == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate memory for Yahoo IM Session header.\n"); + return NULL; + } + sess->protoindex = pie_proto_yahooim_fd; + sess->next_sess = NULL; + sess->proto_info = NULL; + return sess; +} + +int pie_yahooim_tcpfind(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + if (curhdr->datalen >= 20) { + u_int8_t ymsg[4] = {'Y','M','S','G'}; + /* Check for commands */ + if (pie_payload_search(curhdr->data,curhdr->data,ymsg,4) != NULL) { + u_int16_t datalen = 256 * curhdr->data[8] + curhdr->data[9]; + if (curhdr->datalen == datalen + 20) { + return 1; + } + } + } + return 0; +} + +struct pie_protocol_hdr *pie_yahooim_packet_mockup(struct pie_packet_info *pktinfo, struct pie_protocol_hdr *curhdr) { + struct pie_protocol_hdr *yahooimhdr = kmalloc(sizeof(struct pie_protocol_hdr),GFP_KERNEL); + if (yahooimhdr == NULL) { + printk(KERN_ALERT "HiPPIE: Failed to allocate Yahoo IM Session Header.\n"); + return NULL; + } + yahooimhdr->protoindex = pie_proto_yahooim_fd; + yahooimhdr->header = NULL; + yahooimhdr->hlen = 0; + yahooimhdr->datalen = curhdr->datalen; + yahooimhdr->data = curhdr->data; + yahooimhdr->next_hdr = NULL; + yahooimhdr->proto_info = NULL; + return yahooimhdr; +} + +void pie_yahooim_session_cleanup(struct pie_protocol_sess *sess) { + kfree(sess); +} + +void pie_yahooim_packet_cleanup(struct pie_protocol_hdr *hdr) { + kfree(hdr); +} + +static int __init init(void) { + pie_proto_yahooim_fd = pie_reg_protocol("yahooim",PIE_PROTOTYPE_APP,PIE_ENCAP_NONE,10,NULL,NULL,&pie_yahooim_new_session,&pie_yahooim_packet_mockup,NULL,NULL,NULL,NULL,NULL,NULL,&pie_yahooim_session_cleanup,&pie_yahooim_packet_cleanup); + if (pie_proto_yahooim_fd > 0) { + pie_reg_subprotocol("tcp",pie_proto_yahooim_fd,&pie_yahooim_tcpfind); + return 0; + } else { + printk(KERN_WARNING "HiPPIE: Failed to load yahooim module.\n"); + return -1; + } +} + +static void __exit fini(void) { + pie_unreg_protocol("yahooim",pie_proto_yahooim_fd); +} + +module_init(init); +module_exit(fini); + diff -Nru -X excludes.txt linux-2.6.27.8/net/netfilter/Kconfig linux-2.6.27.8-hippie/net/netfilter/Kconfig --- linux-2.6.27.8/net/netfilter/Kconfig 2008-12-05 14:03:02.000000000 -0600 +++ linux-2.6.27.8-hippie/net/netfilter/Kconfig 2008-12-06 21:06:00.000000000 -0600 @@ -781,6 +781,16 @@ To compile it as a module, choose M here. If unsure, say N. +config NETFILTER_XT_MATCH_HIPPIE + tristate '"hippie" match support' + depends on NETFILTER_XTABLES + depends on HIPPIE + help + This option adds a `hippie' match, which allows you to match packets + using the Hi-Performance Protocol Identification Engine. + + To compile it as a module, choose M here. If unsure, say N. + config NETFILTER_XT_MATCH_TCPMSS tristate '"tcpmss" match support' depends on NETFILTER_XTABLES diff -Nru -X excludes.txt linux-2.6.27.8/net/netfilter/Makefile linux-2.6.27.8-hippie/net/netfilter/Makefile --- linux-2.6.27.8/net/netfilter/Makefile 2008-12-05 14:03:02.000000000 -0600 +++ linux-2.6.27.8-hippie/net/netfilter/Makefile 2008-12-06 21:06:00.000000000 -0600 @@ -80,6 +80,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o +obj-$(CONFIG_NETFILTER_XT_MATCH_HIPPIE) += xt_hippie.o obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o diff -Nru -X excludes.txt linux-2.6.27.8/net/netfilter/nf_conntrack_core.c linux-2.6.27.8-hippie/net/netfilter/nf_conntrack_core.c --- linux-2.6.27.8/net/netfilter/nf_conntrack_core.c 2008-12-05 14:03:02.000000000 -0600 +++ linux-2.6.27.8-hippie/net/netfilter/nf_conntrack_core.c 2008-12-06 21:06:00.000000000 -0600 @@ -39,6 +39,10 @@ #include #include +#ifdef CONFIG_HIPPIE_NETFILTER_FEED + #include +#endif + #define NF_CONNTRACK_VERSION "0.5.0" DEFINE_SPINLOCK(nf_conntrack_lock); @@ -713,6 +717,10 @@ return NF_ACCEPT; } +#ifdef CONFIG_HIPPIE_NETFILTER_FEED + pie_packet_read((*pskb)->data,(*pskb)->len); +#endif + if (IS_ERR(ct)) { /* Too stressed to deal. */ NF_CT_STAT_INC_ATOMIC(drop); diff -Nru -X excludes.txt linux-2.6.27.8/net/netfilter/xt_hippie.c linux-2.6.27.8-hippie/net/netfilter/xt_hippie.c --- linux-2.6.27.8/net/netfilter/xt_hippie.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.27.8-hippie/net/netfilter/xt_hippie.c 2007-09-20 09:28:10.000000000 -0500 @@ -0,0 +1,122 @@ +/* + * Hi-Performance Protocol Identification Engine Netfilter Plugin Headers - ipt_hippie.h + * Copyright 2004, Josh Ballard, oofle.com Security + * Author: Josh Ballard + * Project Page: http://hippie.oofle.com + * This software is distributed under the terms of the GPL, Version 2 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) +#include +//#include +#else +#include +#endif + + +MODULE_AUTHOR("Josh Ballard "); +MODULE_DESCRIPTION("Netfilter xtables HiPPIE Protocol Identification matching module"); +MODULE_LICENSE("GPL"); + +static int match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct xt_match *match, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + const struct xt_hippie_info *info = matchinfo; + int matchret = 0; + + //enum ip_conntrack_info ctinfo; + //struct ip_conntrack *ct = nf_conntrack_get(skb->nfct); + int sigcode = 0; + switch (info->opcode) { + case NF_HIPPIE_PROTO: + sigcode = pie_get_protocolid((char *)info->name); + //matchret = pie_packet_inspect(skb->data,skb->len,sigcode); + matchret = pie_skb_inspect(skb,sigcode); + break; + case NF_HIPPIE_ENCAP: + sigcode = pie_get_protocolid((char *)info->name); + //matchret = pie_packet_checkencap(skb->data,skb->len,sigcode); + matchret = pie_skb_checkencap(skb,sigcode); + break; + case NF_HIPPIE_MPROTO: + //matchret = pie_packet_multiinspect(skb->data,skb->len,info->name); + matchret = pie_skb_multiinspect(skb,info->name); + break; + } + if (info->invert) { + if (matchret > 0) { + return 0; + } else { + return 1; + } + } else { + if (matchret > 0) { + return 1; + } else { + return 0; + } + } + return 0; +} + +static int checkentry(const char *tablename, + const void *ip, + const struct xt_match *match, + void *matchinfo, + unsigned int hook_mask) +{ + struct xt_hippie_info *conf = matchinfo; + + /* Return 0 for invalids */ + + return 1; +} + +static struct xt_match xt_hippie_match[] = { + { + .name = "hippie", + .family = AF_INET, + .checkentry = checkentry, + .match = match, + .matchsize = sizeof(struct xt_hippie_info), + .me = THIS_MODULE + }, + // Once IPv6 is implemented. + /*{ + .name = "hippie", + .family = AF_INET6, + .checkentry = checkentry, + .match = match, + .destroy = destroy, + .matchsize = sizeof(struct xt_hippie_info), + .me = THIS_MODULE + },*/ +}; + +static int __init xt_hippie_init(void) { + return xt_register_matches(xt_hippie_match, ARRAY_SIZE(xt_hippie_match)); +} + +static void __exit xt_hippie_fini(void) { + xt_unregister_matches(xt_hippie_match, ARRAY_SIZE(xt_hippie_match)); +} + +module_init(xt_hippie_init); +module_exit(xt_hippie_fini); +