blob: 0089463843efe2d3771177c8e2865f95adb455ab [file] [log] [blame]
Steve Reinhardtba2eae52006-05-22 14:29:33 -04001/*
2 * tcp.h
3 *
4 * Transmission Control Protocol (RFC 793).
5 *
6 * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
7 *
8 * $Id: tcp.h,v 1.17 2004/02/23 10:02:11 dugsong Exp $
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 */
27struct 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 */
126struct 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 */