12632SN/A/* 22632SN/A * tcp.h 32632SN/A * 42632SN/A * Transmission Control Protocol (RFC 793). 52632SN/A * 62632SN/A * Copyright (c) 2000 Dug Song <dugsong@monkey.org> 72632SN/A * 82632SN/A * $Id: tcp.h,v 1.17 2004/02/23 10:02:11 dugsong Exp $ 92632SN/A */ 102632SN/A 112632SN/A#ifndef DNET_TCP_H 122632SN/A#define DNET_TCP_H 132632SN/A 142632SN/A#define TCP_HDR_LEN 20 /* base TCP header length */ 152632SN/A#define TCP_OPT_LEN 2 /* base TCP option length */ 162632SN/A#define TCP_OPT_LEN_MAX 40 172632SN/A#define TCP_HDR_LEN_MAX (TCP_HDR_LEN + TCP_OPT_LEN_MAX) 182632SN/A 192632SN/A#ifndef __GNUC__ 202632SN/A# define __attribute__(x) 212632SN/A# pragma pack(1) 222632SN/A#endif 232632SN/A 242632SN/A/* 252632SN/A * TCP header, without options 262632SN/A */ 272632SN/Astruct tcp_hdr { 282632SN/A uint16_t th_sport; /* source port */ 292632SN/A uint16_t th_dport; /* destination port */ 302632SN/A uint32_t th_seq; /* sequence number */ 312632SN/A uint32_t th_ack; /* acknowledgment number */ 322632SN/A#if DNET_BYTESEX == DNET_BIG_ENDIAN 332632SN/A uint8_t th_off:4, /* data offset */ 342632SN/A th_x2:4; /* (unused) */ 352632SN/A#elif DNET_BYTESEX == DNET_LIL_ENDIAN 362632SN/A uint8_t th_x2:4, 372632SN/A th_off:4; 382632SN/A#else 392632SN/A# error "need to include <dnet.h>" 402632SN/A#endif 412632SN/A uint8_t th_flags; /* control flags */ 422632SN/A uint16_t th_win; /* window */ 432632SN/A uint16_t th_sum; /* checksum */ 442632SN/A uint16_t th_urp; /* urgent pointer */ 452632SN/A}; 462632SN/A 472632SN/A/* 482632SN/A * TCP control flags (th_flags) 492632SN/A */ 502632SN/A#define TH_FIN 0x01 /* end of data */ 512632SN/A#define TH_SYN 0x02 /* synchronize sequence numbers */ 522632SN/A#define TH_RST 0x04 /* reset connection */ 532632SN/A#define TH_PUSH 0x08 /* push */ 542632SN/A#define TH_ACK 0x10 /* acknowledgment number set */ 552632SN/A#define TH_URG 0x20 /* urgent pointer set */ 562632SN/A#define TH_ECE 0x40 /* ECN echo, RFC 3168 */ 572632SN/A#define TH_CWR 0x80 /* congestion window reduced */ 582632SN/A 592632SN/A#define TCP_PORT_MAX 65535 /* maximum port */ 602632SN/A#define TCP_WIN_MAX 65535 /* maximum (unscaled) window */ 612632SN/A 622632SN/A/* 632632SN/A * Sequence number comparison macros 642632SN/A */ 652632SN/A#define TCP_SEQ_LT(a,b) ((int)((a)-(b)) < 0) 662632SN/A#define TCP_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) 672632SN/A#define TCP_SEQ_GT(a,b) ((int)((a)-(b)) > 0) 682632SN/A#define TCP_SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0) 692632SN/A 702632SN/A/* 712632SN/A * TCP FSM states 722632SN/A */ 732632SN/A#define TCP_STATE_CLOSED 0 /* closed */ 742632SN/A#define TCP_STATE_LISTEN 1 /* listening from connection */ 752632SN/A#define TCP_STATE_SYN_SENT 2 /* active, have sent SYN */ 762632SN/A#define TCP_STATE_SYN_RECEIVED 3 /* have sent and received SYN */ 772632SN/A 782632SN/A#define TCP_STATE_ESTABLISHED 4 /* established */ 792632SN/A#define TCP_STATE_CLOSE_WAIT 5 /* rcvd FIN, waiting for close */ 802632SN/A 812632SN/A#define TCP_STATE_FIN_WAIT_1 6 /* have closed, sent FIN */ 822632SN/A#define TCP_STATE_CLOSING 7 /* closed xchd FIN, await FIN-ACK */ 832632SN/A#define TCP_STATE_LAST_ACK 8 /* had FIN and close, await FIN-ACK */ 842632SN/A 852632SN/A#define TCP_STATE_FIN_WAIT_2 9 /* have closed, FIN is acked */ 862632SN/A#define TCP_STATE_TIME_WAIT 10 /* in 2*MSL quiet wait after close */ 872632SN/A#define TCP_STATE_MAX 11 882632SN/A 892632SN/A/* 902632SN/A * Options (opt_type) - http://www.iana.org/assignments/tcp-parameters 912632SN/A */ 922632SN/A#define TCP_OPT_EOL 0 /* end of option list */ 932632SN/A#define TCP_OPT_NOP 1 /* no operation */ 942632SN/A#define TCP_OPT_MSS 2 /* maximum segment size */ 952632SN/A#define TCP_OPT_WSCALE 3 /* window scale factor, RFC 1072 */ 962632SN/A#define TCP_OPT_SACKOK 4 /* SACK permitted, RFC 2018 */ 972632SN/A#define TCP_OPT_SACK 5 /* SACK, RFC 2018 */ 982632SN/A#define TCP_OPT_ECHO 6 /* echo (obsolete), RFC 1072 */ 992632SN/A#define TCP_OPT_ECHOREPLY 7 /* echo reply (obsolete), RFC 1072 */ 1002632SN/A#define TCP_OPT_TIMESTAMP 8 /* timestamp, RFC 1323 */ 1012632SN/A#define TCP_OPT_POCONN 9 /* partial order conn, RFC 1693 */ 1022632SN/A#define TCP_OPT_POSVC 10 /* partial order service, RFC 1693 */ 1032632SN/A#define TCP_OPT_CC 11 /* connection count, RFC 1644 */ 1042632SN/A#define TCP_OPT_CCNEW 12 /* CC.NEW, RFC 1644 */ 1052632SN/A#define TCP_OPT_CCECHO 13 /* CC.ECHO, RFC 1644 */ 1062632SN/A#define TCP_OPT_ALTSUM 14 /* alt checksum request, RFC 1146 */ 1072632SN/A#define TCP_OPT_ALTSUMDATA 15 /* alt checksum data, RFC 1146 */ 1082632SN/A#define TCP_OPT_SKEETER 16 /* Skeeter */ 1092632SN/A#define TCP_OPT_BUBBA 17 /* Bubba */ 1102632SN/A#define TCP_OPT_TRAILSUM 18 /* trailer checksum */ 1112632SN/A#define TCP_OPT_MD5 19 /* MD5 signature, RFC 2385 */ 1122632SN/A#define TCP_OPT_SCPS 20 /* SCPS capabilities */ 1132632SN/A#define TCP_OPT_SNACK 21 /* selective negative acks */ 1142632SN/A#define TCP_OPT_REC 22 /* record boundaries */ 1152632SN/A#define TCP_OPT_CORRUPT 23 /* corruption experienced */ 1162632SN/A#define TCP_OPT_SNAP 24 /* SNAP */ 1172632SN/A#define TCP_OPT_TCPCOMP 26 /* TCP compression filter */ 1182632SN/A#define TCP_OPT_MAX 27 1192632SN/A 1202632SN/A#define TCP_OPT_TYPEONLY(type) \ 1212632SN/A ((type) == TCP_OPT_EOL || (type) == TCP_OPT_NOP) 1222632SN/A 1232632SN/A/* 1242632SN/A * TCP option (following TCP header) 1252632SN/A */ 1262632SN/Astruct tcp_opt { 1272632SN/A uint8_t opt_type; /* option type */ 1282632SN/A uint8_t opt_len; /* option length >= TCP_OPT_LEN */ 1292632SN/A union tcp_opt_data { 1302632SN/A uint16_t mss; /* TCP_OPT_MSS */ 1312632SN/A uint8_t wscale; /* TCP_OPT_WSCALE */ 1322632SN/A uint16_t sack[19]; /* TCP_OPT_SACK */ 1332632SN/A uint32_t echo; /* TCP_OPT_ECHO{REPLY} */ 1342632SN/A uint32_t timestamp[2]; /* TCP_OPT_TIMESTAMP */ 1352632SN/A uint32_t cc; /* TCP_OPT_CC{NEW,ECHO} */ 1362632SN/A uint8_t cksum; /* TCP_OPT_ALTSUM */ 1372632SN/A uint8_t md5[16]; /* TCP_OPT_MD5 */ 1382632SN/A uint8_t data8[TCP_OPT_LEN_MAX - TCP_OPT_LEN]; 1392632SN/A } opt_data; 1402632SN/A} __attribute__((__packed__)); 1412632SN/A 1422632SN/A#ifndef __GNUC__ 1432632SN/A# pragma pack() 1442632SN/A#endif 1452632SN/A 1462632SN/A#define tcp_pack_hdr(hdr, sport, dport, seq, ack, flags, win, urp) do { \ 1472632SN/A struct tcp_hdr *tcp_pack_p = (struct tcp_hdr *)(hdr); \ 1482632SN/A tcp_pack_p->th_sport = htons(sport); \ 1492632SN/A tcp_pack_p->th_dport = htons(dport); \ 1502632SN/A tcp_pack_p->th_seq = htonl(seq); \ 1512632SN/A tcp_pack_p->th_ack = htonl(ack); \ 1522632SN/A tcp_pack_p->th_x2 = 0; tcp_pack_p->th_off = 5; \ 1532632SN/A tcp_pack_p->th_flags = flags; \ 1542632SN/A tcp_pack_p->th_win = htons(win); \ 1552632SN/A tcp_pack_p->th_urp = htons(urp); \ 1562632SN/A} while (0) 1572632SN/A 1582632SN/A#endif /* DNET_TCP_H */ 159