Example #1
0
/****************************************************************************
 ** Current version of sngrep launches a thread that execs original ngrep
 ** binary. sngrep was born with the idea of parsing ngrep output.
 ** This could be changed with a bit of effort to a network capturing thread
 ** using libpcap functions, but we'll keep this way for now.
 **
 ** Also, take into account that as a parser, we expect ngrep header in an
 ** expecific format that is obtained using ngrep arguments -qpt which are
 ** forced by the exec process.
 **
 ** U DD/MM/YY hh:mm:ss.uuuuuu fff.fff.fff.fff:pppp -> fff.fff.fff.fff:pppp
 **
 ** If any other parameters are supplied to sngrep that changes this header
 ** (let's say -T), sngrep will fail at parsing any header :(
 **
 ****************************************************************************/
int
online_capture(void *pargv)
{
    char **argv = (char**) pargv;
    int argc = 1;
    char cmdline[512];
    FILE *fp;
    char stdout_line[2048] = "";
    char msg_header[256], msg_payload[20480];

    // Build the commald line to execute ngrep
    memset(cmdline, 0, sizeof(cmdline));
    sprintf(cmdline, "%s %s %s %s", STDBUF_BIN, STDBUF_ARGS, NGREP_BIN, NGREP_ARGS);
    // Add save to temporal file (if option enabled)
    if (!is_option_disabled("sngrep.tmpfile"))
        sprintf(cmdline + strlen(cmdline), " -O %s", get_option_value("sngrep.tmpfile"));

    while (argv[argc]){
        if (strchr(argv[argc], ' ')) {
            sprintf(cmdline + strlen(cmdline), " \"%s\"", argv[argc++]);
        } else {
            sprintf(cmdline + strlen(cmdline), " %s", argv[argc++]);
        }
    }

    // Open the command for reading.
    fp = popen(cmdline, "r");
    if (fp == NULL) {
        printf("Failed to run command\n");
        return 1;
    }

    // Read the output a line at a time - output it.
    while (fgets(stdout_line, 1024, fp) != NULL) {
        if (!strncmp(stdout_line, "\n", 1) && strlen(msg_header) && strlen(msg_payload)) {
            // Parse message
            struct sip_msg *msg;
            if ((msg = sip_load_message(msg_header, strdup((const char*) msg_payload)))) {
                // Update the ui
                ui_new_msg_refresh(msg);
            }

            // Initialize structures
            strcpy(msg_header, "");
            strcpy(msg_payload, "");
        } else {
            if (!strncmp(stdout_line, "U ", 2)) {
                strcpy(msg_header, stdout_line);
            } else {
                if (strlen(msg_header)) {
                    strcat(msg_payload, stdout_line);
                }
            }
        }
    }

    // Close read pipe
    pclose(fp);
    return 0;
}
Example #2
0
void
parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packet)
{
    // Datalink Header size
    int size_link;
    // Ethernet header data
    struct ether_header *eptr;
    // Ethernet header type
    u_short ether_type;
    // IP header data
    struct nread_ip *ip;
    // IP header size
    int size_ip;
    // UDP header data
    struct nread_udp *udp;
    // XXX Fake header (Like the one from ngrep)
    char msg_header[256];
    // Packet payload data
    u_char *msg_payload;
    // Packet payload size
    int size_payload;
    // Parsed message data
    sip_msg_t *msg;

    // Get link header size from datalink type
    if (linktype == DLT_EN10MB) {
        eptr = (struct ether_header *) packet;
        if ((ether_type = ntohs(eptr->ether_type)) != ETHERTYPE_IP) return;
        size_link = SIZE_ETHERNET;
    } else if (linktype == DLT_LINUX_SLL) {
        size_link = SLL_HDR_LEN;
    } else if (linktype == DLT_NULL) {
        size_link = DLT_RAW;
    } else {
        // Something we are not prepared to parse :(
        fprintf(stderr, "Error handing linktype %d\n", linktype);
        return;
    }

    // Get IP header
    ip = (struct nread_ip*) (packet + size_link);
    size_ip = IP_HL(ip) * 4;

    // Only interested in UDP packets
    if (ip->ip_p != IPPROTO_UDP) return;

    // Get UDP header
    udp = (struct nread_udp*) (packet + size_link + size_ip);

    // Get package payload
    msg_payload = (u_char *) (packet + size_link + size_ip + SIZE_UDP);
    size_payload = htons(udp->udp_hlen) - SIZE_UDP;
    msg_payload[size_payload] = '\0';

    // XXX Process timestamp
    struct timeval ut_tv = header->ts;
    time_t t = (time_t) ut_tv.tv_sec;

    // XXX Get current time
    char timestr[200];
    struct tm *time = localtime(&t);
    strftime(timestr, sizeof(timestr), "%Y/%m/%d %T", time);

    // XXX Build a header string
    sprintf(msg_header, "U %s.%06ld", timestr, ut_tv.tv_usec);
    sprintf(msg_header, "%s %s:%u", msg_header, inet_ntoa(ip->ip_src), htons(udp->udp_sport));
    sprintf(msg_header, "%s -> %s:%u", msg_header, inet_ntoa(ip->ip_dst), htons(udp->udp_dport));

    // Parse this header and payload
    if ((msg = sip_load_message(msg_header, (const char*) msg_payload)) && !strcasecmp((const char*)mode, "Online") ) {
        ui_new_msg_refresh(msg);
    }
}