Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Mar 1997 18:53:18 -0500 (EST)
From:      Paco Hope <bah6f@cs.virginia.edu>
To:        hackers@freebsd.org
Cc:        Kira Attwood <ksa5w@cs.virginia.edu>
Subject:   Raw IP packets cause problems, reboots
Message-ID:  <199703252353.SAA17456@jazz.cs.Virginia.EDU>

next in thread | raw e-mail | index | archive | help

--ELM859333997-17366-0_
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNED MESSAGE-----

A colleague of mine is working on a proxy service for a firewall,
and she's doing it under FreeBSD.  We discovered a piece of sample
code for using raw IP packets.  This code supposedly sends an IP
datagram with arbitrary source and destination fields.

When run as root on a 2.1.5-RELEASE system, it generates an 
"Invalid argument" error.  This identical code, with no modifications,
compiles and executes "correctly" on Solaris (sparc) and Linux.  I'm
no expert on raw IP sockets, so I'm a bit stumped at why this doesn't
work on FreeBSD.

Even worse: If we run this program several times (e.g. 10 times over
the course of 5 minutes) the system we're running on reboots.  No
messages in /var/log/messages, and we don't have a console on it, so
we don't see anything happen.  The system is otherwise basically
unloaded, and we're the only processes running on it.  It's just a toy
firewall.

The sample code is attached to this mail.  If anyone has any
explanations or hints on why this fails, please let me know.  Please
CC me on this discussion.  I don't subscribe to hackers@freebsd.

Thanks,
Paco
- -- 
Paco Hope                                         Computer Systems Engineer
paco@cs.virginia.edu                         Department of Computer Science
http://www.cs.virginia.edu/~bah6f/                   University of Virginia

-----BEGIN PGP SIGNATURE-----
Version: 2.6.2

iQB1AwUBMzhlZqvTy70NhSypAQG/ygMAihNEIHAe3pU3SZp4ehv0O13hWD3d//IO
ATPoZ4/Sqjvk/xIho4fqbf4wBc7RzJ/SsOhzEP2dI6o1k4mHXEtx1LQhDaPXXQf6
pYlYeX7ArnqhTwxCbTXz7BbApkxVZA7W
=bxgc
-----END PGP SIGNATURE-----

--ELM859333997-17366-0_
Content-Type: text/plain; charset=ISO-8859-1
Content-Disposition: attachment; filename=rawtest.c
Content-Description: Sample raw IP socket code
Content-Transfer-Encoding: 7bit

/************************************************************************/
/* arnudp.c version 0.01 by Arny - cs6171@scitsc.wlv.ac.uk		*/
/* Sends a single udp datagram with the source/destination address/port	*/
/* set to whatever you want.  Unfortunately Linux 1.2 and SunOS 4.1	*/
/* don't seem to have the IP_HDRINCL option, so the source address will	*/
/* be set to the real address.  It does however work ok on SunOS 5.4.	*/
/* Should compile fine with just an ANSI compiler (such as gcc) under	*/
/* Linux and SunOS 4.1, but with SunOS 5.4 you have to specify extra	*/
/* libraries on the command line:					*/
/* 	/usr/ucb/cc -o arnudp arnudp001.c -lsocket -lnsl		*/
/* I'll state the obvious - this needs to be run as root!  Do not use	*/
/* this program unless you know what you are doing, as it is possible	*/
/* that you could confuse parts of your network	/ internet.		*/
/* (c) 1995 Arny - I accept no responsiblity for anything this does.	*/
/************************************************************************/
/* I used the source of traceroute as an example while writing this.	*/
/* Many thanks to Dan Egnor (egnor@ugcs.caltech.edu) and Rich Stevens	*/
/* for pointing me in the right direction.				*/
/************************************************************************/
 
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in_systm.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<netinet/udp.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<stdio.h>

main(int argc,char **argv)
{
    struct sockaddr sa;
    int fd;
    int x=1;
    int tmp;
    struct sockaddr_in *p;
    struct hostent *he;
    u_char gram[38]=
    {
	0x45,	0x00,	0x00,	0x26,
	0x12,	0x34,	0x00,	0x00,
	0xFF,	0x11,	0,	0,
	0,	0,	0,	0,
	0,	0,	0,	0,

	0,	0,	0,	0,
	0x00,	0x12,	0x00,	0x00,

	'1','2','3','4','5','6','7','8','9','0'
    };

    if(argc!=5)
    {
	fprintf(stderr,
		"usage: %s sourcename sourceport destinationname destinationport\n",
		*argv);
	exit(1);
    }

    he=gethostbyname(argv[1]);
    if( he == NULL )
    {
	fprintf(stderr,"can't resolve source hostname\n");
	exit(1);
    }
    bcopy(*(he->h_addr_list),(gram+12),4);

    he=gethostbyname(argv[3]);
    if( he == NULL)
    {
	fprintf(stderr,"can't resolve destination hostname\n");
	exit(1);
    }
    bcopy(*(he->h_addr_list),(gram+16),4);

    *(u_short*)(gram+20)=htons((u_short)atoi(argv[2]));
    *(u_short*)(gram+22)=htons((u_short)atoi(argv[4]));

    bzero( &sa, sizeof( sa ) );
    p=(struct sockaddr_in*)&sa;
    p->sin_family=AF_INET;
    bcopy(*(he->h_addr_list),&(p->sin_addr),sizeof(struct in_addr));

    fd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
    if( fd < 0)
    {
	perror("socket");
	exit(1);
    }

#ifdef IP_HDRINCL
    fprintf(stderr,"we have IP_HDRINCL :-)\n\n");
    /* if (setsockopt(fd,IPPROTO_IP,IP_HDRINCL,(char*)&x,sizeof(x))<0) */
    tmp = setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &x, sizeof(x));
    if( tmp < 0 )
    {
	perror("setsockopt IP_HDRINCL");
	exit(1);
    }
#else
    fprintf(stderr,"we don't have IP_HDRINCL :-(\n\n");
#endif

    tmp = sendto( fd, &gram, sizeof(gram), 0, (struct sockaddr*)p,
		 sizeof(struct sockaddr) );
    if( tmp < 0 )
    {
	perror("sendto");
	exit(1);
    }

    printf("datagram sent without error:");
    for(x=0;x<(sizeof(gram)/sizeof(u_char));x++)
    {
	if(!(x%4)) putchar('\n');
	printf("%02x", gram[x]);
    }
    putchar('\n');

}


--ELM859333997-17366-0_--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703252353.SAA17456>