简单端口扫描linux port scanner

tcp/ip填充部分代码参考<网络扫描技术揭密>,同样代码可以参考 anti_sniff代码的anti_sniff/flood_net.c,使用的是一样的方法。


预条件:

安装ethotool, 目的,为了关闭checksum的pre-calculated, 原因Google关键字"tcpdump cksum incorrect"

参考link  http://seclists.org/tcpdump/2012/q4/91

              http://linux.about.com/od/commands/l/blcmdl8_ethtool.htm

安装ethtool过程:

>>./configure

>>make

>>./ethtool -K eth0 rx off

简易prot scanner使用方法

>>./a.out ipaddress startport endport


代码:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <pthread.h>




#define PACKET_LENGTH 128
#define IP_LENGTH     16
struct sockInfo{
    int   dport;
    char dIpAddr[IP_LENGTH];
};


struct ip_hdr{
    unsigned char  h_verlen;
    unsigned char  tos;
    unsigned short total_len;
    unsigned short ident;
    unsigned short frag_and_flags;
    unsigned char  ttl;
    unsigned char  proto;
    unsigned short checksum;
    unsigned int   sourceIP;
    unsigned int   destIP;
};
struct psd_hdr{
    unsigned long saddr;
    unsigned long daddr;
    unsigned char mbz;
    unsigned char ptcl;
    unsigned long tcpl;
};




//reference /use/include/netinet/tcp.h
struct tcp_hdr{
    u_int16_t th_sport;
    u_int16_t th_dport;
    u_int32_t th_seq;
    u_int32_t th_ack;
    u_int8_t  th_lenres;
    u_int8_t  th_flag;
    u_int16_t th_win;
    u_int16_t th_sum;
    u_int16_t th_urp;
};
void* tcpScan(void* param);
void fillSockInfo(struct sockInfo *pSockInfo, char* destIp, int destPort);
void usage(void);
unsigned short csum(unsigned short *buf, int len);
int main(int argc, char* argv[])
{
    int   startPort          = 0;
    int   endPort            = 0;
    int   numPort            = 0;
    int   i =                0;
    char  buf[PACKET_LENGTH] = {0};
    struct iphdr *ip         = (struct iphdr *) buf;
    struct tcphdr *tcp       = (struct tcphdr*)(buf + sizeof(struct iphdr));
    struct sockInfo sInfo    = {0};
    int one = 1;
    const int* val = &one;




    if( 4 != argc){
        usage();
        return 0;
    }




    startPort = atoi(argv[2]);
    endPort   = atoi(argv[3]);




    if((startPort < 1) ||(startPort > 65535)){
        printf("Error: port number should between 1~56635\n");
        return 0;
    }
    if((endPort < 1)||(endPort > 65535)){
        printf("Error: port number should between 1~56635\n");
        return 0;
    }




    if(startPort > endPort){
        printf("Error: start port should not be greater than end port\n");
        return 0;
    }




    numPort =  endPort - startPort + 1;




    for(i = 0; i < numPort; i++){
        fillSockInfo(&sInfo, argv[1], startPort+ i);
        tcpScan((void*)&sInfo);
    }
    return 0;
}








