/******************************************************************************/ /** **/ /** MODULE USED **/ /** **/ /******************************************************************************/ #include <stdio.h> /*printf*/ #include <stdlib.h> /*aoti*/ #include <unistd.h> /*gethostname,close*/ #include <sys/types.h> #include <sys/socket.h> /*socket,setsockopt,connect*/ #include <strings.h> /*bzero*/ #include <errno.h> #include <fcntl.h> #include <sys/select.h> /*select*/ #include <sys/time.h> /*time*/ #include <sys/types.h> #include <sys/signal.h> #include <fcntl.h> /*fcntl*/ #include <netdb.h> /*struct hostent*/ #include <netinet/in.h> /*inet_addr*/ #include <arpa/inet.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <string.h> #include <sys/ioctl.h> #include <net/if.h> #include <netinet/tcp.h> #include <netinet/udp.h> /******************************************************************************/ /** **/ /** DEFINITIONS AND MACROS **/ /** **/ /******************************************************************************/ #define LOCALPORT 32776 #define UDP_LEN 8 #define UDP_CKSUM 0xe887 #define DESTI_UNREACH_ICMP 3 #define PORT_UNREACH_ICMP 3 #define PORT_CLOSED -1 #define PORT_OPENED 0 #define DEV_NAME "eth1"
#define ENABLE_DEBUG /*debug macro*/ #ifdef ENABLE_DEBUG int Debug= 1; #else #define Debug 0 #endif #define DBG(fmts,args...) if(Debug)printf(fmts,##args)
struct pseudo_hdr{ struct in_addr src; struct in_addr dst; uint8_t mbz; uint8_t proto; uint16_t len; }__attribute__((__packed__));
/******************************************************************************/ /** **/ /** LOCAL FUNCTIONS **/ /** **/ /******************************************************************************/ static int fetch_ip(struct in_addr *ina) { int sockfd; struct ifreq ifr; if (!ina){ return -1; }
sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0){ perror("SOCK_RAW"); return -1; } memcpy(ifr.ifr_name, DEV_NAME, IFNAMSIZ); if ( ioctl(sockfd, SIOCGIFADDR, &ifr) < 0 ){ perror("ioctl(SIOCGIFADDR)"); close(sockfd); return -1; }
memcpy(ina, &ifr.ifr_addr.sa_data[2], sizeof(struct in_addr)); DBG("fetch ip result %s\n", inet_ntoa(*ina)); return 0;
}
unsigned short in_cksum(unsigned short *addr, int len) { int sum=0; unsigned short res=0; while( len > 1) { sum += *addr++; len -=2; } if( len == 1) { *((unsigned char *)(&res))=*((unsigned char *)addr); sum += res; } sum = (sum >>16) + (sum & 0xffff); sum += (sum >>16) ; res = ~sum; return res; }
static int sendUdp(int sockfd, struct sockaddr_in *dest) { char buffer[100]; struct ip *ip; struct udphdr *udp; struct icmp *icmp; int udphd_len, total_len; fd_set fdset; int retval; int len = 0; struct timeval tmout; tmout.tv_sec = 5; tmout.tv_usec = 0; struct pseudo_hdr *pseudo_header;
udphd_len = sizeof(struct udphdr); total_len = udphd_len + sizeof(struct pseudo_hdr); pseudo_header = (struct pseudo_hdr *)buffer; fetch_ip(&pseudo_header->src); memcpy(&pseudo_header->dst, &dest->sin_addr, sizeof(struct in_addr)); pseudo_header->mbz = 0; pseudo_header->proto = IPPROTO_UDP; pseudo_header->len = htons(udphd_len); /*fill the udp data*/ udp=(struct udphdr *)&buffer[sizeof(struct pseudo_hdr)]; udp->source = htons(LOCALPORT); udp->dest = dest->sin_port; /** target port **/ udp->len = htons(udphd_len); udp->check = 0;
udp->check = in_cksum((unsigned short *)buffer, total_len);
retval = sendto(sockfd, &buffer[sizeof(struct pseudo_hdr)], udphd_len, 0, (struct sockaddr *)dest, sizeof(struct sockaddr_in));
if (retval != udphd_len){ DBG("sendto error with length %d\n", retval); return -1; } FD_ZERO(&fdset); FD_SET(sockfd, &fdset); retval = select(sockfd+1, &fdset, NULL, NULL, &tmout); if (retval <= 0){ DBG("select error with return %d\n", retval); FD_CLR(sockfd,&fdset); close(sockfd); return -1; }
recvfrom(sockfd,buffer,sizeof(buffer),0, NULL, 0);
icmp = (struct icmp*)(buffer+sizeof(struct ip));
DBG("icmp %d\n",icmp->icmp_type); if(icmp->icmp_type == DESTI_UNREACH_ICMP){ DBG("destination unreachable\n"); } if(icmp->icmp_code == PORT_UNREACH_ICMP){ DBG("port unreachable\n"); close(sockfd); return PORT_CLOSED; }
close(sockfd); return 0; }
int UdpPortScan(char *address,char *port) { int sockfd; struct sockaddr_in addr; struct hostent *host; int n = 1; int result;
if(!address || !port){ DBG("Wrong args\n"); return 1; } bzero(&addr,sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons(atoi(port)); host = gethostbyname(address); if ( NULL == host){ DBG("can't resolv the host\n"); return 1; } addr.sin_addr=*(struct in_addr *)(host->h_addr_list[0]);
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); if(sockfd < 0){ perror("SOCK_RAW"); return 1; } //setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));
//setuid(getpid());
result = sendUdp(sockfd, &addr); return result; }
int TcpPortScan(char *host,char *pt) { int sockfd, port, yes, status,result; //struct hostent *tgHost;
struct sockaddr_in srvaddr; struct timeval timeout; fd_set fd;
if (!host || !pt){ return 1; }
port = atoi(pt);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0 )) == -1){ perror("SOCK_STREAM"); return 1; }
bzero(&srvaddr, sizeof(srvaddr)); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(port); srvaddr.sin_addr.s_addr = inet_addr(host);
timeout.tv_sec = 2; timeout.tv_usec = 0;
FD_ZERO(&fd); FD_SET(sockfd, &fd);
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *) &yes, sizeof (yes)) < 0) { DBG("setsockopt error\n"); return 1; } /*set the socket to non block mode*/ status = fcntl(sockfd, F_GETFL); fcntl(sockfd, F_SETFL, status | O_NONBLOCK);
if (connect( sockfd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr)) < 0){ switch (select(sockfd + 1, &fd, &fd, NULL, &timeout)){ case -1: DBG("select error\n"); result = -1; break; case 0: DBG("connect time out\n"); result = -1; break; default: //printf("%s %d opened\n", host, port);
result = 0; } }
FD_CLR(sockfd, &fd); close(sockfd); return result; }
static void usage(char *argv0) { fprintf(stderr, "Usage: %s [-d] [-u] [-t] [-h target ip] [-p target port] \n",argv0); }
int main(int argc,char *argv[]) { int c; int flagUdp = 0; int flagTcp = 0; int ret; char host[20] = {0}; char port[10] = {0};
if (argc < 4){ usage(argv[0]); DBG("argc %d\n",argc); exit(-1); }
if (argc > 1){ for (;;){ c = getopt( argc, argv, "dtuh:p:"); if (c == EOF) break; switch (c){ #ifdef ENABLE_DEBUG case 'd': ++Debug; break; #endif case 't': flagTcp = 1; break;
case 'u': flagUdp = 1; break;
case 'h': strcpy(host,optarg); DBG("host %s\n",host); break;
case 'p': strcpy(port,optarg); DBG("port %s\n",port); break; default: usage(argv[0]); exit(1); } } }
if (!flagTcp && !flagUdp){ printf("Processing TCP port Scaning\n"); flagTcp = 1; }
if (flagTcp == 1){ printf("Processing TCP port Scaning\n"); ret = TcpPortScan(host, port); if (!ret){ printf("ip %s tcp port %s is opened\n",host,port); } else if(ret == -1){ printf("ip %s tcp port %s is closed\n",host,port); } }
if (flagUdp == 1){ printf("Processing UDP port Scaning\n"); ret = UdpPortScan(host, port); if (!ret){ printf("ip %s udp port %s is opened\n",host,port); } else if (ret == -1){ printf("ip %s udp port %s is closed\n",host,port); } } return 0; }
|