]> sjero.net Git - dccpping/commitdiff
"Sort of working" code. Only IPv6, just detects DCCP packets in response, terrible...
authorSamuel Jero <sj323707@ohio.edu>
Wed, 24 Oct 2012 22:12:26 +0000 (18:12 -0400)
committerSamuel Jero <sj323707@ohio.edu>
Wed, 24 Oct 2012 22:12:26 +0000 (18:12 -0400)
.cproject [new file with mode: 0644]
.project [new file with mode: 0644]
Makefile [new file with mode: 0644]
dccpping.c [new file with mode: 0644]

diff --git a/.cproject b/.cproject
new file mode 100644 (file)
index 0000000..a4e9398
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.6529249">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.6529249" moduleId="org.eclipse.cdt.core.settings" name="Default">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.6529249" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+                                       <folderInfo id="cdt.managedbuild.toolchain.gnu.base.6529249.1950362390" name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.291047802" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1917078375" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder id="cdt.managedbuild.target.gnu.builder.base.1029524714" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.1173789358" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.962956111" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.466644873" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.base.2115081093" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1004924681" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.305791969" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"/>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="dccpping.null.318214883" name="dccpping"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+</cproject>
diff --git a/.project b/.project
new file mode 100644 (file)
index 0000000..57aa611
--- /dev/null
+++ b/.project
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>dccpping</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..6a76196
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,39 @@
+###############################################################################
+#Author: Samuel Jero <sj323707@ohio.edu>
+#
+# Date: 11/2011
+#
+# Makefile for program dccpping
+###############################################################################
+
+CFLAGS= -O2 -Wall -Werror -g --std=gnu99
+
+# for solaris, you probably want:
+#      LDLIBS = -lnsl -lsocket
+# for HP, I'm told that you need:
+#      LDLIBS = -lstr
+# everybody else (that I know of) just needs:
+#      LDLIBS =
+LDLIBS =
+
+CC = gcc
+
+BINDIR = /usr/local/bin
+MANDIR = /usr/local/man
+
+all: dccpping
+
+dccpping: dccpping.c
+       ${CC} ${CFLAGS} ${LDLIBS}  dccpping.c -odccpping
+
+
+install: dccpping
+       install -m 755 -o bin -g bin dccp2tcp ${BINDIR}/dccpping
+#      install -m 444 -o bin -g bin dccp2tcp.1 ${MANDIR}/man1/dccpping.1
+
+uninstall:
+       rm -f ${BINDIR}/dccpping
+#      rm -r ${MANDIR}/man1/dccpping.1
+
+clean:
+       rm -f *~ dccpping core *.o
\ No newline at end of file
diff --git a/dccpping.c b/dccpping.c
new file mode 100644 (file)
index 0000000..8dc59c0
--- /dev/null
@@ -0,0 +1,433 @@
+/******************************************************************************
+Author: Samuel Jero <sj323707@ohio.edu>
+
+Date: 10/2012
+
+Description: Program to ping hosts using DCCP REQ packets to test for DCCP connectivity.
+******************************************************************************/
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/ip.h>
+#include <net/if.h>
+#include <ctype.h>
+#include <linux/dccp.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <arpa/inet.h>
+#include <errno.h>
+
+extern int errno;
+
+
+//Pseudo Header for checksums
+#define IP4_ADDR_LEN   4
+struct ip4_pseudo_hdr{
+       unsigned char src[IP4_ADDR_LEN];
+       unsigned char dest[IP4_ADDR_LEN];
+       unsigned int len;
+       unsigned char zero[3];
+       unsigned char nxt;
+};
+#define IP6_ADDR_LEN   16
+struct ip6_pseudo_hdr{
+       unsigned char src[IP6_ADDR_LEN];
+       unsigned char dest[IP6_ADDR_LEN];
+       unsigned int len;
+       unsigned char zero[3];
+       unsigned char nxt;
+};
+
+
+int debug=0;           /*set to 1 to turn on debugging information*/
+int count=-1;
+int dest_port=33434;
+int ttl=64;
+long interval=1000;
+int ip_type=AF_UNSPEC;
+socklen_t addrlen;
+struct sockaddr *dest_addr;
+struct sockaddr *src_addr;
+
+
+void doping();
+int ip6_chksum(unsigned char* buff, int len, unsigned char* dest, unsigned char* src, int type, unsigned short* chksum);
+int ip4_chksum(unsigned char* buff, int len, unsigned char* dest, unsigned char* src, int type, unsigned short* chksum);
+u_int32_t checksum(unsigned char *buf, unsigned nbytes, u_int32_t sum);
+u_int32_t wrapsum(u_int32_t sum);
+void dbgprintf(int level, const char *fmt, ...);
+void sanitize_environment();
+void usage();
+
+
+/*Parse commandline options*/
+int main(int argc, char *argv[])
+{
+       char c;
+       char *src=NULL;
+       char *dst=NULL;
+       int err;
+       struct addrinfo hint;
+       struct addrinfo *dtmp, *stmp;
+       struct ifaddrs *temp, *cur;
+       struct sockaddr_in6* iv6;
+       struct sockaddr_in6 lv6;
+       struct sockaddr_in lv4;
+       struct sockaddr_in* iv4;
+
+       sanitize_environment();
+
+       while ((c = getopt(argc, argv, "64c:p:i:dt:S:")) != -1) {
+               switch (c) {
+                       case '6':
+                               ip_type=AF_INET6;
+                               break;
+                       case '4':
+                               ip_type=AF_INET;
+                               break;
+                       case 'c':
+                               count = atoi(optarg);
+                               if(count<=0){
+                                       dbgprintf(0, "Error: count must be positive");
+                                       exit(1);
+                               }
+                               break;
+                       case 'p':
+                               dest_port = atoi(optarg);
+                               break;
+                       case 'i':
+                               interval = (long)(atof(optarg) * 1000.0);
+                               if (interval <= 0) {
+                                       fprintf(stderr, "Invalid interval\n");
+                                       exit(1);
+                               }
+                               break;
+                       case 'd':
+                               debug++;
+                               break;
+                       case 't':
+                               ttl = atoi(optarg);
+                               if (ttl < 1 || ttl > 255) {
+                                       fprintf(stderr, "Invalid TTL\n");
+                               }
+                               break;
+                       case 'S':
+                               src=optarg;
+                               //r = inet_aton(optarg, &src_ip);
+                               break;
+                       default:
+                               usage();
+                               break;
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+       if (argc != 1) {
+               usage();
+       }
+       dst=argv[0];
+
+       /*Lookup destination Address*/
+       memset(&hint,0,sizeof(struct addrinfo));
+       hint.ai_family=ip_type;
+       hint.ai_flags=AI_V4MAPPED | AI_ADDRCONFIG;
+
+       if((err=getaddrinfo(dst,NULL,&hint,&dtmp))!=0){
+               dbgprintf(0,"Error: Couldn't lookup destination %s (%s)\n", dst, gai_strerror(err));
+               exit(1);
+       }
+       if(dtmp==NULL){
+               dbgprintf(0,"Error: Unknown Host %s\n", dst);
+               exit(1);
+       }else{
+               hint.ai_family=ip_type=dtmp->ai_family;
+               addrlen=dtmp->ai_addrlen;
+               dest_addr=malloc(dtmp->ai_addrlen);
+               if(dest_addr==NULL){
+                       dbgprintf(0,"Error: Can't allocate Memory\n");
+                       exit(1);
+               }
+               memcpy(dest_addr,dtmp->ai_addr,dtmp->ai_addrlen);
+       }
+       freeaddrinfo(dtmp);
+
+       /*Get a meaningful source address*/
+       if(src!=NULL){
+               /*Use Commandline arg*/
+               if((err=getaddrinfo(src,NULL,&hint,&stmp))!=0){
+                       dbgprintf(0,"Error: Source Address %s is invalid (%s)\n", src, gai_strerror(err));
+                       exit(1);
+               }
+               if(stmp==NULL){
+                       dbgprintf(0,"Error: Unknown Host %s\n", dst);
+                       exit(1);
+               }else{
+                       src_addr=malloc(stmp->ai_addrlen);
+                       if(src_addr==NULL){
+                               dbgprintf(0,"Error: Can't allocate Memory\n");
+                               exit(1);
+                       }
+                       memcpy(src_addr,stmp->ai_addr,stmp->ai_addrlen);
+               }
+               freeaddrinfo(stmp);
+       }else{
+               /*Guess a good source address*/
+               inet_pton(AF_INET6,"::1",&lv6);
+               inet_pton(AF_INET,"127.0.0.1",&lv4);
+               getifaddrs(&temp);
+               cur=temp;
+               while(cur!=NULL){
+                       if((cur->ifa_flags & IFF_BROADCAST) == IFF_BROADCAST){ /*Not broad cast*/
+                               cur=cur->ifa_next;
+                               continue;
+                       }
+                       if(cur->ifa_addr==NULL || cur->ifa_addr->sa_family!=ip_type){ /*Not matching ipv4/ipv6 of dest*/
+                               cur=cur->ifa_next;
+                               continue;
+                       }
+                       if(cur->ifa_addr!=NULL && cur->ifa_addr->sa_family==AF_INET6){
+                               iv6=(struct sockaddr_in6*)cur->ifa_addr;
+                               if(iv6->sin6_scope_id!=0){ /*Not globally valid address, if ipv6*/
+                                       cur=cur->ifa_next;
+                                       continue;
+                               }
+                               if(memcmp(&lv6.sin6_addr,&iv6->sin6_addr,sizeof(iv6->sin6_addr))==0){/*IPv6 loopback*/
+                                       cur=cur->ifa_next;
+                                       continue;
+                               }
+                       }
+                       if(cur->ifa_addr!=NULL && cur->ifa_addr->sa_family==AF_INET){
+                               iv4=(struct sockaddr_in*)cur->ifa_addr;
+                               if(memcmp(&lv4.sin_addr,&iv4->sin_addr,sizeof(iv4->sin_addr))==0){/*IPv4 loopback*/
+                                       cur=cur->ifa_next;
+                                       continue;
+                               }
+                       }
+
+                       src_addr=malloc(sizeof(struct sockaddr_storage));
+                       if(src_addr==NULL){
+                               dbgprintf(0,"Error: Can't allocate Memory\n");
+                               exit(1);
+                       }
+                       src_addr->sa_family=ip_type;
+                       memcpy(src_addr,cur->ifa_addr,addrlen);
+                       break;
+               }
+               freeifaddrs(temp);
+       }
+
+       doping();
+
+
+       free(src_addr);
+       free(dest_addr);
+       return 0;
+}
+
+/*Preform the ping functionality*/
+void doping(){
+       int ds, is;
+       int done=0;
+       int seq=8;
+       int slen=sizeof(struct dccp_hdr)+sizeof(struct dccp_hdr_ext)+sizeof(struct dccp_hdr_request);
+       unsigned char sbuffer[slen+1];
+       unsigned char rbuffer[1000];
+       char pbuf[1000];
+       struct dccp_hdr *dhdr;
+       struct dccp_hdr_ext *dhdre;
+       struct dccp_hdr_request *dhdrr;
+       struct sockaddr_storage rcv_addr;
+       socklen_t rcv_addr_len=sizeof(struct sockaddr_storage);
+       struct sockaddr_in *iv41, *iv42;
+       struct sockaddr_in6 *tmp;
+       int opt;
+       int rlen;
+
+       dbgprintf(0, "In doping()\n");
+
+       /*Open Sockets*/
+       ds=socket(ip_type, SOCK_RAW | SOCK_NONBLOCK ,IPPROTO_DCCP);
+       if(ds<0){
+               dbgprintf(0, "Error opening raw DCCP socket\n");
+               exit(1);
+       }
+       /*opt=1;
+       if(setsockopt(ds,IPPROTO_IP, IP_HDRINCL, &opt, sizeof(opt))<0){
+               dbgprintf(0, "Error setting socket options on raw DCCP socket (%s)\n", strerror(errno));
+               exit(1);
+       }*/
+       is=socket(ip_type,SOCK_RAW | SOCK_NONBLOCK ,IPPROTO_ICMP);
+       if(is<0){
+               dbgprintf(0,"Error opening raw ICMP socket\n");
+               exit(1);
+       }
+
+       /*Build DCCP packet*/
+       dhdr=(struct dccp_hdr*)sbuffer;
+       dhdre=(struct dccp_hdr_ext*)(sbuffer+sizeof(struct dccp_hdr));
+       dhdrr=(struct dccp_hdr_request*)(sbuffer+sizeof(struct dccp_hdr)+sizeof(struct dccp_hdr_ext));
+       dhdr->dccph_ccval=0;
+       dhdr->dccph_checksum=0;
+       dhdr->dccph_cscov=0;
+       dhdr->dccph_doff=slen/4;
+       dhdr->dccph_dport=htons(dest_port);
+       dhdr->dccph_reserved=0;
+       dhdr->dccph_sport=htons(dest_port+1);
+       dhdr->dccph_x=1;
+       dhdr->dccph_type=DCCP_PKT_REQUEST;
+       dhdr->dccph_seq2=htonl(0); //Reserved for 48 bit sequence numbers
+       dhdr->dccph_seq=htonl(0);  //just always make the high end 0
+       dhdre->dccph_seq_low=htonl(seq)>>8;
+       dhdrr->dccph_req_service= htonl(0x50455246);
+
+       opt=((unsigned char*)&dhdr->dccph_checksum) - &sbuffer[0];
+       if (setsockopt(ds, IPPROTO_IPV6, IPV6_CHECKSUM, &opt, sizeof(opt)) < 0){
+               dbgprintf(0, "Error setting up checksums on raw DCCP socket (%s)\n", strerror(errno));
+               exit(1);
+       }
+       if(ip_type==AF_INET){
+               iv41=(struct sockaddr_in*)dest_addr;
+               iv42=(struct sockaddr_in*)src_addr;
+               ip4_chksum(sbuffer, slen, (unsigned char*) &iv41->sin_addr, (unsigned char*)&iv42->sin_addr, 33,&dhdr->dccph_checksum);
+       }
+
+       while(!done){
+               rcv_addr_len=sizeof(struct sockaddr_storage);
+               if(sendto(ds, &sbuffer, slen, MSG_DONTWAIT,(struct sockaddr*)dest_addr,addrlen)<0){
+                       dbgprintf(0,"Error: sendto failed\n");
+               }
+               tmp=(struct sockaddr_in6*)dest_addr;
+               dbgprintf(0, "Sending DCCP Request to %s\n",inet_ntop(ip_type, (void*)&tmp->sin6_addr, pbuf, 1000));
+
+               if((rlen=recvfrom(ds, &rbuffer, 1000,MSG_DONTWAIT,(struct sockaddr*)&rcv_addr,&rcv_addr_len))<0){
+                       if(errno!=EAGAIN){
+                               dbgprintf(0, "Error on receive from DCCP socket (%s)\n",strerror(errno));
+                       }
+               }
+               if(rlen>0){
+                       if(rlen< sizeof(struct dccp_hdr)){
+                               dbgprintf(0,"Received Non-DCCP data!\n");
+                       }
+                       dhdr=(struct dccp_hdr*)rbuffer;
+                       tmp=(struct sockaddr_in6*)&rcv_addr;
+                       dbgprintf(0,"Response from %s (%i)\n", inet_ntop(ip_type, (void*)&tmp->sin6_addr, pbuf, 1000),dhdr->dccph_type);
+               }
+
+               if((rlen=recvfrom(is, &rbuffer, 1000,MSG_DONTWAIT,(struct sockaddr*)&rcv_addr,&rcv_addr_len))<0){
+                       if(errno!=EAGAIN){
+                               dbgprintf(0, "Error on receive from ICMP socket (%s)\n",strerror(errno));
+                       }
+               }
+               if(rlen>0){
+                       dbgprintf(0,"Received ICMP data!\n");
+               }
+
+               if(count>-1){
+                       count--;
+               }
+               if(count==0){
+                       done=1;
+                       break;
+               }
+               sleep(interval/1000);
+       }
+
+       close(ds);
+       close(is);
+}
+
+int ip6_chksum(unsigned char* buff, int len, unsigned char* dest, unsigned char* src, int type, unsigned short* chksum){
+       struct ip6_pseudo_hdr hdr;
+
+       //create pseudo header
+       memset(&hdr, 0, sizeof(struct ip6_pseudo_hdr));
+       memcpy(hdr.src, src, IP6_ADDR_LEN);
+       memcpy(hdr.dest, dest, IP6_ADDR_LEN);
+       hdr.nxt=type;
+       hdr.len=htonl(len);
+
+       //calculate total checksum
+       *chksum=wrapsum(checksum((unsigned char*)&hdr,sizeof(struct ip6_pseudo_hdr),checksum(buff,len,0)));
+return 0;
+}
+
+int ip4_chksum(unsigned char* buff, int len, unsigned char* dest, unsigned char* src, int type, unsigned short* chksum){
+       struct ip4_pseudo_hdr hdr;
+
+       //create pseudo header
+       memset(&hdr, 0, sizeof(struct ip4_pseudo_hdr));
+       memcpy(hdr.src, src, IP4_ADDR_LEN);
+       memcpy(hdr.dest, dest, IP4_ADDR_LEN);
+       hdr.nxt=type;
+       hdr.len=htonl(len);
+
+       //calculate total checksum
+       *chksum=wrapsum(checksum((unsigned char*)&hdr,sizeof(struct ip4_pseudo_hdr),checksum(buff,len,0)));
+return 0;
+}
+
+u_int32_t checksum(unsigned char *buf, unsigned nbytes, u_int32_t sum)
+{
+       int i;
+       /* Checksum all the pairs of bytes first... */
+       for (i = 0; i < (nbytes & ~1U); i += 2) {
+               sum += (u_int16_t)ntohs(*((u_int16_t *)(buf + i)));
+               if (sum > 0xFFFF)
+                       sum -= 0xFFFF;
+       }
+       /*
+        * If there's a single byte left over, checksum it, too.
+        * Network byte order is big-endian, so the remaining byte is
+        * the high byte.
+        */
+       if (i < nbytes) {
+               sum += buf[i] << 8;
+               if (sum > 0xFFFF)
+                       sum -= 0xFFFF;
+       }
+       return (sum);
+}
+
+u_int32_t wrapsum(u_int32_t sum)
+{
+       sum = ~sum & 0xFFFF;
+       return (htons(sum));
+}
+
+/*Usage information for program*/
+void usage()
+{
+       dbgprintf(0, "dccpping: [-d] [-6|-4] [-c count] [-p port] [-i interval] [-t ttl] [-S srcaddress] remote_host\n");
+       exit(0);
+}
+
+/*Program will probably be run setuid, so be extra careful*/
+void sanitize_environment()
+{
+#if defined(_SVID_SOURCE) || defined(_XOPEN_SOURCE)
+       clearenv();
+#else
+       extern char **environ;
+       environ = NULL;
+#endif
+}
+
+/*Debug Printf*/
+void dbgprintf(int level, const char *fmt, ...)
+{
+    va_list args;
+    if(debug>=level){
+       va_start(args, fmt);
+       vfprintf(stderr, fmt, args);
+       va_end(args);
+    }
+}