11#include <stdio.h>
22#include <stdlib.h>
33#include <unistd.h>
4+ #include <limits.h>
5+ #include <string.h>
6+ #include <time.h>
47
58#include <netdb.h>
69#include <sys/socket.h>
912#include <netinet/in.h>
1013#include <netinet/tcp.h>
1114
15+ #define D_PORT 80
16+
17+ struct pseudohdr {
18+ unsigned int src ;
19+ unsigned int dst ;
20+ unsigned char filler ; /* always null */
21+ unsigned char proto ; /* always 0x6 */
22+ unsigned short len ; /* len of real tcp hdr + data */
23+ };
24+
25+ unsigned short in_cksum (unsigned short * addr , size_t len );
26+
1227int main (int argc , char * argv [])
1328{
1429 struct addrinfo * hints , * answ , * tmp ;
30+ struct pseudohdr * psehdr ;
1531 struct tcphdr * send_frame ;
32+ void * final_frame ;
1633 int sock , ret ;
1734 ssize_t send_cnt ;
35+ unsigned short s_port , d_port = htons (D_PORT );
36+ unsigned int seq_num , ack_num ;
37+ time_t t ;
38+ srand ((unsigned int )time (& t ));
39+ s_port = htons ((rand () % USHRT_MAX - 2048 + 1 ) + 2048 );
40+ d_port = htons (D_PORT );
41+ seq_num = htonl (rand () % UINT_MAX + 1 );
42+ ack_num = 0 ;
1843 if (argc < 2 ) {
1944 fprintf (stderr , "need host name\n" );
2045 exit (1 );
@@ -27,6 +52,15 @@ int main(int argc, char *argv[])
2752 perror ("malloc" );
2853 exit (1 );
2954 }
55+ if ( (psehdr = calloc (1 , sizeof (struct pseudohdr ))) == NULL ) {
56+ perror ("malloc" );
57+ exit (1 );
58+ }
59+ if ( (final_frame = calloc (1 , sizeof (struct tcphdr ) +
60+ sizeof (struct pseudohdr ))) == NULL ) {
61+ perror ("malloc" );
62+ exit (1 );
63+ }
3064 hints -> ai_family = AF_INET ;
3165 hints -> ai_socktype = SOCK_RAW ;
3266 hints -> ai_protocol = IPPROTO_TCP ;
@@ -57,11 +91,73 @@ int main(int argc, char *argv[])
5791 exit(1);
5892 }
5993 */
94+ /* get my ip address */
95+ connect (sock , tmp -> ai_addr , tmp -> ai_addrlen );
96+ struct sockaddr_in addr ;
97+ socklen_t len = sizeof (struct sockaddr_in );
98+ getsockname (sock , (struct sockaddr * )& addr , & len );
99+ printf ("tcp from address: %s\n" , inet_ntoa (addr .sin_addr ));
100+
101+ /* filling pseudo hdr */
102+ psehdr -> src = addr .sin_addr .s_addr ;
103+ psehdr -> dst = ((struct sockaddr_in * )tmp -> ai_addr )-> sin_addr .s_addr ;
104+ psehdr -> filler = 0 ;
105+ psehdr -> proto = IPPROTO_TCP ;
106+ psehdr -> len = htons (20 );
107+
108+ /* prepare tcp hdr */
109+ send_frame -> source = s_port ;
110+ send_frame -> dest = d_port ;
111+ send_frame -> seq = seq_num ;
112+ send_frame -> ack_seq = ack_num ;
113+ send_frame -> doff = 5 ;
114+ send_frame -> fin = 0 ;
115+ send_frame -> syn = 1 ;
116+ send_frame -> rst = 0 ;
117+ send_frame -> psh = 0 ;
118+ send_frame -> ack = 0 ;
119+ send_frame -> urg = 0 ;
120+ send_frame -> window = 0xffff ;
121+ send_frame -> check = 0 ;
122+
123+ /* collect all frame (pseudo and real hdr) for computing checksum */
124+ memcpy (final_frame , psehdr , sizeof (struct pseudohdr ));
125+ memcpy (final_frame + sizeof (struct pseudohdr ), send_frame ,
126+ sizeof (struct tcphdr ));
127+ send_frame -> check = in_cksum (final_frame , sizeof (struct tcphdr )+
128+ sizeof (struct pseudohdr ));
129+
130+ /* send tcp hdr */
60131 send_cnt = sendto (sock , send_frame , sizeof (struct tcphdr ), 0 ,
61132 tmp -> ai_addr , tmp -> ai_addrlen );
62133 if (send_cnt == -1 ) {
63134 perror ("sendto" );
64135 exit (1 );
136+ } else {
137+ printf ("was send %d bytes\n" , send_cnt );
65138 }
66139 return 0 ;
67140}
141+
142+ unsigned short in_cksum (unsigned short * addr , size_t len )
143+ {
144+ int nleft = len ;
145+ int sum = 0 ;
146+ unsigned short * w = addr ;
147+ unsigned short answer = 0 ;
148+
149+ while (nleft > 1 ) {
150+ sum += * w ++ ;
151+ nleft -= 2 ;
152+ }
153+
154+ if (nleft == 1 ) {
155+ * (unsigned char * )(& answer ) += * (unsigned char * )w ;
156+ sum += answer ;
157+ }
158+
159+ sum = (sum >> 16 ) + (sum & 0xffff ); /* add hi 16 to low 16 */
160+ sum += (sum >> 16 ); /* add carry */
161+ answer = ~sum ; /* truncate to 16 bits */
162+ return (answer );
163+ }
0 commit comments