Проверьте, открыт ли порт UDP с ICMP в C - PullRequest
0 голосов
/ 12 марта 2020

Я пытаюсь проверить, открыт ли указанный c порт UDP или нет. Я пытаюсь сделать это, посылая пакеты UDP и проверяя ответ ICMP, чтобы видеть, доступен ли порт UDP или нет. Что я делаю неправильно?

#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <pthread.h>
#include <arpa/inet.h>   /* inet(3) functions */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/time.h>

#define MAXLINE 10096

int main(int argc, char **argv)
{
    int sockfd, portno;
    struct sockaddr_in servaddr;
    struct hostent *server;
    int sendfd, recvfd;

    server = gethostbyname(argv[1]);

    if (server == NULL)
    {
        fprintf(stderr,"ERROR, no such host\n");
        exit(EXIT_FAILURE);
    }
    //socket varibles
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;  
    bcopy((char *)server->h_addr, (char *)&servaddr.sin_addr.s_addr, server->h_length);
    //get port from command line arguments
    portno = atoi(argv[2]);
    servaddr.sin_port = htons(portno);
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

    // open send UDP socket
    if((sendfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
     {
       perror("*** socket(,,IPPROTO_UDP) failed ***n");
       exit(-1);
     }
     // open receive ICMP socket
     if((recvfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
     {
       perror("*** socket(,,IPPROTO_ICMP) failed ***n");
       exit(-1);
     }



    int n;
    char sendline[] = "a message";  //string for message to be sent
    char recvline[MAXLINE];     //string for message to be received


    //send ping request
    if(sendto(sendfd, sendline, sizeof(sendline), 0, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
    {
        perror("*** sendto() failed ***");
    }

    struct timeval tv;
    tv.tv_sec = 1;
    tv.tv_usec = 100000;
    if (setsockopt(recvfd, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) {
        perror("Error");
    }

    n = recvfrom(recvfd, recvline, MAXLINE, 0, NULL, NULL);
    recvline[n] = '\0';    /* null terminate */

    struct iphdr *ip_hdr = (struct iphdr *)recvline;
    int iplen = ip_hdr->ihl << 2;
    struct icmphdr *icmp = (struct icmphdr *)((char *)ip_hdr + (4 * ip_hdr->ihl));

    if((icmp->type == ICMP_UNREACH) && (icmp->code == ICMP_UNREACH_PORT))
    {
     printf("\nPORT CLOSED\n"); 
    }
    else
    {
        printf("\nPORT OPEN\n");    
    }



    exit(0);
}

Как мне заставить это работать? Когда я запускаю код, он всегда говорит «PORT OPEN» в каждом тестируемом порте, что определенно не может быть правильным.

...