Skip to content

Commit 5891fa2

Browse files
author
Your Name
committed
send tcp
1 parent 856f3a4 commit 5891fa2

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

simple_examples/tcp.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
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>
@@ -9,12 +12,34 @@
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+
1227
int 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

Comments
 (0)