Subject: Problems with writing raw sockets.
To: None <netbsd-help@netbsd.org>
From: Kholmanskikh Stanislav <kholmanskikh@i4x4.ru>
List: netbsd-help
Date: 12/04/2004 15:01:04
Hello from Russia!
I am a Russian student, trying to write a program which can send raw ip packets. I am doing this just for experience.
Here is the text of my program:
#include <iostream.h>
#include <unistd.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <strings.h>
#include <errno.h>

int main()
{
	//char *buffer = new char[30];
	char buffer[30];
	bzero(buffer, 30);
	
	int nSocket;
	
	struct sockaddr_in serverAddress;
	struct in_addr ip_src, ip_dest;

	inet_aton("127.0.0.1", (struct in_addr *)&(ip_src));
	inet_aton("127.0.0.1", (struct in_addr *)&(ip_dest));

	bzero(&serverAddress, sizeof(struct sockaddr_in));
	serverAddress.sin_family = AF_INET;
	serverAddress.sin_addr = ip_dest;
	serverAddress.sin_port = htons(347); //Is it needed?

	
	struct ip *iphdr = (struct ip *)buffer;
	iphdr->ip_hl = 5;
	iphdr->ip_v = 4;
	iphdr->ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr));
	iphdr->ip_id = htons(getpid());
	iphdr->ip_ttl = 60;
	iphdr->ip_off = 0;
	iphdr->ip_p = IPPROTO_UDP;
	iphdr->ip_src = ip_src;
	iphdr->ip_dst = ip_dest;
	iphdr->ip_sum = 0; //I hope that the kernel should modifies this 

	struct udphdr *udp = (struct udphdr *)(buffer + sizeof(struct ip));
	udp->uh_sport = htons(227);
	udp->uh_dport = htons(347);
	udp->uh_ulen = htons(sizeof(struct udphdr));
	udp->uh_sum = 0;

	if ((nSocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) 
		{
			cout << "Socket error" << errno << '\n';
			return 1;
		}
	int nSwither = 1;
	if (setsockopt(nSocket, IPPROTO_IP, IP_HDRINCL, &nSwither, sizeof(nSwither)) < 0)
		{
			cout << "Options' error " << errno << '\n';
			return 1;
		}
	
	if (sendto(nSocket, buffer, sizeof(struct ip) + sizeof(struct udphdr), 0, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) <0)
		{
			cout << "Sending error " << errno << '\n';
			return 1;
		}
}

After compiling this you can see that my program returns "sending error 22". I can't understand why it does so.
Maybe I need to add check sum to the header(iphdr->ip_sum). I really don't know.
The program are compiled and runned by root.
My OS is NetBSD 1.6.2_Stable.