Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Aug 1999 21:48:52 +0000 (GMT)
From:      FreeBSD mailing lists <lists@idle.za.org>
To:        freebsd-hackers@freebsd.org
Subject:   Raw Packet code containing security bits
Message-ID:  <Pine.BSF.4.10.9908162145130.88346-100000@loves.to.idle.za.org>

next in thread | raw e-mail | index | archive | help
I wonder if anyone here could perhaps of be assistance, Im currently
playing with implementing certain things in trusted bsd to do with ip
security classes and how the system responds to security bits, and
implementing certain things the stack etc.  However my first piece of test
code playing with raw packets to test how things respond to packets with
the security bit set, doesnt seem to want to work.  This code compiles
fine, however when I try and run it it says invalid argument when it tries
to send the packet.  If anyone could give me any insight as to why this
code doesnt run properly, it would be much appreciated, and would
certainly help me in my efforts to continue expanding trusted bsd.

Ive included the code below..

Thanks

Andrew

--- Code starts here ---

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <netinet/udp.h>

#define IPVERSION 4  		/* Define the IP Version (always 4, until we go ipv6) */
#define DEFAULT_TTL 60 		/* Define the default Time to Live as 60 */
#define DESTPORT 1700

	struct pseudohdr {
		struct in_addr source_address;
		struct in_addr dest_address;
		u_char place_holder;
		u_char proto;
		u_short length;
	} pseudohdr;
	
u_short in_chksum(u_short *addr, int len) {
	register int nleft = len;
	register u_short *w = addr;
	register int sum = 0;
	u_short answer = 0;

	while (nleft > 1) {
		sum += *w++;
		nleft -= 2;
		}
	
	if (nleft == 1) {
		*(u_char *)(&answer) = *(u_char *)w;
		sum += answer;
		}

	sum = (sum >> 16) + (sum & 0xffff);
	sum += (sum >> 16);
	answer = ~sum;
	return(answer);
};

u_short trans_check(u_char proto, char *packet, int length, 
			struct in_addr source_address, struct in_addr dest_address)
{
	char *pseudo_packet;
	u_short answer;

	pseudohdr.proto = proto;
	pseudohdr.length = htons(length);
	pseudohdr.place_holder = 0;
	pseudohdr.source_address = source_address;
	pseudohdr.dest_address = dest_address;

	if((pseudo_packet = malloc(sizeof(struct pseudohdr) + length)) == NULL) {
		perror("malloc");
		exit(-1);
		}
	
	memcpy(pseudo_packet, &pseudohdr, sizeof(pseudohdr));
	memcpy((pseudo_packet + sizeof(pseudo_packet)), packet, length);

	answer = (u_short)in_chksum((u_short *)pseudo_packet, (length + sizeof(pseudohdr)));
	free(pseudo_packet);
	return answer;
};
void ipgenerate(char *packet, u_char protocol, struct in_addr saddr, 
		struct in_addr daddr, u_short length)
{
	struct ip *iphead;
	iphead = (struct ip *)packet;
	memset((char *)iphead, '\0', sizeof(struct ip));
	iphead->ip_hl = 5;			/* Define the ip header length as 6, this is standard packet 
						+ security class option, counted in 32 bit words */
	iphead->ip_v = IPVERSION;		/* Set the ip version to 4 as its ipv4 not ipv6 */
	iphead->ip_len = htons(length); 	/* Set the packet length in network byte order */
	iphead->ip_id = htons(getpid());	/* Set the packet id to the process id */
	iphead->ip_ttl = DEFAULT_TTL;		/* Set the time to live to the default defined (60 seconds) */
	iphead->ip_p = protocol;		/* Set the protocol (tcp/udp/icmp) */
	iphead->ip_src = saddr;			/* Set the source address */
	iphead->ip_dst = daddr;			/* Set the destination address */
	iphead->ip_sum = (u_short)in_chksum((u_short *)iphead, 
			sizeof(struct ip));	/* Set the checksum */
	printf("sizeof: %d\n",sizeof(struct ip));
};

