Raw Socket - Recv/Send Problem

Hello,
Iv recently been researching raw sockets, and have tried to create a program which simply sends a raw packet, and then receives it (from 123.4.5.6:55000 to 127.0.0.1:55000).
Here is my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <sys/types.h>
#define __FAVOR_BSD
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <iostream>
#include <string.h>
#include <cstdlib>
char data[1024] = "";

using namespace std;

unsigned short csum(unsigned short *buf,int nwords)
{
	//this function returns the checksum of a buffer
	unsigned long sum;
	for (sum = 0; nwords > 0; nwords--){sum += *buf++;}
	sum = (sum >> 16) + (sum & 0xffff);
	sum += (sum >> 16);
	return (unsigned short) (~sum);
}

int createRaw(int protocol_to_sniff)
{
	int raw_fd = socket(AF_INET, SOCK_RAW, protocol_to_sniff);
	if (raw_fd < 0)
	{
		cout << "ERROR creating raw socket\n";
		exit(1);
	}else{
		cout << "Raw Socket Created!		:-D\n";
		return raw_fd;
	}
}
int bindRaw(int socketToBind,sockaddr_in* sin)
{
	int err = bind(socketToBind,(struct sockaddr *)sin,sizeof(*sin));
	if (err < 0)
	{
		cout << "ERROR binding socket.\n";
		exit(1);
	}else{
		cout << "Bound socket!			:-D\n";
		return 0;
	}
}

int main(int argc,char* argv[])
{
	//create raw socket for binding
	int bindSocket = createRaw(6);
	
	//create structures
	struct sockaddr_in sin;
	unsigned char packetBuf[4096];
	
	//specify port to bind to
	bzero((char *)&sin,sizeof(sin));
	sin.sin_port = htons(55000);
	
	//bind socket
	bindRaw(bindSocket,&sin);
	
	//inform os of recieving raw ip packet
	{
		int tmp = 1;
		setsockopt(bindSocket, 0, IP_HDRINCL,&tmp,sizeof(tmp));
	}
	
	//re-use socket structure
	//Details about where this custom packet is going:
	bzero((char *)& sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(55000);	//port to send packet to
	sin.sin_addr.s_addr = inet_addr("127.0.0.1");	//IP to send packet to
	
	unsigned short buffer_size = sizeof(struct ip) + sizeof(struct tcphdr);//+ sizeof(data);
	cout << "Buffer size: " << buffer_size << endl;
	
	struct ip *IPheader = (struct ip *) packetBuf;
	struct tcphdr *TCPheader = (struct tcphdr *) (packetBuf + sizeof (struct ip));
	
	//Fill out IP Header information:
	IPheader->ip_hl = 5;
	IPheader->ip_v = 4;		//IPv4
	IPheader->ip_tos = 0;		//type of service
	IPheader->ip_len = htons(buffer_size);	//length
	IPheader->ip_id = htonl(54321);
	IPheader->ip_off = 0;
	IPheader->ip_ttl = 255;	//max routers to pass through
	IPheader->ip_p = 6;		//tcp
	IPheader->ip_sum = 0;	//Set to 0 before calulating later
	IPheader->ip_src.s_addr = inet_addr("123.4.5.6");	//source IP address
	IPheader->ip_dst.s_addr = inet_addr("127.0.0.1");	//destination IP address
	
	//Fill out TCP Header information:
	TCPheader->th_sport = htons(55000);	//source port
	TCPheader->th_dport = htons(55000);			//destination port
	TCPheader->th_seq = random();
	TCPheader->th_ack = 0;	//Only 0 on initial SYN 
	TCPheader->th_off = 0;
	TCPheader->th_flags = TH_SYN;	//SYN flag set
	TCPheader->th_win = htonl(65535);	//used for segmentation
	TCPheader->th_sum = 0;				//Kernel fill this out
	TCPheader->th_urp = 0;
	
	//Now fill out the checksum for the IPheader
	IPheader->ip_sum = csum((unsigned short *) packetBuf, IPheader->ip_len >> 1);
	cout << "IP Checksum: " << IPheader->ip_sum << endl;
	//create raw socket for sending ip packet
	int sendRaw = createRaw(6);
	if (sendRaw < 0)
	{
		cout << "ERROR creating raw socket for sending.\n";
		exit(1);
	}else{
		cout << "Raw socket created for sending!	:-D\n";
	}
	int sendErr = sendto(sendRaw,packetBuf,
		sizeof(packetBuf),0,(struct sockaddr *)&sin,sizeof(sin));
	
	if (sendErr < sizeof(packetBuf))
	{
		cout << sendErr << " out of " << sizeof(packetBuf) << " were sent.\n";
		exit(1);
	}else{
		cout << "<" << sendErr << "> Sent message!!!		:-D\n";
	}
	
	cout << "Sleeping for 2 seconds";
	sleep(1);
	cout << ".";
	sleep(1);
	cout << ".\n";
	char recvPacket[4096] = "";
	int newData = recv(bindSocket,recvPacket,sizeof(recvPacket),0);
	if (newData <=0)
	{
		cout << newData << " returned by recv! :(\n";
		exit(1);
	}else{
		cout << "<" << newData << "> RECIEVE SUCCESSFULL!!	:-D\n";
	}
	
	return 0;	
}


The problem occurs in my output:
1
2
3
4
5
6
7
8
9
10
Raw Socket Created!		:-D
Bound socket!			:-D
Buffer size: 40
IP Checksum: 56557
Raw Socket Created!		:-D
Raw socket created for sending!	:-D
<4096> Sent message!!!		:-D
Sleeping for 2 seconds..
<4096> RECIEVE SUCCESSFULL!!	:-D
E


The last line is 'E', What does this mean? Shouldn't I get a whole lot of code describing the packet that just arrived? (And then I should be able to pass that info into a TCP and IP header?)
So in simple terms: Why is my code displaying 'E'?

All help is appreciated :)

PS. Running Fedora 10
Topic archived. No new replies allowed.