diff options
| author | lijia <[email protected]> | 2018-10-24 09:36:45 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2018-10-24 09:36:45 +0800 |
| commit | 86a43b4d325ddc850fa9dc4711670880f35b11e8 (patch) | |
| tree | 8356a056ac9bfb8cf14fcf57f113dd306b4277d1 /support/ltsm | |
create new project.
Diffstat (limited to 'support/ltsm')
| -rw-r--r-- | support/ltsm/Makefile | 14 | ||||
| -rw-r--r-- | support/ltsm/ltsm.c | 485 | ||||
| -rw-r--r-- | support/ltsm/ltsm.h | 117 | ||||
| -rw-r--r-- | support/ltsm/ltsm_with_hash.h | 81 | ||||
| -rw-r--r-- | support/ltsm/test_ltsm.c | 59 |
5 files changed, 756 insertions, 0 deletions
diff --git a/support/ltsm/Makefile b/support/ltsm/Makefile new file mode 100644 index 0000000..1cb32b7 --- /dev/null +++ b/support/ltsm/Makefile @@ -0,0 +1,14 @@ +all:test_ltsm.so libltsm.a + +libltsm.a:ltsm.o + ar -r $@ $^; + cp $@ ../../lib + +test_ltsm.so:test_ltsm.o ltsm.o + gcc -fPIC -shared -o $@ $^ -I/opt/MESA/include/MESA + +test_ltsm.o:test_ltsm.c + gcc -fPIC -c -D__USE_MISC -D_BSD_SOURCE -o $@ $^ -I/opt/MESA/include/MESA + +ltsm.o:ltsm.c + gcc -fPIC -c -D__USE_MISC -D_BSD_SOURCE -o $@ $^ -I/opt/MESA/include/MESA diff --git a/support/ltsm/ltsm.c b/support/ltsm/ltsm.c new file mode 100644 index 0000000..c8af056 --- /dev/null +++ b/support/ltsm/ltsm.c @@ -0,0 +1,485 @@ +
+
+#include <netinet/ip.h>
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+
+/*
+ * The TCP state transition table needs a few words...
+ *
+ * We are the man in the middle. All the packets go through us
+ * but might get lost in transit to the destination.
+ * It is assumed that the destinations can't receive segments
+ * we haven't seen.
+ *
+ * The checked segment is in window, but our windows are *not*
+ * equivalent with the ones of the sender/receiver. We always
+ * try to guess the state of the current sender.
+ *
+ * The meaning of the states are:
+ *
+ * NONE: initial state
+ * SYN_SENT: SYN-only packet seen
+ * SYN_SENT2: SYN-only packet seen from reply dir, simultaneous open
+ * SYN_RECV: SYN-ACK packet seen
+ * ESTABLISHED: ACK packet seen
+ * FIN_WAIT: FIN packet seen
+ * CLOSE_WAIT: ACK seen (after FIN)
+ * LAST_ACK: FIN seen (after FIN)
+ * TIME_WAIT: last ACK seen
+ * CLOSE: closed connection (RST)
+ *
+ * Packets marked as IGNORED (sIG):
+ * if they may be either invalid or valid
+ * and the receiver may send back a connection
+ * closing RST or a SYN/ACK.
+ *
+ * Packets marked as INVALID (sIV):
+ * if we regard them as truly invalid packets
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip.h>
+#include <assert.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include "ltsm.h"
+
+
+
+enum tcp_conntrack {
+ TCP_CONNTRACK_NONE,
+ TCP_CONNTRACK_SYN_SENT,
+ TCP_CONNTRACK_SYN_RECV,
+ TCP_CONNTRACK_ESTABLISHED,
+ TCP_CONNTRACK_FIN_WAIT,
+ TCP_CONNTRACK_CLOSE_WAIT,
+ TCP_CONNTRACK_LAST_ACK,
+ TCP_CONNTRACK_TIME_WAIT,
+ TCP_CONNTRACK_CLOSE,
+ TCP_CONNTRACK_LISTEN, /* obsolete */
+#define TCP_CONNTRACK_SYN_SENT2 TCP_CONNTRACK_LISTEN
+ TCP_CONNTRACK_MAX,
+ TCP_CONNTRACK_IGNORE
+};
+
+
+/* What TCP flags are set from RST/SYN/FIN/ACK. */
+enum tcp_bit_set {
+ TCP_SYN_SET,
+ TCP_SYNACK_SET,
+ TCP_FIN_SET,
+ TCP_ACK_SET,
+ TCP_RST_SET,
+ TCP_NONE_SET,
+};
+
+#define TCP_URG_FLAG 0x20
+#define TCP_ACK_FLAG 0x10
+#define TCP_PSH_FLAG 0x08
+#define TCP_RST_FLAG 0x04
+#define TCP_SYN_FLAG 0x02
+#define TCP_FIN_FLAG 0x01
+#define TCP_FLAG_ALL 0x3F
+
+
+#define sNO TCP_CONNTRACK_NONE
+#define sSS TCP_CONNTRACK_SYN_SENT
+#define sSR TCP_CONNTRACK_SYN_RECV
+#define sES TCP_CONNTRACK_ESTABLISHED
+#define sFW TCP_CONNTRACK_FIN_WAIT
+#define sCW TCP_CONNTRACK_CLOSE_WAIT
+#define sLA TCP_CONNTRACK_LAST_ACK
+#define sTW TCP_CONNTRACK_TIME_WAIT
+#define sCL TCP_CONNTRACK_CLOSE
+#define sS2 TCP_CONNTRACK_SYN_SENT2
+#define sIV TCP_CONNTRACK_MAX
+#define sIG TCP_CONNTRACK_IGNORE
+
+static const struct ltsm_result g_tsm_first_void = {FTSM_VOID, LTSM_VOID}; /* ��SYN��, ��������״̬, ����void */
+static const struct ltsm_result g_tsm_first_start = {TCP_CONNTRACK_SYN_SENT, LTSM_START};
+
+
+static const char *g_ftsm_string[] =
+{
+ "VOID",
+ "FTSM_SYN_SENT",
+ "FTSM_SYN_RCVD",
+ "FTSM_ESTABLISHED",
+ "FTSM_FIN_WAIT",
+ "FTSM_CLOSE_WAIT",
+ "FTSM_LAST_ACK",
+ "FTSM_TIME_WAIT",
+ "FTSM_CLOSED",
+ "FTSM_LISTEN",
+ "__FTSM_MAX",
+};
+
+static const char *g_ltsm_string[] =
+{
+ "LTSM_VOID",
+ "LTSM_START",
+ "LTSM_DATA",
+ "LTSM_CLOSE",
+};
+
+
+
+static const enum light_tcp_state g_ltsm_full2light_table[12] =
+{
+ LTSM_VOID, /* TCP_CONNTRACK_NONE, */
+ LTSM_START, /* TCP_CONNTRACK_SYN_SENT, */
+ LTSM_DATA, /* TCP_CONNTRACK_SYN_RECV, */
+ LTSM_DATA, /* TCP_CONNTRACK_ESTABLISHED, */
+ LTSM_DATA, /* TCP_CONNTRACK_FIN_WAIT, */
+ LTSM_DATA, /* TCP_CONNTRACK_CLOSE_WAIT, */
+ LTSM_DATA, /* TCP_CONNTRACK_LAST_ACK, */
+ LTSM_CLOSE, /* TCP_CONNTRACK_TIME_WAIT, */
+ LTSM_CLOSE, /* TCP_CONNTRACK_CLOSE, */
+ LTSM_VOID, /* TCP_CONNTRACK_LISTEN, */
+ LTSM_VOID, /* TCP_CONNTRACK_MAX, */
+ LTSM_VOID, /* TCP_CONNTRACK_IGNORE */
+};
+
+/*
+ if dir == 0, packet from client; if dir == 1, packet from service.
+
+ new_tcp_state = tcp_conntracks[dir][new_tcp_flag][old_tcp_state];
+*/
+static const uint8_t tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
+ {/* ORIGINAL */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*syn*/ {sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sS2},
+ /*
+ * sNO -> sSS Initialize a new connection
+ * sSS -> sSS Retransmitted SYN
+ * sS2 -> sS2 Late retransmitted SYN
+ * sSR -> sIG
+ * sES -> sIG Error: SYNs in window outside the SYN_SENT state
+ * are errors. Receiver will reply with RST
+ * and close the connection.
+ * Or we are not in sync and hold a dead connection.
+ * sFW -> sIG
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sSS Reopened connection (RFC 1122).
+ * sCL -> sSS
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*synack*/ {sIV, sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR},
+ /*
+ * sNO -> sIV Too late and no reason to do anything
+ * sSS -> sIV Client can't send SYN and then SYN/ACK
+ * sS2 -> sSR SYN/ACK sent to SYN2 in simultaneous open
+ * sSR -> sIG
+ * sES -> sIG Error: SYNs in window outside the SYN_SENT state
+ * are errors. Receiver will reply with RST
+ * and close the connection.
+ * Or we are not in sync and hold a dead connection.
+ * sFW -> sIG
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sIG
+ * sCL -> sIG
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*fin*/ {sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV},
+ /*
+ * sNO -> sIV Too late and no reason to do anything...
+ * sSS -> sIV Client migth not send FIN in this state:
+ * we enforce waiting for a SYN/ACK reply first.
+ * sS2 -> sIV
+ * sSR -> sFW Close started.
+ * sES -> sFW
+ * sFW -> sLA FIN seen in both directions, waiting for
+ * the last ACK.
+ * Migth be a retransmitted FIN as well...
+ * sCW -> sLA
+ * sLA -> sLA Retransmitted FIN. Remain in the same state.
+ * sTW -> sTW
+ * sCL -> sCL
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*ack*/ {sES, sIV, sES, sES, sCW, sCW, sTW, sTW, sCL, sIV},
+ /*
+ * sNO -> sES Assumed.
+ * sSS -> sIV ACK is invalid: we haven't seen a SYN/ACK yet.
+ * sS2 -> sIV
+ * sSR -> sES Established state is reached.
+ * sES -> sES :-)
+ * sFW -> sCW Normal close request answered by ACK.
+ * sCW -> sCW
+ * sLA -> sTW Last ACK detected.
+ * sTW -> sTW Retransmitted last ACK. Remain in the same state.
+ * sCL -> sCL
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*rst*/ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
+ /*none*/ {sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV}},
+
+ {/******************************** REPLY *******************************/
+
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*syn*/ {sIV, sS2, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sS2},
+ /*
+ * sNO -> sIV Never reached.
+ * sSS -> sS2 Simultaneous open
+ * sS2 -> sS2 Retransmitted simultaneous SYN
+ * sSR -> sIV Invalid SYN packets sent by the server
+ * sES -> sIV
+ * sFW -> sIV
+ * sCW -> sIV
+ * sLA -> sIV
+ * sTW -> sIV Reopened connection, but server may not do it.
+ * sCL -> sIV
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*synack*/ {sIV, sSR, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sSR},
+ /*
+ * sSS -> sSR Standard open.
+ * sS2 -> sSR Simultaneous open
+ * sSR -> sSR Retransmitted SYN/ACK.
+ * sES -> sIG Late retransmitted SYN/ACK?
+ * sFW -> sIG Might be SYN/ACK answering ignored SYN
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sIG
+ * sCL -> sIG
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*fin*/ {sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV},
+ /*
+ * sSS -> sIV Server might not send FIN in this state.
+ * sS2 -> sIV
+ * sSR -> sFW Close started.
+ * sES -> sFW
+ * sFW -> sLA FIN seen in both directions.
+ * sCW -> sLA
+ * sLA -> sLA Retransmitted FIN.
+ * sTW -> sTW
+ * sCL -> sCL
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*ack*/ {sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIG},
+ /*
+ * sSS -> sIG Might be a half-open connection.
+ * sS2 -> sIG
+ * sSR -> sSR Might answer late resent SYN.
+ * sES -> sES :-)
+ * sFW -> sCW Normal close request answered by ACK.
+ * sCW -> sCW
+ * sLA -> sTW Last ACK detected.
+ * sTW -> sTW Retransmitted last ACK.
+ * sCL -> sCL
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*rst*/ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
+ /*none*/ {sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV}}
+ };
+
+typedef struct{
+ uint32_t sip_net_order;
+ uint32_t dip_net_order;
+ uint16_t sport_net_order;
+ uint16_t dport_net_order;
+ uint8_t old_state;
+ uint8_t cur_state;
+ uint8_t create_dir;
+}ltsm_inner_t;
+
+
+const char *ltsm_fstate_ntop(enum full_tcp_state fstate)
+{
+ if((int)fstate < 0 || (int)fstate >= __FTSM_MAX){
+ return "Invalid";
+ }
+
+ return g_ftsm_string[fstate];
+}
+
+
+const char *ltsm_lstate_ntop(enum light_tcp_state lstate)
+{
+ if((int)lstate < 0 || (int)lstate > LTSM_CLOSE){
+ return "Invalid";
+ }
+
+ return g_ltsm_string[lstate];
+}
+
+
+
+static inline uint32_t ltsm_get_tcpflags(const struct ltsm_tcphdr *th) {
+ if (th->th_flags & TCP_RST_FLAG)
+ return TCP_RST_SET;
+ else if (th->th_flags & TCP_SYN_FLAG)
+ return ((th->th_flags & TCP_ACK_FLAG) ? TCP_SYNACK_SET : TCP_SYN_SET);
+ else if (th->th_flags & TCP_FIN_FLAG)
+ return TCP_FIN_SET;
+ else if (th->th_flags & TCP_ACK_FLAG)
+ return TCP_ACK_SET;
+ else
+ return TCP_NONE_SET;
+}
+
+
+static inline uint32_t ltsm_convert_tcpflags(uint8_t th_flags) {
+ if (th_flags & TCP_RST_FLAG)
+ return TCP_RST_SET;
+ else if (th_flags & TCP_SYN_FLAG)
+ return ((th_flags & TCP_ACK_FLAG) ? TCP_SYNACK_SET : TCP_SYN_SET);
+ else if (th_flags & TCP_FIN_FLAG)
+ return TCP_FIN_SET;
+ else if (th_flags & TCP_ACK_FLAG)
+ return TCP_ACK_SET;
+ else
+ return TCP_NONE_SET;
+}
+
+
+ltsm_stream_handle ltsm_create_handle(void)
+{
+ ltsm_inner_t *ltsm_inner;
+
+ ltsm_inner = calloc(1, sizeof(ltsm_inner_t));
+
+ ltsm_inner->old_state = TCP_CONNTRACK_SYN_SENT;
+
+ return ltsm_inner;
+}
+
+
+
+ltsm_stream_handle ltsm_create_stream_handle(const struct ltsm_iphdr * iphdr)
+{
+ const struct ltsm_tcphdr *tcp_hdr;
+ ltsm_inner_t *ltsm_inner;
+ int dir = 0;
+ uint32_t tcp_flags_set;
+
+ if(IPPROTO_TCP != iphdr->ip_p){
+ return NULL;
+ }
+
+ tcp_hdr = (const struct ltsm_tcphdr *)((char *)iphdr + iphdr->ip_hl*4);
+ if(TH_SYN == tcp_hdr->th_flags){
+ dir = 0;
+ }else if(TH_SYN|TH_ACK == tcp_hdr->th_flags){
+ dir = 1;
+ }else{
+ return NULL;
+ }
+
+ ltsm_inner = calloc(1, sizeof(ltsm_inner_t));
+ ltsm_inner->old_state = TCP_CONNTRACK_NONE;
+ ltsm_inner->sip_net_order = iphdr->ip_src.s_addr;
+ ltsm_inner->dip_net_order = iphdr->ip_dst.s_addr;
+ ltsm_inner->sport_net_order = tcp_hdr->th_sport;
+ ltsm_inner->dport_net_order = tcp_hdr->th_dport;
+
+ tcp_flags_set = ltsm_get_tcpflags(tcp_hdr);
+
+ ltsm_inner->cur_state = tcp_conntracks[dir][tcp_flags_set][ltsm_inner->old_state];
+ ltsm_inner->create_dir = dir;
+
+ return ltsm_inner;
+}
+
+
+uint8_t ltsm_proc_ipv4tcppkt(ltsm_stream_handle s_ltsm, const struct ltsm_iphdr *iphdr)
+{
+ uint8_t tcpstate;
+ ltsm_inner_t *ltsm_inner = (ltsm_inner_t *)s_ltsm;
+ int dir = 0;
+ uint32_t tcp_flags_set;
+ const struct ltsm_tcphdr *tcp_hdr;
+
+ if(IPPROTO_TCP != iphdr->ip_p){
+ return LTSM_VOID;
+ }
+
+ tcp_hdr = (const struct ltsm_tcphdr *)((char *)iphdr + iphdr->ip_hl*4);
+ tcp_flags_set = ltsm_get_tcpflags(tcp_hdr);
+
+ if((ltsm_inner->sip_net_order == iphdr->ip_src.s_addr)
+ && (ltsm_inner->dip_net_order == iphdr->ip_dst.s_addr)
+ && (ltsm_inner->sport_net_order == tcp_hdr->th_sport)
+ && (ltsm_inner->dport_net_order == tcp_hdr->th_dport)){
+ dir = ltsm_inner->create_dir;
+ }else{
+ dir = ltsm_inner->create_dir ^ 1;
+ }
+
+ tcpstate = tcp_conntracks[dir][tcp_flags_set][ltsm_inner->old_state];
+
+ if(tcpstate < TCP_CONNTRACK_MAX){
+ ltsm_inner->old_state = tcpstate;
+ }
+
+ return tcpstate;
+}
+
+void ltsm_destroy_stream_handle(ltsm_stream_handle pltsm)
+{
+ free(pltsm);
+}
+
+void ltsm_destroy_handle(ltsm_stream_handle pltsm)
+{
+ free(pltsm);
+}
+
+
+
+struct ltsm_result ltsm_get_current_state(ltsm_stream_handle pltsm, uint8_t tcp_flags, uint8_t dir)
+{
+ uint8_t tcp_fstate;
+ uint32_t tcp_flags_set;
+ struct ltsm_result res;
+
+ if(NULL == pltsm){
+ if(TH_SYN != tcp_flags){
+ return g_tsm_first_void;
+ }
+
+ return g_tsm_first_start;
+ }
+
+ ltsm_inner_t *ltsm_inner = (ltsm_inner_t *)pltsm;
+
+ tcp_flags_set = ltsm_convert_tcpflags(tcp_flags);
+ tcp_fstate = tcp_conntracks[dir][tcp_flags_set][ltsm_inner->old_state];
+
+ ltsm_inner->old_state = tcp_fstate;
+
+ res.fstate = tcp_fstate;
+ res.lstate = g_ltsm_full2light_table[tcp_fstate];
+
+ return res;
+}
+
+
+uint32_t ltsm_tcp_key_generate(uint32_t sip_net_order, uint32_t dip_net_order, uint16_t sport_net_order, uint16_t dport_net_order)
+{
+
+}
+
+int ltsm_tcp_key_verify(const struct ip * iphdr)
+{
+
+}
+
diff --git a/support/ltsm/ltsm.h b/support/ltsm/ltsm.h new file mode 100644 index 0000000..340aa2f --- /dev/null +++ b/support/ltsm/ltsm.h @@ -0,0 +1,117 @@ +#ifndef __LTSM_H_
+#define __LTSM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ LTSM : Light TCP State Machine.
+ Version : 2018-01-16
+*/
+
+/* RFC��TCPЭ��ջ״̬������ */
+enum full_tcp_state{
+ FTSM_VOID, /* ���һ�����ĵ�һ��������SYN��, ���ش�ֵ */
+ FTSM_SYN_SENT,
+ FTSM_SYN_RCVD,
+ FTSM_ESTABLISHED,
+ FTSM_FIN_WAIT,
+ FTSM_CLOSE_WAIT,
+ FTSM_LAST_ACK,
+ FTSM_TIME_WAIT,
+ FTSM_CLOSED,
+ FTSM_LISTEN,
+ __FTSM_MAX,
+};
+
+/*
+ ����TCP״̬������,
+ ʵ��ֻ������״̬:�½�����, ��������, ��������,
+ ÿ�����ض�����1��START��1��CLOSE״̬, ���ܰ���0�����ɸ�DATA״̬.
+
+ VOID״̬���ڵ����߿����ж��Ƿ���Ҫ��������.
+*/
+enum light_tcp_state{
+ LTSM_VOID, /* ���һ�����ĵ�һ��������SYN��, ���ش�ֵ */
+ LTSM_START,
+ LTSM_DATA,
+ LTSM_CLOSE,
+};
+
+struct ltsm_iphdr
+ {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ip_hl:4; /* header length */
+ unsigned int ip_v:4; /* version */
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int ip_v:4; /* version */
+ unsigned int ip_hl:4; /* header length */
+#endif
+ u_int8_t ip_tos; /* type of service */
+ u_short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ u_short ip_off; /* fragment offset field */
+#define IP_RF 0x8000 /* reserved fragment flag */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_int8_t ip_ttl; /* time to live */
+ u_int8_t ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ struct in_addr ip_src, ip_dst; /* source and dest address */
+ };
+
+struct ltsm_tcphdr
+ {
+ u_int16_t th_sport; /* source port */
+ u_int16_t th_dport; /* destination port */
+ u_int32_t th_seq; /* sequence number */
+ u_int32_t th_ack; /* acknowledgement number */
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_int8_t th_x2:4; /* (unused) */
+ u_int8_t th_off:4; /* data offset */
+# endif
+# if __BYTE_ORDER == __BIG_ENDIAN
+ u_int8_t th_off:4; /* data offset */
+ u_int8_t th_x2:4; /* (unused) */
+# endif
+ u_int8_t th_flags;
+# define TH_FIN 0x01
+# define TH_SYN 0x02
+# define TH_RST 0x04
+# define TH_PUSH 0x08
+# define TH_ACK 0x10
+# define TH_URG 0x20
+ u_int16_t th_win; /* window */
+ u_int16_t th_sum; /* checksum */
+ u_int16_t th_urp; /* urgent pointer */
+};
+
+struct ltsm_result{
+ enum full_tcp_state fstate;
+ enum light_tcp_state lstate;
+};
+
+typedef void * ltsm_stream_handle;
+
+ltsm_stream_handle ltsm_create_handle(void);
+
+#define LTSM_DIR_C2S 0
+#define LTSM_DIR_S2C 1
+
+struct ltsm_result ltsm_get_current_state(ltsm_stream_handle pltsm, uint8_t tcp_flags, uint8_t dir);
+
+const char *ltsm_fstate_ntop(enum full_tcp_state fstate);
+const char *ltsm_lstate_ntop(enum light_tcp_state lstate);
+
+void ltsm_destroy_handle(ltsm_stream_handle pltsm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/support/ltsm/ltsm_with_hash.h b/support/ltsm/ltsm_with_hash.h new file mode 100644 index 0000000..0404f3d --- /dev/null +++ b/support/ltsm/ltsm_with_hash.h @@ -0,0 +1,81 @@ +#ifndef LTSM_H_
+#define LTSM_H_
+
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include "mesa_net.h"
+/*
+ LTSM : Light TCP State Machine.
+
+*/
+
+/* RFC��TCPЭ��ջ״̬������ */
+enum full_tcp_state{
+ FTSM_CLOSED,
+ FTSM_LISTEN,
+ FTSM_SYN_SENT,
+ FTSM_SYN_RCVD,
+ FTSM_ESTABLISHED,
+ FTSM_CLOSE_WAIT,
+ FTSM_LAST_ACK,
+ FTSM_FIN_WAIT1,
+ FTSM_FIN_WAIT2,
+ FTSM_CLOSING,
+ FTSM_TIME_WAIT,
+};
+
+/*
+ ����TCP״̬������,
+ ֻ������״̬:�½�����, ��������, ��������,
+ ÿ�����ض�����1��START��1��CLOSE״̬, ���ܰ���0�����ɸ�DATA״̬.
+*/
+enum light_tcp_state{
+ LTSM_START,
+ LTSM_DATA,
+ LTSM_CLOSE,
+ LTSM_INVALID,
+};
+
+
+enum light_tsm_opt{
+ LTSMO_THREAD_NUM, /* �߳�����, ѡ������:uint32 */
+ LTSMO_CREATE_MODE, /* ������ģʽ, 1:�������SYN; 2:�������ݰ��ɴ���, ѡ������:uint32 */
+ LTSMO_MAX_STREAM_NUM, /* TCP���������, forÿ���߳�, ѡ������:uint32 */
+ LTSMO_STREAM_TIMEOUT, /* ����ʱ��̭ʱ��, ��λ:��, 0��ʾ����ʱ. ѡ������:uint32 */
+};
+
+struct ltsm_result{
+ enum full_tcp_state fstate;
+ enum light_tcp_state lstate;
+ void *pme;
+};
+
+typedef void * ltsm_global_handle;
+typedef void * ltsm_stream_handle;
+
+/* ltsmȫ�־����ʼ�� */
+void *ltsm_init(void);
+
+/* ltsm������ز��� */
+int ltsm_set_opt(ltsm_global_handle pltsm, enum light_tsm_opt opt, void *value, int value_len);
+
+/* ltsm���� */
+int ltsm_run(ltsm_global_handle pltsm);
+
+/* IPv4������, ���ص�ǰ��������ltsm״̬�����, pme�����ⲿ�����ߴ洢�Զ�������, �ڴ�������������ͷ� */
+struct ltsm_result *ltsm_proc_ip4pkt(ltsm_global_handle pltsm, int tseq, const struct ip *ip4hdr);
+
+/* IPv4��ͷ+TCP��ͷ����, ���ص�ǰ��������ltsm״̬�����, pme�����ⲿ�����ߴ洢�Զ�������, �ڴ�������������ͷ� */
+struct ltsm_result *ltsm_proc_ip4tcppkt(ltsm_global_handle pltsm, int tseq, const struct ip *ip4hdr, const struct tcphdr *tcp_hdr);
+
+/* IPv6������, ���ص�ǰ��������ltsm״̬�����, pme�����ⲿ�����ߴ洢�Զ�������, �ڴ�������������ͷ� */
+struct ltsm_result *ltsm_proc_ip6pkt(ltsm_global_handle pltsm, int tseq, const struct ip6_hdr *ip6hdr);
+
+/* IPv6��ͷ+TCP��ͷ����, ���ص�ǰ��������ltsm״̬�����, pme�����ⲿ�����ߴ洢�Զ�������, �ڴ�������������ͷ� */
+struct ltsm_result *ltsm_proc_ip6tcppkt(ltsm_global_handle pltsm, int tseq, const struct ip6_hdr *ip6hdr, const struct tcphdr *tcp_hdr);
+
+uint8_t ltsm_proc_ipv4tcppkt(ltsm_stream_handle s_ltsm, const struct mesa_ip4_hdr *iphdr);
+
+void ltsm_destroy_stream_handle(ltsm_stream_handle s_ltsm);
+#endif
\ No newline at end of file diff --git a/support/ltsm/test_ltsm.c b/support/ltsm/test_ltsm.c new file mode 100644 index 0000000..01935a9 --- /dev/null +++ b/support/ltsm/test_ltsm.c @@ -0,0 +1,59 @@ +
+#include <stdlib.h>
+#include <stdio.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <assert.h>
+#include <time.h>
+#include <arpa/inet.h>
+
+#include "stream.h"
+#include "ltsm.h"
+
+
+
+
+char LTSM_TCPALL_ENTRY(struct streaminfo *pstream, void **pme, int thread_seq,void *apacket)
+{
+ void *ltsm_handle;
+ struct ltsm_result tcpstate;
+ const struct ltsm_tcphdr *tcp_hdr;
+ const struct ip *iphdr = (const struct ip *)apacket;
+
+ if(apacket != NULL){
+ tcp_hdr = (const struct ltsm_tcphdr *)((char *)iphdr + iphdr->ip_hl*4);
+ }
+
+ if(OP_STATE_PENDING == pstream->pktstate){
+ tcpstate = ltsm_get_current_state(NULL, tcp_hdr->th_flags, pstream->curdir);
+ if(LTSM_START == tcpstate.lstate ){
+ ltsm_handle = ltsm_create_handle();
+ *pme = ltsm_handle;
+ }else{
+ return APP_STATE_DROPME;
+ }
+ }else{
+ ltsm_handle = *pme;
+ if(OP_STATE_CLOSE == pstream->pktstate){
+ ltsm_destroy_handle(ltsm_handle);
+ return APP_STATE_DROPME;
+ }
+ }
+
+
+ tcpstate = ltsm_get_current_state(ltsm_handle, tcp_hdr->th_flags, pstream->curdir - 1);
+
+ printf("stream: %s, flags:0x%x, fstate: %s,\t lstate:%s\n", printaddr(&pstream->addr, thread_seq), tcp_hdr->th_flags, ltsm_fstate_ntop(tcpstate.fstate), ltsm_lstate_ntop(tcpstate.lstate));
+
+ return APP_STATE_GIVEME;
+}
+
+
+int LTSM_INIT(void)
+{
+ return 1;
+}
+
+
+
|