void addsecure(char *packet)
{
	char *pack;
	pack = (char *)packet+sizeof(struct ip);
	pack[0] = 0x82;		/* We want a security option that is copied on all fragmentation */
	pack[1] = 0xB;	
	pack[2] = 0x6B;		/* We class this packet as top secret */
	pack[3] = 0xC5;
	pack[4] = 0;		/* Packet is non compartmentalized */
	pack[5] = 0;
	pack[6] = 0;		/* More security crap from DIAM 65-19 */
	pack[7] = 0;
	pack[8] = 0;		/* Still more crap leave this 0 */
	pack[9] = 0;
	pack[10] = 0;
	pack[11] = 0;		/* Terminate the packet options */

	/* Packet data now starts at (char *)packet+sizeof(struct ip)+12 */
};

void addudphead(char *packet, u_short sport, u_short dport, u_short length)
{
	struct udphdr *udphead;
	udphead = (struct udphdr *)packet;
	udphead->uh_sport = 0;
	udphead->uh_dport = DESTPORT;
	udphead->uh_ulen = length;
};
		
int main(int argc, char *argv[]) 
{ 
	char *packetdata;				/* Data going into our UDP Packet */
 	struct in_addr saddr, daddr;			/* Source and Destination address structs */
	u_short sport, dport;				/* Source and Destination ports */
	struct sockaddr_in rawsocket;			/* The socket we will be talking over */
	int sockd, on = 1;				/* Socket stuff */
	struct udphdr *udpheader;			/* UDP header used for generating checksums */		
	u_short datalength = strlen("Test UDP Packet") +5;
	u_short packetlength = sizeof(struct ip) + sizeof(struct udphdr) + 12 + datalength;
	u_char entirepacket[packetlength];
	u_char *tempstr;

	if (argc < 5) {
		printf("\nRaw UDP packet + security bit transmitter\n(c) 1999 Andrew Alston\n");
		printf("Usage: %s source_port source_address destination_port destination_address\n"
			,argv[0]);
		exit(-1);
		};

	if((packetdata = malloc(datalength)) == NULL) {
		perror("malloc");
		exit(-1);
		};					/* Allocate some memory for the packet data */

	memset(packetdata, '\0', datalength);	/* Fill the string with 0's */
	snprintf(packetdata, strlen("Test UDP Packet")+5, "Test UDP Packet\n");

	memset(entirepacket, '\0', packetlength);	/* 0 out the entire packet */

	sport = (u_short)atoi(argv[1]);			/* Source port from argument 1 */
	saddr.s_addr = htonl(inet_addr(argv[2]));		/* Source address from argument 2 */
	dport = (u_short)atoi(argv[3]);			/* Destination port from argument 3 */
	daddr.s_addr = htonl(inet_addr(argv[4]));		/* Destination address from argument 4 */

	if((sockd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 ) {
		perror("Socket");
		exit(-1);
		};					/* Set up the socket and die on faliure */

	if(setsockopt(sockd, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) {
		perror("setsockopt");
		exit(-1);
		};					/* Request permission to include own ip header */

	ipgenerate(entirepacket, IPPROTO_UDP, saddr, daddr, packetlength); 
	addsecure(entirepacket);
	udpheader = (struct udphdr *)(entirepacket + sizeof(struct ip) + 12);
	addudphead((char *)udpheader, sport, dport, sizeof(struct udphdr) + datalength);
	udpheader->uh_sum = trans_check(IPPROTO_UDP, (char *)udpheader,
					(datalength + sizeof(struct udphdr)),
					saddr, daddr);	
	
	tempstr = entirepacket + sizeof(struct ip) + sizeof(struct udphdr) + 12;
	strncpy(tempstr, packetdata, strlen(packetdata));
	memset(&rawsocket, '\0', sizeof(struct sockaddr_in));
	rawsocket.sin_family = AF_INET;
	rawsocket.sin_port = htons(dport);
	rawsocket.sin_addr = daddr;

	printf("Length of packet: %d\n",sizeof(entirepacket));
	printf("Packetlength: %d\n", packetlength);
	if(sendto(sockd,&entirepacket,packetlength,0x0,(struct sockaddr *)&rawsocket,
		sizeof(rawsocket)) != packetlength) {
			perror("send to");
			exit(-1);
			}; 

	return(0);
};
	



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.10.9908162145130.88346-100000>