home *** CD-ROM | disk | FTP | other *** search
-
-
- /************************************************************************/
- /* arnudp100.c - sends a single UDP datagram with the source and */
- /* destination address and port set to whatever you want. */
- /* Known to work on: Linux pre2.0.7 (486), SunOS 5.4 (SPARC) and */
- /* FreeBSD 2.1.0 (486). */
- /* Old kernels such as SunOS 4.1 and Linux 1.2 will overwrite the */
- /* source address with the real address of the interface. */
- /* Should compile fine with just an ANSI compiler (such as gcc) under */
- /* Linux and SunOS 4.1, but with SunOS 5.4 you may have to specify */
- /* extra libraries on the command line: */
- /* /usr/ucb/cc -o arnudp arnudp100.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. */
- /* Written by R.T.Arnold (arny@geek.org.uk) for Netcraft Ltd. */
- /* (c) copyright 1996 R.T. Arnold. This is not free software. */
- /************************************************************************/
-
- #include<sys/types.h>
- #include<sys/socket.h>
- #include<netinet/in.h>
- #include<arpa/inet.h>
- #include<netdb.h>
- #include<errno.h>
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
-
- #ifndef INADDR_NONE
- #define INADDR_NONE 0xffffffff
- #endif
-
- u_long getip(char*);
- u_short getportudp(char*);
-
- u_long cptol(u_char*);
- u_char *stocp(u_char*,u_short);
- u_char *ltocp(u_char*,u_long);
-
- union shortunion { u_short s; u_char c[2]; };
- union longunion { u_long l; u_char c[4]; };
-
- struct sockaddr sa;
-
- main(int argc,char **argv)
- {
- int fd;
- int x=1;
- u_long host;
- u_short service;
- struct sockaddr_in *p;
- u_char gram[]=
- {
- 0x45, 0x00, 0, 0,
- 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x11, 0x00, 0x00,
- 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'
- };
-
- /* sanity check... */
- if((sizeof(u_char)!=1)||(sizeof(u_short)!=2)||(sizeof(u_long)!=4))
- {
- fprintf(stderr,"error: integer types aren't the right size.\n");
- exit(1);
- };
-
- /* it does seem odd that the total length needs to be in host byte order */
- stocp(gram+2,(u_short)sizeof(gram));
-
- if(argc!=5)
- {
- fprintf(stderr,"usage: %s sourcename sourceport destinationname destinationport\n",*argv);
- exit(1);
- };
-
- /* fill in source/destination addresses/ports and the socket address...*/
- if(strcmp(argv[1],"255.255.255.255")==0) host=0xffffffff; else if((host=getip(argv[1]))==INADDR_NONE) exit(1);
- ltocp(gram+12,host);
- if(strcmp(argv[3],"255.255.255.255")==0) host=0xffffffff; else if((host=getip(argv[3]))==INADDR_NONE) exit(1);
- ltocp(gram+16,host);
- p=(struct sockaddr_in*)&sa;
- p->sin_family=AF_INET;
- p->sin_addr.s_addr=host;
- if(strcmp(argv[2],"0")==0) service=0; else if((service=getportudp(argv[2]))==0) exit(1);
- stocp(gram+20,service);
- if(strcmp(argv[4],"0")==0) service=0; else if((service=getportudp(argv[4]))==0) exit(1);
- stocp(gram+22,service);
-
- if((fd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))== -1)
- {
- perror("socket");
- exit(1);
- };
-
- #ifdef IP_HDRINCL
- if (setsockopt(fd,IPPROTO_IP,IP_HDRINCL,(char*)&x,sizeof(x))<0)
- {
- perror("setsockopt IP_HDRINCL");
- exit(1);
- };
- #else
- fprintf(stderr,"the IP_HDRINCL option didn't exist on the system this was compliled on.\n");
- #endif
-
- if((sendto(fd,&gram,sizeof(gram),0,&sa,sizeof(sa)))== -1)
- {
- perror("sendto");
- exit(1);
- };
-
- printf("datagram passed to kernel:");
- for(x=0;x<(sizeof(gram)/sizeof(u_char));x++)
- {
- if(!(x%4)) putchar('\n');
- printf("%02x",gram[x]);
- };
- putchar('\n');
- return(0);
- }
-
- /* returns IP address (as a u_long) given a hostname string */
-
- u_long getip(char *hostname)
- {
- u_long ip;
- struct hostent *he;
- if((ip=inet_addr(hostname))==INADDR_NONE)
- {
- if((he=gethostbyname(hostname))==NULL)
- {
- fprintf(stderr,"error: can't resolve hostname \"%s\"\n",hostname);
- return(INADDR_NONE);
- };
- if(he->h_addrtype!=AF_INET) fprintf(stderr,"warning: resolved address type is not AF_INET, will try to carry on anyway.\n");
- if(he->h_length!=4) fprintf(stderr,"warning: resolved address length is not 4, will try to carry on anyway.\n");
- ip=cptol((u_char*)*(he->h_addr_list));
- };
- return(ip);
- }
-
- /* returns port given a UDP service name or port number */
-
- u_short getportudp(char *service)
- {
- u_short port;
- struct servent *se;
- if((port=atoi(service))!=0) return(htons(port));
- if((se=getservbyname(service,"udp"))==NULL)
- {
- fprintf(stderr,"error: unknown service \"%s\"\n",service);
- return(0);
- };
- return(se->s_port);
- }
-
- /* the following functions convert between types, hopefully in a way thats portable */
-
- u_long cptol(u_char *cp)
- {
- static union longunion l;
- l.c[0]=cp[0];
- l.c[1]=cp[1];
- l.c[2]=cp[2];
- l.c[3]=cp[3];
- return(l.l);
- }
-
- u_char *stocp(u_char *cp,u_short us)
- {
- static union shortunion s;
- s.s=us;
- cp[0]=s.c[0];
- cp[1]=s.c[1];
- return(cp);
- }
-
- u_char *ltocp(u_char *cp,u_long ul)
- {
- static union longunion l;
- l.l=ul;
- cp[0]=l.c[0];
- cp[1]=l.c[1];
- cp[2]=l.c[2];
- cp[3]=l.c[3];
- return(cp);
- }
-
-
-