void usage(void)
{
    printf("Usage:\n");
    printf("\t\t ./sscan ipaddress startport endport\n");
    return;
}
void fillSockInfo(struct sockInfo *pSockInfo, char* destIp, int destPort)
{
    memset(pSockInfo, 0, sizeof(struct sockInfo));
    pSockInfo->dport = destPort;
    strcpy(pSockInfo->dIpAddr, destIp);
    return ;
}
void* tcpScan(void* param)
{
    char* src = "192.168.0.133";
    char* dst = ((struct sockInfo*)param)->dIpAddr;
    int   dPort =((struct sockInfo*)param)->dport;
    int   sPort = 55555;
    int   sd    = 0;
    char  buf[PACKET_LENGTH] = {0};
    char  recv[PACKET_LENGTH] = {0};
    struct iphdr *ip = (struct iphdr*) buf;
    struct tcphdr *tcp = (struct tcphdr*)(buf + sizeof(struct iphdr));
    struct ip_hdr  ipHeader   = {0};
    struct tcp_hdr tcpHeader  = {0};
    struct psd_hdr psdHeader  = {0};
    struct sockaddr_in sin, din;
    int one = 1;
    int cnt = 0;
    socklen_t socklen = 0;
    const int *val = &one;
    struct timeval timeout;




    timeout.tv_sec = 2;
    timeout.tv_usec = 0;
    memset(buf, 0, PACKET_LENGTH);
    sd =  socket(PF_INET, SOCK_RAW, IPPROTO_TCP);


    if( sd < 0){
        perror("socket() error");
        exit(-1);
    }else{
        printf("socket()-SOCK_RAW and tcp protocol is OK.\n");
    }




    sin.sin_family = AF_INET;
    din.sin_family = AF_INET;
    sin.sin_port = htons(sPort);
    din.sin_port = htons(dPort);
    sin.sin_addr.s_addr = inet_addr(src);
    din.sin_addr.s_addr = inet_addr(dst);




    ipHeader.h_verlen      = (4<<4|sizeof(ipHeader)/sizeof(unsigned long));
    ipHeader.tos           = 0;
    ipHeader.total_len     = htonl(sizeof(ipHeader) + sizeof(tcpHeader));
    ipHeader.ident         = 1;
    ipHeader.frag_and_flags = 0;
    ipHeader.ttl           = 128;
    ipHeader.proto         = IPPROTO_TCP;
    ipHeader.checksum      = 0;
    ipHeader.sourceIP      = inet_addr(src);
    ipHeader.destIP        = inet_addr(dst);




    tcpHeader.th_sport = htons(sPort);
    tcpHeader.th_dport = htons(dPort);
    tcpHeader.th_seq   = (random()%65535);
    tcpHeader.th_ack   = (random()%65535);
    tcpHeader.th_lenres = (sizeof(tcpHeader)/4 << 4 | 0);
    tcpHeader.th_flag  = 2;
    tcpHeader.th_win   = htons(512);
    tcpHeader.th_urp   = 0;
    tcpHeader.th_sum   = 0;




    psdHeader.saddr = inet_addr(src);
    psdHeader.daddr = inet_addr(dst);
    psdHeader.mbz   = 0;
    psdHeader.ptcl  = IPPROTO_TCP;
    psdHeader.tcpl  = htonl(sizeof(tcpHeader));




    memcpy(buf, &psdHeader, sizeof(psdHeader));
    memcpy(buf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
    tcpHeader.th_sum = csum((unsigned short*) buf, sizeof(*ip) + sizeof(tcpHeader));
    
    memcpy(buf, &ipHeader, sizeof(ipHeader));
    memcpy(buf+ sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
    ipHeader.checksum = csum((unsigned short*) buf, sizeof(ipHeader)+ sizeof(tcpHeader));
    memcpy(buf, &ipHeader, sizeof(ipHeader));




    if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0){
        perror("setsockopt() error");
        exit(-1);
    }else{
        printf("setsockopt() is OK\n");
    }
    if (setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0){
        error("setsockopt failed\n");
    }else{
        printf("setsockopt() is OK\n");
    }
    if (setsockopt (sd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0){
        error("setsockopt failed\n");
    }else{
        printf("setsockopt() is OK\n");
    }




    if(sendto(sd, buf, sizeof(ipHeader) + sizeof(tcpHeader), 0, (struct sockaddr *)&sin, sizeof(sin)) < 0){
        perror("sendto() error");
        exit(-1);
    }else{
        printf("sendto() is OK\n");
    }




    cnt = 5;
    while(cnt){
        memset(recv, 0, PACKET_LENGTH);
        if( recvfrom(sd, recv, PACKET_LENGTH, 0, (struct sockaddr*)&sin, (socklen_t *)&socklen) > 0 ){
            printf("receive data from %d\n", dPort);
            break;
        }
        cnt--;
    }




    return NULL;
}
unsigned short csum(unsigned short *buf, int len)
{
    unsigned long sum;
    for(sum=0; len>0; len--){
        sum += *buf++;
    }
    sum = (sum >> 16) + (sum &0xffff);
    sum += (sum >> 16);
    return (unsigned short)(~sum);
}

===============================================================================================================================

发送端:




接收端



你可能感兴趣的:(简单端口扫描linux port scanner)