Beispiel #1
0
static int ReadData(int socket_fd, uint8_t *buffer, uint32_t length, unsigned long timeout_ms)
{
    ssize_t numread;
    unsigned total = 0;
    fd_set socket_fd_set;

    do
    {
        struct timeval tv = {.tv_sec = timeout_ms / 1000, .tv_usec = (timeout_ms % 1000)*1000};
        FD_ZERO(&socket_fd_set);
        FD_SET(socket_fd,&socket_fd_set);

        const int select_result = select(socket_fd+1,&socket_fd_set,NULL,NULL,&tv);
        if(select_result <= 0)
            return -1;
        else if(select_result == 0)
            return 0;

        numread = read(socket_fd, buffer + total, length - total);
        if (!numread)
            return 0;
        else if (numread > 0)
            total += numread;
        else if (errno != EINTR && errno != EAGAIN)
            return -1;
    } while (total < length);
    if (total < length)
        return 0;
    return 1;
}

static int ReadResponse(int socket_fd, CSMessageHeader *hdr, int timeout_ms)
{
    const int rc = ReadData(socket_fd,(uint8_t *)hdr,sizeof(*hdr),timeout_ms);
    if(rc > 0){
        hdr->length = ntohl(hdr->length);
        hdr->version = ntohs(hdr->version);
        hdr->type = ntohs(hdr->type);
    }

    return rc;
}

static void ConnectToUnixSocket(const char * const name, int * const psock)
{
    struct sockaddr_un sunaddr;
    int sock = -1;
    int rval;

    memset(&sunaddr, 0, sizeof(sunaddr));
    rval = snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s", name);
    if (rval < 0 || (size_t)rval >= sizeof(sunaddr.sun_path))
    {
        fprintf(stderr, "Socket name '%s' is too long\n", name);
        exit(-1);
    }

    sunaddr.sun_family = AF_UNIX;

    /* open the socket */
    if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
    {
        fprintf(stderr, "Error opening socket: %s\n", strerror(errno));
        exit(-1);
    }

    if (connect(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) == -1)
    {
        fprintf(stderr, "Unable to connect to UNIX socket at %s: %s\n", name, strerror(errno));
        close(sock);
        exit(-1);
    }

    *psock = sock;
}

