1 /* 2 * tcp.h 3 * 4 * Transmission Control Protocol (RFC 793). 5 * 6 * Copyright (c) 2000 Dug Song <dugsong@monkey.org> 7 * 8 * $Id$ 9 */ 10 11 #ifndef DNET_TCP_H 12 #define DNET_TCP_H 13 14 #define TCP_HDR_LEN 20 /* base TCP header length */ 15 #define TCP_OPT_LEN 2 /* base TCP option length */ 16 #define TCP_OPT_LEN_MAX 40 17 #define TCP_HDR_LEN_MAX (TCP_HDR_LEN + TCP_OPT_LEN_MAX) 18 19 #ifndef __GNUC__ 20 # define __attribute__(x) 21 # pragma pack(1) 22 #endif 23 24 /* 25 * TCP header, without options 26 */ 27 struct tcp_hdr { 28 uint16_t th_sport; /* source port */ 29 uint16_t th_dport; /* destination port */ 30 uint32_t th_seq; /* sequence number */ 31 uint32_t th_ack; /* acknowledgment number */ 32 #if DNET_BYTESEX == DNET_BIG_ENDIAN 33 uint8_t th_off:4, /* data offset */ 34 th_x2:4; /* (unused) */ 35 #elif DNET_BYTESEX == DNET_LIL_ENDIAN 36 uint8_t th_x2:4, 37 th_off:4; 38 #else 39 # error "need to include <dnet.h>" 40 #endif 41 uint8_t th_flags; /* control flags */ 42 uint16_t th_win; /* window */ 43 uint16_t th_sum; /* checksum */ 44 uint16_t th_urp; /* urgent pointer */ 45 }; 46 47 /* 48 * TCP control flags (th_flags) 49 */ 50 #define TH_FIN 0x01 /* end of data */ 51 #define TH_SYN 0x02 /* synchronize sequence numbers */ 52 #define TH_RST 0x04 /* reset connection */ 53 #define TH_PUSH 0x08 /* push */ 54 #define TH_ACK 0x10 /* acknowledgment number set */ 55 #define TH_URG 0x20 /* urgent pointer set */ 56 #define TH_ECE 0x40 /* ECN echo, RFC 3168 */ 57 #define TH_CWR 0x80 /* congestion window reduced */ 58 59 #define TCP_PORT_MAX 65535 /* maximum port */ 60 #define TCP_WIN_MAX 65535 /* maximum (unscaled) window */ 61 62 /* 63 * Sequence number comparison macros 64 */ 65 #define TCP_SEQ_LT(a,b) ((int)((a)-(b)) < 0) 66 #define TCP_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) 67 #define TCP_SEQ_GT(a,b) ((int)((a)-(b)) > 0) 68 #define TCP_SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0) 69 70 /* 71 * TCP FSM states 72 */ 73 #define TCP_STATE_CLOSED 0 /* closed */ 74 #define TCP_STATE_LISTEN 1 /* listening from connection */ 75 #define TCP_STATE_SYN_SENT 2 /* active, have sent SYN */ 76 #define TCP_STATE_SYN_RECEIVED 3 /* have sent and received SYN */ 77 78 #define TCP_STATE_ESTABLISHED 4 /* established */ 79 #define TCP_STATE_CLOSE_WAIT 5 /* rcvd FIN, waiting for close */ 80 81 #define TCP_STATE_FIN_WAIT_1 6 /* have closed, sent FIN */ 82 #define TCP_STATE_CLOSING 7 /* closed xchd FIN, await FIN-ACK */ 83 #define TCP_STATE_LAST_ACK 8 /* had FIN and close, await FIN-ACK */ 84 85 #define TCP_STATE_FIN_WAIT_2 9 /* have closed, FIN is acked */ 86 #define TCP_STATE_TIME_WAIT 10 /* in 2*MSL quiet wait after close */ 87 #define TCP_STATE_MAX 11 88 89 /* 90 * Options (opt_type) - http://www.iana.org/assignments/tcp-parameters 91 */ 92 #define TCP_OPT_EOL 0 /* end of option list */ 93 #define TCP_OPT_NOP 1 /* no operation */ 94 #define TCP_OPT_MSS 2 /* maximum segment size */ 95 #define TCP_OPT_WSCALE 3 /* window scale factor, RFC 1072 */ 96 #define TCP_OPT_SACKOK 4 /* SACK permitted, RFC 2018 */ 97 #define TCP_OPT_SACK 5 /* SACK, RFC 2018 */ 98 #define TCP_OPT_ECHO 6 /* echo (obsolete), RFC 1072 */ 99 #define TCP_OPT_ECHOREPLY 7 /* echo reply (obsolete), RFC 1072 */ 100 #define TCP_OPT_TIMESTAMP 8 /* timestamp, RFC 1323 */ 101 #define TCP_OPT_POCONN 9 /* partial order conn, RFC 1693 */ 102 #define TCP_OPT_POSVC 10 /* partial order service, RFC 1693 */ 103 #define TCP_OPT_CC 11 /* connection count, RFC 1644 */ 104 #define TCP_OPT_CCNEW 12 /* CC.NEW, RFC 1644 */ 105 #define TCP_OPT_CCECHO 13 /* CC.ECHO, RFC 1644 */ 106 #define TCP_OPT_ALTSUM 14 /* alt checksum request, RFC 1146 */ 107 #define TCP_OPT_ALTSUMDATA 15 /* alt checksum data, RFC 1146 */ 108 #define TCP_OPT_SKEETER 16 /* Skeeter */ 109 #define TCP_OPT_BUBBA 17 /* Bubba */ 110 #define TCP_OPT_TRAILSUM 18 /* trailer checksum */ 111 #define TCP_OPT_MD5 19 /* MD5 signature, RFC 2385 */ 112 #define TCP_OPT_SCPS 20 /* SCPS capabilities */ 113 #define TCP_OPT_SNACK 21 /* selective negative acks */ 114 #define TCP_OPT_REC 22 /* record boundaries */ 115 #define TCP_OPT_CORRUPT 23 /* corruption experienced */ 116 #define TCP_OPT_SNAP 24 /* SNAP */ 117 #define TCP_OPT_TCPCOMP 26 /* TCP compression filter */ 118 #define TCP_OPT_MAX 27 119 120 #define TCP_OPT_TYPEONLY(type) \ 121 ((type) == TCP_OPT_EOL || (type) == TCP_OPT_NOP) 122 123 /* 124 * TCP option (following TCP header) 125 */ 126 struct tcp_opt { 127 uint8_t opt_type; /* option type */ 128 uint8_t opt_len; /* option length >= TCP_OPT_LEN */ 129 union tcp_opt_data { 130 uint16_t mss; /* TCP_OPT_MSS */ 131 uint8_t wscale; /* TCP_OPT_WSCALE */ 132 uint16_t sack[19]; /* TCP_OPT_SACK */ 133 uint32_t echo; /* TCP_OPT_ECHO{REPLY} */ 134 uint32_t timestamp[2]; /* TCP_OPT_TIMESTAMP */ 135 uint32_t cc; /* TCP_OPT_CC{NEW,ECHO} */ 136 uint8_t cksum; /* TCP_OPT_ALTSUM */ 137 uint8_t md5[16]; /* TCP_OPT_MD5 */ 138 uint8_t data8[TCP_OPT_LEN_MAX - TCP_OPT_LEN]; 139 } opt_data; 140 } __attribute__((__packed__)); 141 142 #ifndef __GNUC__ 143 # pragma pack() 144 #endif 145 146 #define tcp_pack_hdr(hdr, sport, dport, seq, ack, flags, win, urp) do { \ 147 struct tcp_hdr *tcp_pack_p = (struct tcp_hdr *)(hdr); \ 148 tcp_pack_p->th_sport = htons(sport); \ 149 tcp_pack_p->th_dport = htons(dport); \ 150 tcp_pack_p->th_seq = htonl(seq); \ 151 tcp_pack_p->th_ack = htonl(ack); \ 152 tcp_pack_p->th_x2 = 0; tcp_pack_p->th_off = 5; \ 153 tcp_pack_p->th_flags = flags; \ 154 tcp_pack_p->th_win = htons(win); \ 155 tcp_pack_p->th_urp = htons(urp); \ 156 } while (0) 157 158 #endif /* DNET_TCP_H */ 159