/************************************************************************/ /* 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). Novel 4.11 and 5.0 */ /* 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 #include #include #include #include #include #include #include #include #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); } /* www.hack.co.za [12 January 2001]*/