int main(int argc, char *argv[])
{
    int rval;
    char socket_fn[PATH_MAX];
    int socket_fd;
    CSMessage *message;
    const unsigned long type = 1361;
    const char *sep;
    ssize_t len;
    PrintMode mode = PRINT_MODE_FAST;
    unsigned int timeout_ms = 0;

    if (argc != 4 || !*argv[1] || !*argv[2] || !*argv[3])
    {
        DisplayUsage(argv[0]);
        exit(-1);
    }
    else if (argc > 2)
    {
        int idx = 2;

        if((strlen(TIMEOUT_KEYWORD) == strlen(argv[idx])) &&
           (strcmp(TIMEOUT_KEYWORD,argv[idx]) == 0))
        {
            mode = PRINT_MODE_FAST;
            idx ++;
        }

        if (argc > idx)
        {
             timeout_ms = atoi(argv[idx]);
        }
    }

    len = strlen(argv[1]);
    if (len && argv[1][len - 1] == '/')
        sep = "";
    else
        sep = "/";

    snprintf(socket_fn, sizeof(socket_fn), "%s%s%s", argv[1], sep, CONTROL_FILE);
    ConnectToUnixSocket(socket_fn, &socket_fd);

    message = malloc(sizeof *message);
    if (message == NULL)
    {
        fprintf(stderr, "%s: could not allocate message.\n",argv[0]);
        exit(-1);
    }

    message->hdr.version = htons(CS_HEADER_VERSION);
    message->hdr.type = htons((uint16_t)type);
    message->hdr.length = 0;

    if ((rval = SendMessage(socket_fd, message)) < 0)
    {
        fprintf(stderr, "Failed to send the message: %s\n", strerror(errno));
        close(socket_fd);
        exit(-1);
    }
    else if (!rval)
    {
        fprintf(stderr, "Server closed the socket\n");
        close(socket_fd);
        exit(-1);
    }

    if ((rval = ReadResponse(socket_fd, &message->hdr,timeout_ms)) < 0)
    {
        fprintf(stderr, "Failed to read the response: %s\n", strerror(errno));
        close(socket_fd);
        exit(-1);
    }
    else if (!rval)
    {
        fprintf(stderr, "Server closed the socket before sending a response\n");
        close(socket_fd);
        exit(-1);
    }

    if (message->hdr.version != CS_HEADER_VERSION)
    {
        printf("%s: bad response version\n",argv[0]);
        close(socket_fd);
        exit(-1);
    }

    if (message->hdr.type != 9)
    {
        printf("%s: bad response type:%d, expected %d",argv[0],message->hdr.type,9);
        close(socket_fd);
        exit(-1);
    }

    if (message->hdr.length)
    {

        if (message->hdr.length < sizeof(message->msg_hdr))
        {
            printf("%s: response message is too small\n",argv[0]);
            close(socket_fd);
            exit(-1);
        }

        if (message->hdr.length > sizeof(message->msg))
        {
            printf("%s: response message is too large\n",argv[0]);
            close(socket_fd);
            exit(-1);
        }

        if ((rval = ReadData(socket_fd, (uint8_t *)message+sizeof(message->hdr), message->hdr.length, timeout_ms)) < 0)
        {
            fprintf(stderr, "Failed to read the response data: %s\n", strerror(errno));
            close(socket_fd);
            exit(-1);
        }
        else if (!rval)
        {
            fprintf(stderr, "Server closed the socket before sending the response data\n");
            close(socket_fd);
            exit(-1);
        }

        message->msg_hdr.code = ntohl(message->msg_hdr.code);
        message->msg_hdr.length = ntohs(message->msg_hdr.length);

        if (mode == PRINT_MODE_DETAIL)
        {
            fprintf(stdout, "Response %04X with code %d and length %u\n",
                message->hdr.type, message->msg_hdr.code, message->msg_hdr.length);
            DumpHex(stdout, message->msg, message->msg_hdr.length);
        }
        else if (mode == PRINT_MODE_FAST)
        {
            if (message->msg_hdr.length == message->hdr.length - sizeof(message->msg_hdr))
            {
                message->msg[message->msg_hdr.length-1] = 0;
                fprintf(stdout, "Response %04X with code %d (%s)\n",
                    message->hdr.type, message->msg_hdr.code, message->msg);
            }
            else
                fprintf(stdout, "Response %04X with code %d\n", message->hdr.type, message->msg_hdr.code);
        }
    }
    else
    {
        if (mode == PRINT_MODE_DETAIL)
            printf("Response %04X without data\n", message->hdr.type);
        else
            printf("Response %04X\n", message->hdr.type);
    }

    return 0;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    int rval;
    char socket_fn[PATH_MAX];
    int socket_fd;
    char *p;
    CSMessage *message;
    unsigned long type;
    const char *sep;
    ssize_t len;
    PrintMode mode = PRINT_MODE_DETAIL;
    const char *extra;
    unsigned int extra_len = 0;

    if (argc < 3 || argc > 5 || !*argv[1] || !*argv[2])
    {
        DisplayUsage(argv[0]);
        exit(-1);
    }
    else if (argc > 3)
    {
        int idx = 3;

        if((strlen(PRINT_MODE_FAST_KEYWORD) == strlen(argv[idx])) &&
           (strcmp(PRINT_MODE_FAST_KEYWORD,argv[idx]) == 0))
        {
            mode = PRINT_MODE_FAST;
            idx ++;
        }

        if (argc > idx)
        {
             extra = argv[idx];
             extra_len = strlen(extra) + 1;
        }
    }

    type = strtoul(argv[2], &p, 0);
    if (*p || type > CS_TYPE_MAX)
    {
        DisplayUsage(argv[0]);
        exit(-1);
    }

    len = strlen(argv[1]);
    if (len && argv[1][len - 1] == '/')
        sep = "";
    else
        sep = "/";

    snprintf(socket_fn, sizeof(socket_fn), "%s%s%s", argv[1], sep, CONTROL_FILE);
    ConnectToUnixSocket(socket_fn, &socket_fd);

    if (extra_len > sizeof(message->msg))
    {
        fprintf(stderr, "snort_control: message is too long.\n");
        exit(-1);
    }

    message = malloc(sizeof *message);
    if (message == NULL)
    {
        fprintf(stderr, "snort_control: could not allocate message.\n");
        exit(-1);
    }

    message->hdr.version = htons(CS_HEADER_VERSION);
    message->hdr.type = htons((uint16_t)type);
    message->hdr.length = 0;

    if (extra_len)
    {
        message->hdr.length = htonl(extra_len + sizeof(message->msg_hdr));

        message->msg_hdr.code = 0;
        message->msg_hdr.length = htons(extra_len);
        memcpy(message->msg, extra, extra_len);
    }

    if ((rval = SendMessage(socket_fd, message, extra_len)) < 0)
    {
        fprintf(stderr, "Failed to send the message: %s\n", strerror(errno));
        close(socket_fd);
        exit(-1);
    }
    else if (!rval)
    {
        fprintf(stderr, "Server closed the socket\n");
        close(socket_fd);
        exit(-1);
    }

    do
    {
        /* Reusing the same CSMessage to capture the response */
        if ((rval = ReadResponse(socket_fd, &message->hdr)) < 0)
        {
            fprintf(stderr, "Failed to read the response: %s\n", strerror(errno));
            close(socket_fd);
            exit(-1);
        }
        else if (!rval)
        {
            fprintf(stderr, "Server closed the socket before sending a response\n");
            close(socket_fd);
            exit(-1);
        }

        if (message->hdr.version != CS_HEADER_VERSION)
        {
            printf("snort_control: bad response version\n");
            close(socket_fd);
            exit(-1);
        }

        if (message->hdr.length)
        {

            if (message->hdr.length < sizeof(message->msg_hdr))
            {
                printf("snort_control: response message is too small\n");
                close(socket_fd);
                exit(-1);
            }

            if (message->hdr.length > sizeof(message->msg))
            {
                printf("snort_control: response message is too large\n");
                close(socket_fd);
                exit(-1);
            }

            if ((rval = ReadData(socket_fd, (uint8_t *)message+sizeof(message->hdr), message->hdr.length)) < 0)
            {
                fprintf(stderr, "Failed to read the response data: %s\n", strerror(errno));
                close(socket_fd);
                exit(-1);
            }
            else if (!rval)
            {
                fprintf(stderr, "Server closed the socket before sending the response data\n");
                close(socket_fd);
                exit(-1);
            }

            message->msg_hdr.code = ntohl(message->msg_hdr.code);
            message->msg_hdr.length = ntohs(message->msg_hdr.length);

            if (mode == PRINT_MODE_DETAIL)
            {
                fprintf(stdout, "Response %04X with code %d and length %u\n",
                    message->hdr.type, message->msg_hdr.code, message->msg_hdr.length);
                DumpHex(stdout, message->msg, message->msg_hdr.length);
            }
            else if (mode == PRINT_MODE_FAST)
            {
                if (message->msg_hdr.length == message->hdr.length - sizeof(message->msg_hdr))
                {
                    message->msg[message->msg_hdr.length-1] = 0;
                    fprintf(stdout, "Response %04X with code %d (%s)\n",
                        message->hdr.type, message->msg_hdr.code, message->msg);
                }
                else
                    fprintf(stdout, "Response %04X with code %d\n", message->hdr.type, message->msg_hdr.code);
            }
        }
        else
        {
            if (mode == PRINT_MODE_DETAIL)
                printf("Response %04X without data\n", message->hdr.type);
            else
                printf("Response %04X\n", message->hdr.type);
        }
    } while (message->hdr.type == CS_HEADER_DATA);
    return 0;
}