コード例 #1
0
ファイル: telnet.c プロジェクト: shineit/wifimanage
static bool TelnetVerifyCheck(int flow_id, bool check)
{
    packet *pkt;
    short cnt, cnt_lim;
    long offset;

    cnt = 0;
    pkt = FlowGetPktCp(flow_id);
    /* numer of packet to verify */
    cnt_lim = TELNET_PKT_CHECK;
    if (!check) {
        cnt_lim = 1;
        do {
            while (pkt != NULL && pkt->len == 0) {
                PktFree(pkt);
                pkt = FlowGetPktCp(flow_id);
            }
            if (pkt != NULL && pkt->data != NULL && pkt->len != 0) {
                offset = TelnetSkipCommand((unsigned char *)(pkt->data), 
                                           (unsigned char *)(pkt->data + pkt->len));
                if (offset == pkt->len)
                    cnt++;
            }
            PktFree(pkt);
            pkt = FlowGetPktCp(flow_id);
        } while (pkt != NULL);
    }
    else {
        do {
            if (pkt != NULL && pkt->data != NULL && pkt->len != 0) {
                offset = TelnetSkipCommand((unsigned char *)(pkt->data), 
                                           (unsigned char *)(pkt->data + pkt->len));
                if (offset == pkt->len) {
                    cnt++;
                }
                else {
                    break;
                }
            }
            PktFree(pkt);
            pkt = FlowGetPktCp(flow_id);
        } while (pkt != NULL);
    }
    
    if (pkt != NULL)
        PktFree(pkt);
    if (cnt >= cnt_lim) {
        return TRUE;
    }

    return FALSE;
}
コード例 #2
0
ファイル: sdp.c プロジェクト: Cbrdiv/xplico
static packet* SdpDissector(packet *pkt)
{
    packet *sdp_pkt;
    sdp_msg *msg;
    pstack_f *frame;

    sdp_pkt = NULL;

    /* create new SDP message */
    msg = DMemMalloc(sizeof(sdp_msg));
    SdpMsgInit(msg);
    if (SdpParse(pkt, pkt->len, msg) == 0) {
        /* new sdp packet */
        sdp_pkt = PktNew();
        sdp_pkt->stk = ProtCopyFrame(pkt->stk, TRUE);

        /* new frame */
        frame = ProtCreateFrame(sdp_id);
        ProtSetNxtFrame(frame, sdp_pkt->stk);
        sdp_pkt->stk = frame;

        /* set frame attribute */
        sdp_pkt->cap_sec = pkt->cap_sec;
        sdp_pkt->cap_usec = pkt->cap_usec;
        sdp_pkt->serial = pkt->serial;
        
        sdp_pkt->data = (char *)msg;
    }
    PktFree(pkt);

    return sdp_pkt;
}
コード例 #3
0
ファイル: pppoe.c プロジェクト: Cbrdiv/xplico
static packet* PppoeDissector(packet *pkt)
{
    pstack_f *frame;
    ftval val;
    unsigned short len;
    pppoe_hdr *pppoeh;

    /* simple verify */
    if (sizeof(pppoe_hdr) > pkt->len) {
        ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }
    len = 0;
    pppoeh = (pppoe_hdr*)pkt->data;
    len = ntohs(pppoeh->len);
    
    if (len > pkt->len - sizeof(pppoe_hdr)) {
        ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }

    /* new frame */
    frame = ProtCreateFrame(prot_id);
    ProtSetNxtFrame(frame, pkt->stk);
    pkt->stk = frame;
    
    /* set attribute */
    /* type */
    val.uint8 = pppoeh->type;
    ProtInsAttr(frame, type_id, &val);
    
    /* code */
    val.uint8 = pppoeh->code;
    ProtInsAttr(frame, code_id, &val);

    /* session id */
    val.uint16 = ntohs(pppoeh->sess_id);
    ProtInsAttr(frame, ses_id, &val);

    /* pdu */
    pkt->data += sizeof(pppoe_hdr);
    pkt->len = len;

    return pkt;
}
コード例 #4
0
ファイル: sll.c プロジェクト: Cbrdiv/xplico
static packet* SllDissector(packet *pkt)
{
    pstack_f *frame;
    ftval val;
    struct sll_header *psll;
    unsigned short addr_len;

    /* check consistence */
    if (pkt->len < sizeof(struct sll_header)) {
        LogPrintf(LV_WARNING, "SLL packet dimension overflow the real dimension of packet");
        //ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }
    psll = (struct sll_header *)pkt->data;
    addr_len = ntohs(psll->sll_halen);
    if (addr_len > SLL_ADDRLEN) {
        LogPrintf(LV_WARNING, "SLL frame error");
        //ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }

    /* new frame */
    frame = ProtCreateFrame(prot_id);
    ProtSetNxtFrame(frame, pkt->stk);
    pkt->stk = frame;

    /* set attribute */
#if 0
    val.uint16 = ntohs(psll->sll_pkttype);
    ProtInsAttr(frame, pkttype_id, &val);
    val.uint16 = ntohs(psll->sll_hatype);
    ProtInsAttr(frame, hatype_id, &val);
    val.uint16 = addr_len;
    ProtInsAttr(frame, halen_id, &val);
#endif
    val.uint16 = ntohs(psll->sll_protocol);
    ProtInsAttr(frame, protocol_id, &val);

    /* pdu */
    pkt->data += sizeof(struct sll_header);
    pkt->len -= sizeof(struct sll_header);

    return pkt;
}
コード例 #5
0
ファイル: radiotap.c プロジェクト: Cbrdiv/xplico
static packet* RadiotapDissector(packet *pkt)
{
    pstack_f *frame;
    size_t rthdr_len;
    size_t rt_len;
    radiotap_hd *hd;

    if (pkt->len < sizeof(radiotap_hd)) {
        LogPrintf(LV_WARNING, "Radiotap size error");
        //ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }
    hd = (radiotap_hd *)pkt->data;
    rt_len = swap16(hd->it_len);
    if (rt_len > pkt->len) {
        LogPrintf(LV_WARNING, "Radiotap packet length error");
        //ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }

    /* add frame */
    frame = ProtCreateFrame(prot_id);
    ProtSetNxtFrame(frame, pkt->stk);
    pkt->stk = frame;
    
    /* pdu */
    pkt->data += rt_len;
    pkt->len -= rt_len;
    
    /* call wlan dissector */
    if (wlan_id != -1)
        return ProtDissecPkt(wlan_id, pkt);
    
    PktFree(pkt);
    return NULL;
}
コード例 #6
0
ファイル: null.c プロジェクト: Cbrdiv/xplico
static packet* NullDissector(packet *pkt)
{
    pstack_f *frame;
    ftval val;
    unsigned int null_hdr;
    unsigned short len;

    /* check consistence */
    if (pkt->len < 4) {
        LogPrintf(LV_WARNING, "Null packet dimension overflow the real dimension of packet");
        //ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }

    /* check if there is PPP */
    if (ntohs(*((unsigned short *)pkt->data)) == 0xFF03) {
        LogPrintf(LV_WARNING, "Null packet contents is PPP (to develop)");
        return NULL;
    }
    len = sizeof(unsigned int);
    memcpy(&null_hdr, pkt->data, len);
    if ((null_hdr & 0xFFFF0000) != 0) {
        /* swap bytes */
#warning "to complete"
        return NULL;
    }

    if (null_hdr > IEEE_802_3_MAX_LEN) {
#warning "to complete"
        return NULL;
    }
    
    /* new frame */
    frame = ProtCreateFrame(prot_id);
    ProtSetNxtFrame(frame, pkt->stk);
    pkt->stk = frame;

    /* set attribute */
    val.uint32 = null_hdr;
    ProtInsAttr(frame, family_id, &val);

    /* pdu */
    pkt->data += len;
    pkt->len -= len;

    return pkt;
}
コード例 #7
0
ファイル: vlan.c プロジェクト: Cbrdiv/xplico
static packet* VlanDissector(packet *pkt)
{
    pstack_f *frame;
    ftval val;
    int proto_offset;
    unsigned short proto, vid;
    unsigned short data;

    /* header */
    data = ntohs(*((uint16_t *)pkt->data));
    proto_offset = 2;

    /* vid */
    vid = data & 0x0FFF;
    
    /* protocol */
    proto = ntohs(*(uint16_t *)(pkt->data + proto_offset));
    proto_offset += 2;

    if (proto <= IEEE_802_3_MAX_LEN) {
        /* to be implemented */
        LogPrintf(LV_DEBUG, "Unknow protocol:%i ", proto);
        PktFree(pkt);
        
        return NULL;
    }

    /* new frame */
    frame = ProtCreateFrame(prot_id);
    ProtSetNxtFrame(frame, pkt->stk);
    pkt->stk = frame;

    /* set attribute */
    val.uint16 = vid;
    ProtInsAttr(frame, vid_id, &val);
    val.uint16 = proto;
    ProtInsAttr(frame, proto_id, &val);

    /* pdu */
    pkt->data += proto_offset;
    pkt->len -= proto_offset;

    return pkt;
}
コード例 #8
0
ファイル: tcp_analysis.c プロジェクト: M0Rf30/xplico
static int TcpCaDisFlowSetUp(tca_flow *ifw, packet *pkt)
{
    ftval lost;
    bool clnt;
    
    if (pkt != NULL) {
        clnt = TcpCaClientPkt(&ifw->priv, pkt);
        ProtGetAttr(pkt->stk, lost_id, &lost);
        if (lost.uint8 == FALSE) {
            /* create pei */
            PeiNew(&ifw->ppei, tcp_ca_id);
            PeiCapTime(ifw->ppei, pkt->cap_sec);
            PeiMarker(ifw->ppei, pkt->serial);
            PeiStackFlow(ifw->ppei, FlowStack(ifw->flow_id));
            ifw->cap_sec = pkt->cap_sec;
            ifw->end_cap = pkt->cap_sec;
            TcpCaDisFlow(ifw, pkt);
            return 0;
        }
        else {
            ifw->first_lost = TRUE;
            if (clnt) {
                ifw->priv.blost_sent += pkt->len;
                if (ifw->priv.blost_sent == 0)
                    ifw->priv.blost_sent = 1;
            }
            else {
                ifw->priv.blost_receiv += pkt->len;
                if (ifw->priv.blost_receiv == 0)
                    ifw->priv.blost_receiv = 1;
            }
        }
        PktFree(pkt);
    }
    
    return 1;
}
コード例 #9
0
ファイル: ipp.c プロジェクト: Cbrdiv/xplico
static packet* IppDissector(packet *pkt)
{
    http_msg *msg;
    pei *ppei;
    pei_component *cmpn;
    int ind, fd;
    unsigned char buff[IPP_BUFFER_SIZE];
    char *pcl_file, *pdf_file;
    char cmd[IPP_FILENAME_PATH_SIZE*2];
    ssize_t len;
    unsigned int offset;
    ipp_ver ver;
    FILE *pcl;
    struct stat fst;

    ppei = NULL;

    /* display info */
    msg = (http_msg *)pkt->data;
    LogPrintf(LV_DEBUG, "IPP Dissector");
    
#ifdef XPL_CHECK_CODE
    if (msg->serial == 0) {
        LogPrintf(LV_FATAL, "IPP Dissector serial error");
        exit(-1);
    }
#endif

    /* check if post and if PCL file */
    if (msg->mtd != HTTP_MT_POST || msg->req_body_size == 0) {
        /* free memory */
        HttpMsgRemove(msg);
        HttpMsgFree(msg);
        PktFree(pkt);
        
        return NULL;
    }
    
    /* open body file */
    fd = open(msg->req_body_file, O_RDONLY);
    if (fd == 0) {
        LogPrintf(LV_ERROR, "Can't open file:%s", msg->req_body_file);
        /* free memory */
        HttpMsgRemove(msg);
        HttpMsgFree(msg);
        PktFree(pkt);
        
        return NULL;
    }
    len = read(fd, buff, IPP_BUFFER_SIZE);
    offset = 0;

    /* IPP version */
    if (buff[0] == 1) {
        if (buff[1] == 0) {
            ver = IPP_1_0;
        }
        else if (buff[1] == 1) {
            ver = IPP_1_1;
        }
        else {
            LogPrintf(LV_WARNING, "Unknow version: %u.%u", buff[0], buff[1]);
            close(fd);
            /* free memory */
            HttpMsgRemove(msg);
            HttpMsgFree(msg);
            PktFree(pkt);
            
            return NULL;
        }
    }
    else {
        LogPrintf(LV_WARNING, "Unknow version: %u.%u", buff[0], buff[1]);
        close(fd);
        /* free memory */
        HttpMsgRemove(msg);
        HttpMsgFree(msg);
        PktFree(pkt);
        
        return NULL;
    }
    offset += 2;
    /* check if print job */
    if (ntohs(*((unsigned short *)(buff+offset))) != PRINT_JOB) {
        close(fd);
        /* free memory */
        HttpMsgRemove(msg);
        HttpMsgFree(msg);
        PktFree(pkt);
        
        return NULL;
    }
    offset += 2;
    offset += 4; /* skeep request id */
#warning "to improve"
    offset = ParseAttributes(buff, offset, len); /* i hope that IPP_BUFFER_SIZE is alwayse correct */

    /* create PCL file */
    pcl_file = DMemMalloc(IPP_FILENAME_PATH_SIZE);
    pdf_file = DMemMalloc(IPP_FILENAME_PATH_SIZE);
    sprintf(pcl_file, "%s/%s/ipp_%lu_%p_%i.pcl", ProtTmpDir(), IPP_TMP_DIR,
            time(NULL), msg, incr);
    sprintf(pdf_file, "%s/%s/ipp_%lu_%p_%i.pdf", ProtTmpDir(), IPP_TMP_DIR,
            time(NULL), msg, incr);
    incr++;
               
    pcl = fopen(pcl_file, "w+");
    fwrite(buff+offset, 1, len-offset, pcl);
    len = read(fd, buff, IPP_BUFFER_SIZE);
    while (len != 0) {
        fwrite(buff, 1, len, pcl);
        len = read(fd, buff, IPP_BUFFER_SIZE);
    }
    fclose(pcl);
    close(fd);

    /* pdf conversion */
    sprintf(cmd, "%s -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=%s %s", pcl6_path, pdf_file, pcl_file);
    system(cmd);
    fst.st_size = 0;
    stat(pdf_file, &fst);

    /* compose pei */
    ppei = DMemMalloc(sizeof(pei));
    PeiInit(ppei);
    ppei->prot_id = prot_id;
    ppei->serial = pkt->serial;
    ppei->time_cap = pkt->cap_sec;
    ppei->stack = ProtCopyFrame(pkt->stk, TRUE);
    /*   url */
    ind = 0;
    cmpn = DMemMalloc(sizeof(pei_component));
    memset(cmpn, 0, sizeof(pei_component));
    cmpn->eid = pei_url_id;
    cmpn->id = ind;
    cmpn->time_cap = msg->start_cap;
    cmpn->time_cap_end = msg->end_cap;
    cmpn->strbuf = msg->uri;
    msg->uri = NULL;
    ppei->components = cmpn;
    /*   pdf */
    ind++;
    cmpn->next = DMemMalloc(sizeof(pei_component));
    cmpn = cmpn->next;
    memset(cmpn, 0, sizeof(pei_component));
    cmpn->eid = pei_pdffile_id;
    cmpn->id = ind;
    cmpn->time_cap = msg->start_cap;
    cmpn->time_cap_end = msg->end_cap;
    cmpn->file_path = pdf_file;
    cmpn->file_size = fst.st_size;
    if (msg->error)
        cmpn->err = ELMT_ER_PARTIAL;
    /*   pcl */
    ind++;
    cmpn->next = DMemMalloc(sizeof(pei_component));
    cmpn = cmpn->next;
    memset(cmpn, 0, sizeof(pei_component));
    cmpn->eid = pei_pclfile_id;
    cmpn->id = ind;
    cmpn->time_cap = msg->start_cap;
    cmpn->time_cap_end = msg->end_cap;
    cmpn->file_path = pcl_file;
    cmpn->file_size = msg->req_body_size - offset;
    if (msg->error)
        cmpn->err = ELMT_ER_PARTIAL;

    /* free memory */
    HttpMsgRemove(msg);
    HttpMsgFree(msg);
    PktFree(pkt);
    
    /* insert pei */
    PeiIns(ppei);

    return NULL;
}
コード例 #10
0
ファイル: syslog.c プロジェクト: Cbrdiv/xplico
static packet *SyslogDissector(int flow_id)
{
    packet *pkt;
    const pstack_f *udp, *ip;
    const char *msg;
    ftval val;
    char file_log[SYSLOG_FILENAME_PATH_SIZE];
    char host[SYSLOG_FILENAME_PATH_SIZE];
    pei *ppei;
    pei_component *cmpn;
    time_t cap_sec, end_cap;
    int cntpkt, len;
    short pri, fac, sev;
    FILE *fp;
    
    ppei = NULL;
    LogPrintf(LV_DEBUG, "Syslog id: %d", flow_id);
    cntpkt = 0;

    /* ip version and number */
    udp = FlowStack(flow_id); /* udp frame */
    ip = ProtGetNxtFrame(udp); /* ip/ipv6 frame */

    ProtStackFrmDisp(udp, TRUE);

    /* host */
    len = 0;
    if (ProtFrameProtocol(ip) == ip_id) {
        ProtGetAttr(ip, ip_src_id, &val);
        if (DnsDbSearch(&val, FT_IPv4, host+len, SYSLOG_FILENAME_PATH_SIZE - len) != 0) {
            FTString(&val, FT_IPv4, host+len);
        }
        len = strlen(host);
        host[len++] = ' ';
        host[len++] = '-';
        host[len++] = ' ';
        ProtGetAttr(ip, ip_dst_id, &val);
        if (DnsDbSearch(&val, FT_IPv4, host+len, SYSLOG_FILENAME_PATH_SIZE - len) != 0) {
            FTString(&val, FT_IPv4, host+len);
        }
    }
    else {
        ProtGetAttr(ip, ipv6_src_id, &val);
        if (DnsDbSearch(&val, FT_IPv6, host+len, SYSLOG_FILENAME_PATH_SIZE - len) != 0) {
            FTString(&val, FT_IPv6, host+len);
        }
        host[len++] = ' ';
        host[len++] = '-';
        host[len++] = ' ';
        ProtGetAttr(ip, ipv6_dst_id, &val);
        if (DnsDbSearch(&val, FT_IPv6, host+len, SYSLOG_FILENAME_PATH_SIZE - len) != 0) {
            FTString(&val, FT_IPv6, host+len);
        }
    }
    len = strlen(host);

    /* syslog file */
    sprintf(file_log, "%s/%s/syslog_%p_%lu.log", ProtTmpDir(), SYSLOG_TMP_DIR, file_log,incr++);
    fp = fopen(file_log, "w");
    
    /* first packet */
    pkt = FlowGetPkt(flow_id);
    if (pkt != NULL) {
        /* pei definition */
        PeiNew(&ppei, prot_id);
        PeiCapTime(ppei, pkt->cap_sec);
        PeiMarker(ppei, pkt->serial);
        PeiStackFlow(ppei, udp);
        cap_sec = pkt->cap_sec;
    }
    if (fp != NULL) {
        while (pkt != NULL) {
            cntpkt++;
            end_cap = pkt->cap_sec;
            pri = SyslogPri(pkt->data, pkt->len);
            if (pri != -1) {
                msg = SyslogMsg(pkt->data, pkt->len);
                if (msg != NULL) {
                    sev = pri & 0x07;
                    fac = pri >> 3;
                    fprintf(fp, "{%s.%s} %s", facility[fac], severity[sev], msg);
                }
            }
            
            PktFree(pkt);
            pkt = FlowGetPkt(flow_id);
        }
コード例 #11
0
ファイル: ip.c プロジェクト: shineit/wifimanage
static packet* IpDissector(packet *pkt)
{
    pstack_f *frame;
    ftval val;
    struct iphdr *ip;
    unsigned short checksum_v;
    size_t iphdr_len;
    size_t ip_len;

    if (sizeof(struct iphdr) > pkt->len) {
        LogPrintf(LV_WARNING, "IP hedear packet dimension overflow the real dimension of packet");
        ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }

    ip = (struct iphdr *)pkt->data;
    /* IPv- or IPv4 */
    if (ip->version != 4) {
        if (ip->version == 6 && ipv6_id != -1)
            return ProtDissecPkt(ipv6_id, pkt);

        LogPrintf(LV_WARNING, "IP verision %i without dissector", ip->version);
        ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }
    /* IPv4 */
    iphdr_len = ip->ihl << 2;
    ip_len = ntohs(ip->tot_len);

    /* check consistence and checksum */
    if (ip_len > pkt->len) {
        //LogPrintf(LV_WARNING, "IP packet dimension overflow the real dimension of packet (%i>%i)", ip_len, pkt->len);
        LogPrintf(LV_WARNING, "IP packet dimension overflow the real dimension of packet");
        ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }

#if (XPL_DIS_IP_CHECKSUM == 0)
    if (ip_len <= iphdr_len) {
        LogPrintf(LV_WARNING, "Bogus IP length (%i, less than header length 20)", ip_len);
        ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }
    checksum_v = ip_fast_csum((unsigned char *)ip, ip->ihl);
    if (checksum_v != 0) {
        LogPrintf(LV_WARNING, "IP packet chechsum error (0x%x != 0x%x)", checksum_v, ip->check);
        //ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }
#else 
    if (ip_len <= iphdr_len) {
        ip_len = pkt->len;
    }
#endif
    
    /* fragment ip */
    if (ip->frag_off != 0 && ip->frag_off != 0x40) {
#warning we have to be implement the fragment ip
        LogPrintf(LV_WARNING, "IP packet fragment 0x%x (%i)", ip->frag_off, ntohs(ip->frag_off)<<3);
        ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);
        return NULL;
    }

    /* new frame */
    frame = ProtCreateFrame(prot_id);
    ProtSetNxtFrame(frame, pkt->stk);
    pkt->stk = frame;

    /* set attribute */
    val.uint8 = ip->protocol;
    ProtInsAttr(frame, proto_id, &val);
#ifdef XPL_X86
    val.uint32 = ip->saddr;
#else
    val.uint32 = Emb32(&ip->saddr);
#endif
    ProtInsAttr(frame, src_id, &val);
#ifdef XPL_X86
    val.uint32 = ip->daddr;
#else
    val.uint32 = Emb32(&ip->daddr);
#endif
    ProtInsAttr(frame, dst_id, &val);
    val.uint32 = (pkt->data - pkt->raw);
    ProtInsAttr(frame, offset_id, &val);
#if SNIFFER_EVASION
    val.uint8 = ip->ttl;
    ProtInsAttr(frame, ttl_id, &val);
    val.uint16 = ntohs(ip->id);
    ProtInsAttr(frame, id_id, &val);
#endif

    /* pdu */
    pkt->data += iphdr_len;
    pkt->len = ip_len - iphdr_len;

    return pkt;
}
コード例 #12
0
ファイル: rtp.c プロジェクト: shineit/wifimanage
static packet* RtpDissector(int flow_id)
{
    struct in_addr ip_addr;
    struct in6_addr ipv6_addr;
    const pstack_f *udp, *ip;
    ftval port_src, port_dst, offset, phone;
    char ips_str[INET6_ADDRSTRLEN], ipd_str[INET6_ADDRSTRLEN];
    rtp_priv *priv;
    packet *pkt;
    int rid, ret, gid, rtcp_fid;
    cmp_val rip, rport;
    char tmp_file_1[256];
    char tmp_file_2[256];
    char media_file_1[256];
    char media_file_2[256];
    char media_conv[256];
    FILE *fp_pcap_1, *fp_pcap_2, *fp_pcap;
    struct pcap_file_header fh;
    struct pcappkt_hdr pckt_header;
    struct stat fsbuf;
    char cmd[1024];
    size_t nwrt, wcnt;
    time_t tstart, tend;
    pei *ppei;
    pei_component *cmpn;
    bool aud1, aud2;
    unsigned short pkt_cnt;
    
    LogPrintf(LV_DEBUG, "RTP id: %d", flow_id);

    gid = FlowGrpId(flow_id);
    priv = DMemMalloc(sizeof(rtp_priv));
    memset(priv, 0, sizeof(rtp_priv));
    udp = FlowStack(flow_id);
    ip = ProtGetNxtFrame(udp);
    ProtGetAttr(udp, uport_src_id, &port_src);
    ProtGetAttr(udp, uport_dst_id, &port_dst);
    priv->port_s = port_src.uint16;
    priv->port_d = port_dst.uint16;
    priv->stack = udp;
    if (priv->port_s != port_dst.uint16)
        priv->port_diff = TRUE;
    priv->ipv6 = TRUE;
    if (ProtFrameProtocol(ip) == ip_id)
        priv->ipv6 = FALSE;
    
    if (priv->ipv6 == FALSE) {
        ProtGetAttr(ip, ip_src_id, &priv->ip_s);
        ProtGetAttr(ip, ip_dst_id, &priv->ip_d);
        ip_addr.s_addr = priv->ip_s.uint32;
        inet_ntop(AF_INET, &ip_addr, ips_str, INET6_ADDRSTRLEN);
        ip_addr.s_addr = priv->ip_d.uint32;
        inet_ntop(AF_INET, &ip_addr, ipd_str, INET6_ADDRSTRLEN);
    }
    else {
        ProtGetAttr(ip, ipv6_src_id, &priv->ip_s);
        ProtGetAttr(ip, ipv6_dst_id, &priv->ip_d);
        memcpy(ipv6_addr.s6_addr, priv->ip_s.ipv6, sizeof(priv->ip_s.ipv6));
        inet_ntop(AF_INET6, &ipv6_addr, ips_str, INET6_ADDRSTRLEN);
        memcpy(ipv6_addr.s6_addr, priv->ip_d.ipv6, sizeof(priv->ip_d.ipv6));
        inet_ntop(AF_INET6, &ipv6_addr, ipd_str, INET6_ADDRSTRLEN);
    }
    LogPrintf(LV_DEBUG, "\tSRC: %s:%d", ips_str, port_src.uint16);
    LogPrintf(LV_DEBUG, "\tDST: %s:%d", ipd_str, port_dst.uint16);
    
    /* RTCP flow search */
    rid = -1;
    rtcp_fid = -1;
    if (rtcp_id != -1) {
        rid = GrpRuleNew(flow_id);
        if (priv->ipv6 == TRUE) {
            rip.prot = ipv6_id;
            rip.att = ipv6_dst_id;
            FTCopy(&rip.val, &priv->ip_d, FT_IPv6);
        }
        else {
            rip.prot = ip_id;
            rip.att = ip_dst_id;
            rip.val.uint32 = priv->ip_d.uint32;
        }
        rport.prot = udp_id;
        rport.att = uport_dst_id;
        port_dst.uint16++;
        rport.val.int16 = port_dst.uint16;
        GrpRule(rid, 2, &rip, &rport);
        if (priv->ipv6 == TRUE) {
            rip.att = ipv6_src_id;
        }
        else {
            rip.att = ip_src_id;
        }
        rport.att = uport_src_id;
        GrpRule(rid, 2, &rip, &rport);
        GrpRuleCmplt(rid);
        LogPrintf(LV_DEBUG, "Rule rtcp %i, port:%i", rid, port_dst.uint16);
    }
    
    /* put packets in the pcap files */
    sprintf(tmp_file_1, "%s/%s/rtp_1_%d_%lu_%d.pcap", ProtTmpDir(), RTP_TMP_DIR, incr, time(NULL), port_src.uint16);
    sprintf(tmp_file_2, "%s/%s/rtp_2_%d_%lu_%d.pcap", ProtTmpDir(), RTP_TMP_DIR, incr, time(NULL), port_src.uint16);
    sprintf(media_conv, "%s/%s/rtp_%d_%lu_%d", ProtTmpDir(), RTP_TMP_DIR, incr, time(NULL), port_src.uint16);
    incr++;

    fp_pcap_1 = fopen(tmp_file_1, "w");
    fp_pcap_2 = fopen(tmp_file_2, "w");
    memset(&fh, 0, sizeof(struct pcap_file_header));
    fh.magic = 0xA1B2C3D4;
    fh.version_major = PCAP_VERSION_MAJOR;
    fh.version_minor = PCAP_VERSION_MINOR;
    fh.snaplen = 65535;
    fh.linktype = DLT_RAW;
    if (fp_pcap_1 != NULL) {
        fwrite((char *)&fh, 1, sizeof(struct pcap_file_header), fp_pcap_1);
    }
    if (fp_pcap_2 != NULL) {
        fwrite((char *)&fh, 1, sizeof(struct pcap_file_header), fp_pcap_2);
    }

    /* first packet */
    pkt_cnt = 0;
    pkt = FlowGetPkt(flow_id);
    /* start time */
    if (pkt != NULL) {
        /* pei definition */
        PeiNew(&ppei, rtp_id);
        PeiCapTime(ppei, pkt->cap_sec);
        PeiMarker(ppei, pkt->serial);
        PeiStackFlow(ppei, udp);
        tstart = pkt->cap_sec;
    }
    while (pkt != NULL) {
        pkt_cnt++;
        /* check if exit rtcp "stream" */
        if (rid != -1) {
            rtcp_fid = GrpLink(gid);
            if (rtcp_fid != -1) {
                FlowSyncr(flow_id, FALSE);
                FlowSyncr(rtcp_fid, FALSE);
                PeiAddStkGrp(ppei, FlowStack(rtcp_fid));
                rid = -1;
            }
        }

        tend = pkt->cap_sec;
        if (priv->ipv6) {
            ip = ProtStackSearchProt(pkt->stk, ipv6_id);
            ProtGetAttr(ip, ipv6_offset_id, &offset);
            wcnt = offset.uint32;
        }
        else {
            ip = ProtStackSearchProt(pkt->stk, ip_id);
            ProtGetAttr(ip, ip_offset_id, &offset);
            wcnt = offset.uint32;
        }
        pckt_header.caplen = pkt->raw_len - wcnt;
        pckt_header.len = pkt->raw_len - wcnt;
        pckt_header.tv_sec = pkt->cap_sec;
        pckt_header.tv_usec = pkt->cap_usec;
        if (RtpClientPkt(priv, pkt)) {
            fp_pcap = fp_pcap_1;
        }
        else {
            fp_pcap = fp_pcap_2;
        }
        if (fp_pcap != NULL) {
            wcnt = 0;
            do {
                nwrt = fwrite(((char *)&pckt_header)+wcnt, 1, sizeof(struct pcappkt_hdr)-wcnt, fp_pcap);
                if (nwrt != -1)
                    wcnt += nwrt;
                else
                    break;
            } while (wcnt != sizeof(struct pcappkt_hdr));
        
            wcnt = offset.uint32;
            do {
                nwrt = fwrite(((char *)pkt->raw)+wcnt, 1, pkt->raw_len-wcnt, fp_pcap);
                if (nwrt != -1)
                    wcnt += nwrt;
                else
                    break;
            } while (wcnt != pkt->raw_len);
        }
        PktFree(pkt);
        pkt = FlowGetPkt(flow_id);
    }
    /* close file */
    if (fp_pcap_1 != NULL)
        fclose(fp_pcap_1);
    if (fp_pcap_1 != NULL)
        fclose(fp_pcap_2);
    /* remove rtcp rule */
    if (rid != -1) {
        rtcp_fid = GrpLink(gid);
        if (rtcp_fid != -1) {
            FlowSyncr(flow_id, FALSE);
            FlowSyncr(rtcp_fid, FALSE);
            PeiAddStkGrp(ppei, FlowStack(rtcp_fid));
            rid = -1;
        }
        else {
            GrpRuleRm(rid);
        }
    }
    
    /* decode rtcp packet */
    if (rtcp_fid != -1) {
        /* new priv data */
        priv->port_s++;
        priv->port_d++;
        pkt = FlowGetPkt(rtcp_fid);
        while (pkt != NULL) {
            pkt = ProtDissecPkt(rtcp_id, pkt);
            if (pkt != NULL) {
                ProtGetAttr(pkt->stk, rtcp_phone_id, &phone);
                if (RtcpClientPkt(priv, pkt)) {
                    strcpy(ipd_str, phone.str);
                }
                else {
                    strcpy(ips_str, phone.str);
                }
                PktFree(pkt);
            }
            pkt = FlowGetPkt(rtcp_fid); 
        }
    }

    /* audio decoding */
    sprintf(cmd, "./videosnarf -i %s -o %s 2>/dev/null 1>/dev/null", tmp_file_1, tmp_file_1);
    ret = system(cmd);
    if (ret == -1) {
        LogPrintf(LV_WARNING, "videosnarf failed");
    }
    else if (WEXITSTATUS(ret) != 0) {
        LogPrintf(LV_WARNING, "videosnarf crash");
    }
    sprintf(cmd, "./videosnarf -i %s -o %s 2>/dev/null 1>/dev/null", tmp_file_2, tmp_file_2);
    ret = system(cmd);
    if (ret == -1) {
        LogPrintf(LV_WARNING, "videosnarf failed");
    }
    else if (WEXITSTATUS(ret) != 0) {
        LogPrintf(LV_WARNING, "videosnarf crash");
    }
    /* delete temporary files */
#if DEBUG_RM
    remove(tmp_file_1);
    remove(tmp_file_2);
#endif
    
    /* media file check */
    sprintf(media_file_1, "%s-media-1.wav", tmp_file_1);
    sprintf(media_file_2, "%s-media-1.wav", tmp_file_2);

    /* complete pei */
    /*  from */
    PeiNewComponent(&cmpn, pei_from);
    PeiCompCapTime(cmpn, tstart);
    PeiCompAddStingBuff(cmpn, ipd_str);
    PeiAddComponent(ppei, cmpn);
    /*  to */
    PeiNewComponent(&cmpn, pei_to);
    PeiCompCapTime(cmpn, tstart);
    PeiCompAddStingBuff(cmpn, ips_str);
    PeiAddComponent(ppei, cmpn);
    /*  duration */
    sprintf(cmd, "%lu", tend-tstart);
    PeiNewComponent(&cmpn, pei_duration);
    PeiCompCapTime(cmpn, tstart);
    PeiCompAddStingBuff(cmpn, cmd);
    PeiAddComponent(ppei, cmpn);
    /*  audio from */
    aud2 = FALSE;
    if (stat(media_file_2, &fsbuf) == 0) {
        aud2 = TRUE;
        /* convert to be used with lame */
        sprintf(tmp_file_2, "%s_2.wav", media_conv);
        sprintf(cmd, "sox %s -s %s 2>/dev/null 1>/dev/null", media_file_2, tmp_file_2);
        ret = system(cmd);
#if DEBUG_RM
        remove(media_file_2);
#endif
        /* mp3 conversion */
        sprintf(media_file_2, "%s_2.mp3", media_conv);
        sprintf(cmd, "lame --quiet -h %s %s 2>/dev/null 1>/dev/null", tmp_file_2, media_file_2);
        ret = system(cmd);
        if (ret == -1) {
            LogPrintf(LV_WARNING, "lame failed");
        }
        else if (WEXITSTATUS(ret) != 0) {
            LogPrintf(LV_WARNING, "lame crash (%i): %s", WEXITSTATUS(ret), cmd);
        }
        if (stat(media_file_2, &fsbuf) == 0) {
            PeiNewComponent(&cmpn, pei_audio_from);
            PeiCompCapTime(cmpn, tstart);
            PeiCompCapEndTime(cmpn, tend);
            PeiCompAddFile(cmpn, "audio_caller.mp3", media_file_2, fsbuf.st_size);
            PeiAddComponent(ppei, cmpn);
        }
        sprintf(media_file_2, "%s_stereo_2.wav", media_conv);
        sprintf(cmd, "sox %s -c 2 %s pan 1 2>/dev/null 1>/dev/null", tmp_file_2, media_file_2);
        ret = system(cmd);
#if DEBUG_RM
        remove(tmp_file_2);
#endif
    }
    /*  audio to */
    aud1 = FALSE;
    if (stat(media_file_1, &fsbuf) == 0) {
        aud1 = TRUE;
        /* convert to be used with lame */
        sprintf(tmp_file_1, "%s_1.wav", media_conv);
        sprintf(cmd, "sox %s -s %s 2>/dev/null 1>/dev/null", media_file_1, tmp_file_1);
        ret = system(cmd);
#if DEBUG_RM
        remove(media_file_1);
#endif
        /* mp3 conversion */
        sprintf(media_file_1, "%s_1.mp3", media_conv);
        sprintf(cmd, "lame --quiet -h %s %s 2>/dev/null 1>/dev/null", tmp_file_1, media_file_1);
        ret = system(cmd);
        if (ret == -1) {
            LogPrintf(LV_WARNING, "lame failed");
        }
        else if (WEXITSTATUS(ret) != 0) {
            LogPrintf(LV_WARNING, "lame crash (%i): %s", WEXITSTATUS(ret), cmd);
        }
        if (stat(media_file_1, &fsbuf) == 0) {
            PeiNewComponent(&cmpn, pei_audio_to);
            PeiCompCapTime(cmpn, tstart);
            PeiCompCapEndTime(cmpn, tend);
            PeiCompAddFile(cmpn, "audio_called.mp3", media_file_1, fsbuf.st_size);
            PeiAddComponent(ppei, cmpn);
        }
        sprintf(media_file_1, "%s_stereo_1.wav", media_conv);
        sprintf(cmd, "sox %s -c 2 %s pan -1 2>/dev/null 1>/dev/null", tmp_file_1, media_file_1);
        ret = system(cmd);
#if DEBUG_RM
        remove(tmp_file_1);
#endif
    }
    /*  mix audio */
    if (aud2 || aud1) {
        /* mix two audio files */
        sprintf(tmp_file_1, "%s_mix.wav", media_conv);
        sprintf(tmp_file_2, "%s_mix.mp3", media_conv);
        if (aud1 == FALSE) {
            sprintf(cmd, "sox %s %s 2>/dev/null 1>/dev/null", media_file_2, tmp_file_1);
        }
        else if (aud2 == FALSE) {
            sprintf(cmd, "sox %s %s 2>/dev/null 1>/dev/null", media_file_1, tmp_file_1);
        }
        else {
            sprintf(cmd, "sox -m %s %s -s %s 2>/dev/null 1>/dev/null", media_file_2, media_file_1, tmp_file_1);
        }
        ret = system(cmd);
        if (ret == -1) {
            LogPrintf(LV_WARNING, "sox failed");
        }
        else if (WEXITSTATUS(ret) != 0) {
            LogPrintf(LV_WARNING, "sox mix crash: %s", cmd);
        }       
        /* mp3 conversion */
        sprintf(cmd, "lame --quiet -h %s %s 2>/dev/null 1>/dev/null", tmp_file_1, tmp_file_2);
        ret = system(cmd);
        /* delete temporary files */
#if DEBUG_RM
        remove(media_file_1);
        remove(media_file_2);
        remove(tmp_file_1);
#endif
        if (stat(tmp_file_2, &fsbuf) == 0) {
            PeiNewComponent(&cmpn, pei_audio_mix);
            PeiCompCapTime(cmpn, tstart);
            PeiCompCapEndTime(cmpn, tend);
            PeiCompAddFile(cmpn, "audio_mix.mp3", tmp_file_2, fsbuf.st_size);
            PeiAddComponent(ppei, cmpn);
        }
    }
    /* insert pei */
    PeiIns(ppei);

    /* free */
    DMemFree(priv);
    
    LogPrintf(LV_DEBUG, "RTP... bye bye  fid:%d (pkt:%i)", flow_id, pkt_cnt);

    return NULL;
}
コード例 #13
0
ファイル: httpfd.c プロジェクト: Cbrdiv/xplico
static packet* HttpFdDissector(packet *pkt)
{
    http_msg *msg;
    packet *httppkt;
    pei *ppei;
    pei_component *cmpn;
    char strbuf[HTTPFD_FILE_PATH];
    char new_path[HTTPFD_FILE_PATH];
    char *orig_file, *file_save, *content_type;
    const char *bnd;
    multipart_f *mpfile;
    multipart_f *nxt;
    bool nend;
    unsigned long rbase, rend, rsize;
    
    ppei = NULL;
    mpfile = nxt = NULL;
    nend = FALSE;
    content_type = NULL;
    
    /* display info */
    msg = (http_msg *)pkt->data;
    LogPrintf(LV_DEBUG, "HTTPfd HttpFdDissector");

#ifdef XPL_CHECK_CODE
    if (msg->serial == 0) {
        LogPrintf(LV_FATAL, "HTTPfd HttpFdDissector serial error");
        exit(-1);
    }
#endif

    /* make the HTTP-PEI also for this message */
    if (insert_http == TRUE) {
        httppkt = HttpMsgPktCpy(pkt);
        if (httppkt != NULL) {
            HttpPktDis(httppkt);
        }
    }

    orig_file = msg->res_body_file;
    /* encoding */
    if (msg->content_encoding[1] != NULL) {
        /* compressed */
        sprintf(new_path, "%s.dec", msg->res_body_file);
        FFormatUncompress(msg->content_encoding[1], msg->res_body_file, new_path);
        remove(msg->res_body_file);
        DMemFree(orig_file);
        orig_file = new_path;
    }
    msg->res_body_file = NULL;

    bnd = HttpMsgBodyBoundary(msg, FALSE);
    if (bnd != NULL) {
        mpfile = FFormatMultipart(orig_file, bnd);
        if (orig_file == new_path)
            remove(orig_file);
        //FFormatMultipartPrint(mpfile);
        nxt = mpfile;
        if (mpfile != NULL && mpfile->content_range != NULL)
            nend = TRUE;
    }
    else {
        rbase = msg->rbase;
        rend = msg->rend;
        rsize = msg->rsize;
        file_save = orig_file;
    }
    do {
        if (nxt != NULL) {
            file_save = nxt->file_path;
            nxt->file_path = NULL;
            HttpFdRange(nxt->content_range, &rbase, &rend, &rsize);
            ppei = NULL;
            if (nxt->content_type)
                content_type = nxt->content_type;
            else
                content_type = NULL;
        }
        /* compose pei (to send to manipulator) */
        PeiNew(&ppei, prot_id);
        PeiCapTime(ppei, pkt->cap_sec);
        PeiMarker(ppei, pkt->serial);
        PeiStackFlow(ppei, pkt->stk);
        
        /*   url */
        PeiNewComponent(&cmpn, pei_url_id);
        PeiCompCapTime(cmpn, msg->start_cap);
        PeiCompCapEndTime(cmpn, msg->end_cap);
        PeiCompAddStingBuff(cmpn, msg->uri);
        PeiAddComponent(ppei, cmpn);
        
        /*   file */
        PeiNewComponent(&cmpn, pei_file_id);
        PeiCompCapTime(cmpn, msg->start_cap);
        PeiCompCapEndTime(cmpn, msg->end_cap);
        PeiCompAddFile(cmpn, "Http file", file_save, 0);
        if (msg->error)
            PeiCompError(cmpn, ELMT_ER_PARTIAL);
        PeiAddComponent(ppei, cmpn);
        
        /*   range */
        if (rsize != 0) {
            PeiNewComponent(&cmpn, pei_range_id);
            PeiCompCapTime(cmpn, msg->start_cap);
            PeiCompCapEndTime(cmpn, msg->end_cap);
            sprintf(strbuf, "%lu-%lu/%lu", rbase, rend, rsize);
            PeiCompAddStingBuff(cmpn, strbuf);
            PeiAddComponent(ppei, cmpn);
        }
        
        /* content_type */
        if (content_type != NULL) {
            PeiNewComponent(&cmpn, pei_content_type);
            PeiCompCapTime(cmpn, msg->start_cap);
            PeiCompCapEndTime(cmpn, msg->end_cap);
            PeiCompAddStingBuff(cmpn, content_type);
            PeiAddComponent(ppei, cmpn);
        }
        else {
            if (msg->content_type[1] != NULL) {
                PeiNewComponent(&cmpn, pei_content_type);
                PeiCompCapTime(cmpn, msg->start_cap);
                PeiCompCapEndTime(cmpn, msg->end_cap);
                PeiCompAddStingBuff(cmpn, msg->content_type[1]);
                PeiAddComponent(ppei, cmpn);
            }
            else if (msg->content_type[0] != NULL) {
                PeiNewComponent(&cmpn, pei_content_type);
                PeiCompCapTime(cmpn, msg->start_cap);
                PeiCompCapEndTime(cmpn, msg->end_cap);
                PeiCompAddStingBuff(cmpn, msg->content_type[0]);
                PeiAddComponent(ppei, cmpn);
            }
        }
    
        /* insert pei */
        PeiIns(ppei);
        if (nxt != NULL) {
            do {
                nxt = nxt->nxt;
                if (nxt == NULL) {
                    nend = FALSE;
                    break;
                }
            } while (nxt != NULL && nxt->content_range == NULL);
        }
    } while (nend);

    /* remove file */
    HttpMsgRemove(msg);
    if (mpfile != NULL) {
        FFormatMultipartFree(mpfile);
    }

    /* free memory */
    if (orig_file != new_path)
        msg->res_body_file = orig_file;
    HttpMsgFree(msg);
    PktFree(pkt);

    return NULL;
}
コード例 #14
0
ファイル: mms.c プロジェクト: Cbrdiv/xplico
static packet* MmsDissector(packet *pkt)
{
    http_msg *msg;
    char newname[MMS_BUFFER_SIZE];
    ssize_t len;
    mms_message mms;
    unsigned char *mms_raw;
    FILE *fp;

    /* display info */
    msg = (http_msg *)pkt->data;
    LogPrintf(LV_DEBUG, "MMS Dissector");
    
#ifdef XPL_CHECK_CODE
    if (msg->serial == 0) {
        LogPrintf(LV_FATAL, "MMS Dissector serial error");
        exit(-1);
    }
#endif
    if (msg->error != ELMT_ER_NONE) {
        /* http pei generation and insertion */
        HttpPktDis(pkt);
        return NULL;
    }
    
    /* open body file */
    if (msg->req_body_file != NULL && msg->req_body_size != 0) {
        sprintf(newname, "%s/%s/mms_req_%lu_%i.mms", ProtTmpDir(), MMS_TMP_DIR, time(NULL), incr++);
        rename(msg->req_body_file, newname);
        /* decode */
        MMSInit(&mms);
        fp = fopen(newname, "r");
        if (fp != NULL) {
            mms_raw = xmalloc(msg->req_body_size);
            if (mms_raw != NULL) {
                len = fread(mms_raw, 1, msg->req_body_size, fp);
                mms_raw = MmsUncompress(msg, mms_raw, &len);
                if (len != msg->req_body_size) {
                    /* new file... decompressed */
                    fclose(fp);
                    fp = fopen(newname, "w");
                    fwrite(mms_raw, 1, len, fp);
                }
                MMSDecode(&mms, mms_raw, len, tmp_dir);
                /*MMSPrint(&mms);*/
                MmsToPei(&mms, msg, pkt->stk, newname, msg->req_body_size);
                xfree(mms_raw);
            }
            fclose(fp);
        }
        MMSFree(&mms);
    }
    if (msg->res_body_file != NULL && msg->res_body_size != 0) {
        sprintf(newname, "%s/%s/mms_res_%lu_%i.mms", ProtTmpDir(), MMS_TMP_DIR, time(NULL), incr++);
        rename(msg->res_body_file, newname);
        /* decode */
        MMSInit(&mms);
        fp = fopen(newname, "r");
        if (fp != NULL) {
            mms_raw = xmalloc(msg->res_body_size);
            if (mms_raw != NULL) {
                len = fread(mms_raw, 1, msg->res_body_size, fp);
                mms_raw = MmsUncompress(msg, mms_raw, &len);
                if (len != msg->req_body_size) {
                    /* new file... decompressed */
                    fclose(fp);
                    fp = fopen(newname, "w");
                    fwrite(mms_raw, 1, len, fp);
                }
                MMSDecode(&mms, mms_raw, len, tmp_dir);
                /*MMSPrint(&mms);*/
                MmsToPei(&mms, msg, pkt->stk, newname, msg->res_body_size);
                xfree(mms_raw);
            }
            fclose(fp);
        }
        MMSFree(&mms);
    }

    /* free memory */
    HttpMsgRemove(msg);
    HttpMsgFree(msg);
    PktFree(pkt);

    return NULL;
}
コード例 #15
0
ファイル: telnet.c プロジェクト: shineit/wifimanage
static packet *TelnetDissector(int flow_id)
{
    packet *pkt;
    const pstack_f *tcp, *ip;
    ftval lost, ip_host, port;
    unsigned short port_host;
    bool ipv6;
    long offset, len, size;
    char host[TELNET_FILENAME_PATH_SIZE];
    char user[TELNET_BUF_SIZE];
    char password[TELNET_BUF_SIZE];
    char cmd_file[TELNET_FILENAME_PATH_SIZE];
    FILE *fp;
    char *buf;
    pei *ppei;
    time_t cap_sec, end_cap;
    int cntpkt;

    LogPrintf(LV_DEBUG, "Telnet id: %d", flow_id);
    
    cntpkt = 0;
    /* init (this for each telnet stream) */
    user[0] = '\0';
    password[0] = '\0';
    sprintf(cmd_file, "%s/%s/telnet_%lu_%p_%i.txt", ProtTmpDir(), TELNET_TMP_DIR, time(NULL), cmd_file, incr);
    incr++;
    fp = fopen(cmd_file, "w");
    ipv6 = FALSE;
    buf = DMemMalloc(TELNET_LOGIN_SIZE);
    buf[0] = '\0';
    len = 0;
    
    /* ip version and number */
    tcp = FlowStack(flow_id); /* tcp frame */
    ip = ProtGetNxtFrame(tcp); /* ip/ipv6 frame */
    ProtGetAttr(tcp, port_dst_id, &port);
    port_host = port.uint16;
    if (ProtFrameProtocol(ip) == ipv6_id) {
        ipv6 = TRUE;
    }
    if (ipv6 == FALSE) {
        ProtGetAttr(ip, ip_dst_id, &ip_host);
        if (DnsDbSearch(&(ip_host), FT_IPv4, host, TELNET_FILENAME_PATH_SIZE) != 0) {
            FTString(&(ip_host), FT_IPv4, host);
        }
    }
    else {
        ProtGetAttr(ip, ipv6_dst_id, &ip_host);
        if (DnsDbSearch(&(ip_host), FT_IPv6, host, TELNET_FILENAME_PATH_SIZE) != 0) {
            FTString(&(ip_host), FT_IPv6, host);
        }
    }
    sprintf(host+strlen(host), ":%i", port_host);
    
    /* first packet */
    pkt = FlowGetPkt(flow_id);
    if (pkt != NULL) {
        /* pei definition */
        PeiNew(&ppei, telnet_id);
        PeiCapTime(ppei, pkt->cap_sec);
        PeiMarker(ppei, pkt->serial);
        PeiStackFlow(ppei, tcp);
        cap_sec = pkt->cap_sec;
    }
    while (pkt != NULL) {
        cntpkt++;
        end_cap = pkt->cap_sec;
        offset = 0;
        /* check if there are packet lost */
        ProtGetAttr(pkt->stk, lost_id, &lost);
        //ProtStackFrmDisp(pkt->stk, TRUE); /* this function display the structure of packet stack of this packet */
        if (lost.uint8 == FALSE && pkt->len != 0) {
            /* no packet lost and packet with data */
            /* skip the telnet commands, we are interested only in readable data */
#warning "to do: reassemble telnet message from many tcp packets"
            offset = TelnetSkipCommand((unsigned char *)(pkt->data), (unsigned char *)(pkt->data + pkt->len));
            if (offset < pkt->len) {
                TelnetConvertZeros((unsigned char *)(pkt->data + offset), (unsigned char *)(pkt->data + pkt->len));
                size = pkt->len - offset;
                fwrite(pkt->data + offset, 1, size, fp);
                if (len + size < TELNET_LOGIN_SIZE) {
                    memcpy(buf+len, pkt->data + offset, size);
                    len += size;
                    buf[len] = '\0';
                }
            }
        }
        else if (lost.uint8) {
            fprintf(fp, "-----> xplico: packets lost (size: %lub) <-----", pkt->len);
        }

        /* new/next packet */
        PktFree(pkt);
        pkt = FlowGetPkt(flow_id);
    }

    /* search login */
    buf[TELNET_LOGIN_SIZE - 1] = '\0';
    TelnetLogin(buf, user, password, TELNET_BUF_SIZE);

    /* free memory and close file */
    DMemFree(buf);
    if (fp != NULL) {
        fclose(fp);
    }

    if (len != 0) {
        /* compose pei */
        TelnetPei(ppei, host, user, password, cmd_file, &cap_sec, &end_cap);
        /* insert pei */
        PeiIns(ppei);
    }
    
    LogPrintf(LV_DEBUG, "Telnet... bye bye. (count:%i)", cntpkt);

    return NULL;
}
コード例 #16
0
ファイル: gtp.c プロジェクト: Lingnutter/xplico
static packet *GtpDissector(packet *pkt)
{
    pstack_f *frame;
    ftval val;
    gtphdr *gtp_h;
    unsigned short offset;
    unsigned char neht, nhlen;

    if (pkt->len < GTP_MIN_HEADER_SIZE) {
        LogPrintf(LV_WARNING, "GTP V1 size error");
        PktFree(pkt);
        return NULL;
    }
    
    /* header */
    gtp_h = (gtphdr *)pkt->data;
    /* gtp version */
    if (gtp_h->ver != 1) {
        LogPrintf(LV_WARNING, "GTP version error (ver:%i)", gtp_h->ver);
        GtpPrintHdr(gtp_h);
        //ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);

        return NULL;
    }
    offset = 8;
    if (gtp_h->ext || gtp_h->seq || gtp_h->npdu) {
        offset += 4;
        if (gtp_h->ext) {
            /* decode extension header */
            neht = gtp_h->neht;
            while (neht != 0) {
                nhlen = pkt->data[offset];
                offset += nhlen;
                neht = pkt->data[offset-1];
            }
        }
        //GtpPrintHdr(gtp_h);

        /* new frame */
        frame = ProtCreateFrame(prot_id);
        ProtSetNxtFrame(frame, pkt->stk);
        pkt->stk = frame;
        
        /* set attribute */
        val.uint32 = gtp_h->teid;
        ProtInsAttr(frame, tunnel_id, &val);
        val.uint8 = gtp_h->mtype;
        ProtInsAttr(frame, proto_id, &val);
        
        /* pdu */
        pkt->data += offset;
        pkt->len -= offset;

        //LogPrintf(LV_DEBUG, "data: 0x%x 0x%x", pkt->data[0], pkt->data[1]);

        return pkt;
    }
    
    //ProtStackFrmDisp(pkt->stk, TRUE);
    PktFree(pkt);

    return NULL;

#if 0
    /* gtp version */
    if (gtp_h->ver != 1) {
        LogPrintf(LV_WARNING, "GTP version error (ver:%i)", gtp_h->ver);
        GtpPrintHdr(gtp_h);
        //ProtStackFrmDisp(pkt->stk, TRUE);
        PktFree(pkt);

        return NULL;
    }
    proto_offset += 2;

    /* control message */
    if (gtp_h->t == 1) {
        LogPrintf(LV_DEBUG, "Control message gtp ver:%i ", gtp_h->ver);
        PktFree(pkt);

        return NULL;
    }
    
    /* length */
    if (gtp_h->l == 1) {
        length = ntohs(*(uint16_t *)(pkt->data + proto_offset));
        //LogPrintf(LV_DEBUG, "Length message: %i", length);
        proto_offset += 2;
    }

    /* tunnel and session id */
    tunnel = ntohs(*(uint16_t *)(pkt->data + proto_offset));
    proto_offset += 2;
    session = ntohs(*(uint16_t *)(pkt->data + proto_offset));
    proto_offset += 2;

    /* Ns and Nr fields */
    if (gtp_h->s == 1) {
        LogPrintf(LV_DEBUG, "Ns and Nr fields");
        ProtStackFrmDisp(pkt->stk, TRUE);
        proto_offset += 4;
    }
    
    /* offset size field */
    if (gtp_h->o == 1) {
        offset = ntohs(*(uint16_t *)(pkt->data + proto_offset));
        //ProtStackFrmDisp(pkt->stk, TRUE);
        proto_offset += (offset + 2);
    }
    
    /* new frame */
    frame = ProtCreateFrame(prot_id);
    ProtSetNxtFrame(frame, pkt->stk);
    pkt->stk = frame;

    /* set attribute */
    val.uint16 = tunnel;
    ProtInsAttr(frame, tunnel_id, &val);
    val.uint16 = session;
    ProtInsAttr(frame, session_id, &val);
    val.uint16 = 3; /* forced to be PPP */
    ProtInsAttr(frame, proto_id, &val);

    /* pdu */
    pkt->data += proto_offset;
    pkt->len -= proto_offset;

    return pkt;
#endif
}
コード例 #17
0
ファイル: flow.c プロジェクト: ZhangLang001/xplico
int FlowDelete(int flow_id)
{
    int ret;
    packet *pkt, *tmp;
    int i, cnt, base;
    int nxt_flw, grp_id;
    freel *ftmp;
    
    FlowTblLock();

    /* check if flow is closed */
    if (flow_tbl[flow_id].close == FALSE) {
        FlowTblUnlock();
        LogPrintf(LV_ERROR, "It is tried to delete an open flow");
        return -1;
    }

    /* close all flows son of this */
    grp_id = flow_tbl[flow_id].grp_id;
    if (grp_id == -1) {
        if (flow_tbl[flow_id].son_num) {
            cnt = 0;
            base = flow_num;
            for (i=0; i<tbl_dim && cnt<base; i++) {
                if (flow_tbl[i].stack != NULL) {
                    cnt++;
                    if (flow_tbl[i].pfid == flow_id) {
                        FlowClose(i);
                        flow_tbl[i].pfid = -1; /* parent terminated */
                    }
                }
            }
        }
    }
    else if (GrpFlowNum(grp_id) == 1) {
        /* last flow of this group (the thread flow is terminated!) */
        cnt = 0;
        base = flow_num;
        for (i=0; i<tbl_dim && cnt<base; i++) {
            if (flow_tbl[i].stack != NULL) {
                cnt++;
                if (flow_tbl[i].pgrp_id == grp_id) {
                    FlowClose(i);
                    flow_tbl[i].pfid = -1; /* parent terminated */
                    flow_tbl[i].pgrp_id = -1; /* parent terminated */
                }
            }
        }
    }

    /* parent son counter */
    if (flow_tbl[flow_id].pfid != -1) {
        flow_tbl[flow_tbl[flow_id].pfid].son_num--;
    }

    /* count the packet from protocol node to protocol dissector */
#ifdef XPL_PEDANTIC_STATISTICS
    if (flow_tbl[flow_id].proto_id != -1 && flow_tbl[flow_id].proto_id != flow_tbl[flow_id].pfid) {
        ProtPktFromNode(flow_tbl[flow_id].proto_id, flow_tbl[flow_id].pkt_tot);
    }
#endif

    /* remove all (grp) rules created by this flow */
    GrpRuleRmAll(flow_id);

    /* check if flow have packet in the queue */
    pthread_mutex_lock(flow_tbl[flow_id].mux);
    if (flow_tbl[flow_id].pkt_num != 0) {
        if (flow_tbl[flow_id].elab == TRUE) {
            LogPrintf(LV_WARNING, "Deleted a flow with %d packet in queue", flow_tbl[flow_id].pkt_num);
            ProtStackFrmDisp(FlowStack(flow_id), TRUE);
        }
        pkt = flow_tbl[flow_id].fpkt;
        
        /* free all packet */
#ifndef XPL_CHECK_CODE
        PktFree(pkt); /* recursive */
        pkt = NULL;
#else
        while (pkt != NULL) {
            tmp = pkt;
            pkt = pkt->next;
            tmp->next = NULL;
            PktFree(tmp);
            flow_tbl[flow_id].pkt_num--;
        }
        if (flow_tbl[flow_id].pkt_num != 0) {
            LogPrintf(LV_OOPS, "bug in pkt flow counter");
        }
#endif
    }

    pthread_mutex_unlock(flow_tbl[flow_id].mux);

    /* thread */
    if (flow_tbl[flow_id].elab == TRUE) {
        if (flow_tbl[flow_id].grp_id == -1) {
            ProtRunFlowDec(flow_tbl[flow_id].proto_id);
            FthreadChFlow(flow_tbl[flow_id].fthd_id, -1);
        }
        else {
            if (FthreadFlow(flow_tbl[flow_id].fthd_id) == flow_id) {
                GrpLock(flow_tbl[flow_id].grp_id);
                do {
                    nxt_flw = GrpNext(flow_tbl[flow_id].grp_id);
                } while (nxt_flw != -1 && nxt_flw == flow_id);
                GrpUnlock(flow_tbl[flow_id].grp_id);
#ifndef PROT_GRP_COUNT
                if (nxt_flw == -1) {
                    ProtRunFlowDec(flow_tbl[flow_id].proto_id);
                }
#else
                ProtRunFlowDec(flow_tbl[flow_id].proto_id);
#endif
                FthreadChFlow(flow_tbl[flow_id].fthd_id, nxt_flw);
            }
            else {
#ifdef PROT_GRP_COUNT
                ProtRunFlowDec(flow_tbl[flow_id].proto_id);
#endif
            }
        }
    }

    /* remove from grp */
    if (flow_tbl[flow_id].grp_id != -1) {
        ret = GrpRm(flow_tbl[flow_id].grp_id, flow_id);
#ifdef XPL_CHECK_CODE
        if (ret == -1) {
            LogPrintf(LV_OOPS, "bug in Grp Add/Rm use");
        }
#endif
    }

    /* stack */
    ProtDelFrame(flow_tbl[flow_id].stack);

    /* reset flow cel */
    FlowElemInit(flow_tbl+flow_id, TRUE);
    
    ftmp = xmalloc(sizeof(freel));
    ftmp->id = flow_id;
    ftmp->nxt = ffree;
    ffree = ftmp;
    ffree_num++;
    
    flow_num--;

    FlowTblUnlock();

    return 0;
}
コード例 #18
0
ファイル: tcp_analysis.c プロジェクト: M0Rf30/xplico
static int TcpCaDisFlow(tca_flow *ifw, packet *pkt)
{
    ftval lost, syn;
    bool clnt, ins;
    
    clnt = TcpCaClientPkt(&ifw->priv, pkt);
    ifw->flow_size += pkt->len;
    //ProtStackFrmDisp(pkt->stk, TRUE);
    ProtGetAttr(pkt->stk, lost_id, &lost);
    if (lost.uint8 == FALSE) {
        ins = TRUE;
        /* data */
        if (pkt->len != 0) {
            if (clnt) {
                ifw->priv.bsent += pkt->len;
                ifw->priv.pkt_sent++;
            }
            else {
                ifw->priv.breceiv += pkt->len;
                ifw->priv.pkt_receiv++;
            }
        }
        else {
            ProtGetAttr(pkt->stk, syn_id, &syn);
            if (clnt) {
                if (syn.uint8 == TRUE) {
                    if (ifw->syn_clt == FALSE)
                        ifw->syn_clt = TRUE;
                    else
                        ins = FALSE;
                }
            }
            else {
                if (syn.uint8 == TRUE) {
                    if (ifw->syn_srv == FALSE)
                        ifw->syn_srv = TRUE;
                    else
                        ins = FALSE;
                }
            }
        }
        ifw->count++;
        ifw->end_cap = pkt->cap_sec;
        
        /* protocol type -ndpi- */
        if (ifw->stage != 4 && (ifw->l7prot_type == NULL || ifw->l7prot_id.master_protocol == NDPI_PROTOCOL_HTTP) && ifw->l7flow != NULL && ins == TRUE) {
            if (clnt) {
                ifw->l7prot_id = nDPIPacket(pkt, ifw->l7flow, ifw->l7src, ifw->l7dst, ifw->priv.ipv6);
            }
            else {
                ifw->l7prot_id = nDPIPacket(pkt, ifw->l7flow, ifw->l7dst, ifw->l7src, ifw->priv.ipv6);
            }
            if (ifw->l7prot_id.protocol != NDPI_PROTOCOL_UNKNOWN) {
                ifw->stage++;
                ifw->l7prot_type = ndpi_protocol2name(ndpi, ifw->l7prot_id, ifw->buff, TCP_CA_LINE_MAX_SIZE);
            }
        }
#ifdef XPL_CHECK_CODE
        if (pkt->raw_len != 0 && ((pkt->raw + pkt->raw_len) < pkt->data)) {
            LogPrintf(LV_OOPS, "TCP data location error %p %p %lu %lu", pkt->raw, pkt->data, pkt->raw_len, pkt->len);
            ProtStackFrmDisp(pkt->stk, TRUE);
            exit(-1);
        }
        if (pkt->raw_len != 0 && (pkt->data + pkt->len) > (pkt->raw + pkt->raw_len)) {
            LogPrintf(LV_OOPS, "TCP data dim error %p %p %lu %lu", pkt->raw, pkt->data, pkt->raw_len, pkt->len);
            ProtStackFrmDisp(pkt->stk, TRUE);
            exit(-1);
        }
#endif
    }
    else {
#if CA_CHECK_LOST
        LogPrintf(LV_WARNING, "Packet Lost (size:%lu)", pkt->len);
        ProtStackFrmDisp(pkt->stk, TRUE);
#endif
        if (clnt) {
            ifw->priv.blost_sent += pkt->len;
            if (ifw->priv.blost_sent == 0)
                ifw->priv.blost_sent = 1;
        }
        else {
            ifw->priv.blost_receiv += pkt->len;
            if (ifw->priv.blost_receiv == 0)
                ifw->priv.blost_receiv = 1;
        }
    }
        
    PktFree(pkt);

    return 0;
}
コード例 #19
0
ファイル: rtp.c プロジェクト: shineit/wifimanage
static bool RtpCheck(int flow_id)
{
    const pstack_f *ip;
    packet *pkt;
    bool ret;
    ftval ips, ipx, port;
    bool ipv4, cmp;
    int pt_1, pt_2;
    unsigned int ssrc_1, ssrc_2;
    int cnt, ecnt;
    rtp_hdr *rtp;
    unsigned short min_size;

    if (FlowPktNum(flow_id) < RTP_PKT_LIMIT && FlowIsClose(flow_id) == FALSE) {
        return FALSE;
    }

    ipv4 = FALSE;
    ret = FALSE;
    cnt = ecnt = 0;

    pkt = FlowGetPktCp(flow_id);
    if (pkt != NULL) {
        /* check port */
        ProtGetAttr(pkt->stk, uport_dst_id, &port);
        if (port.uint16 < 1024) {
            PktFree(pkt);
            return FALSE;
        }
        ProtGetAttr(pkt->stk, uport_src_id, &port);
        if (port.uint16 < 1024) {
            PktFree(pkt);
            return FALSE;
        }
        /* check ip */
        ip = ProtGetNxtFrame(pkt->stk);
        if (ProtFrameProtocol(ip) == ip_id)
            ipv4 = TRUE;
        if (ipv4 == TRUE)
            ProtGetAttr(ip, ip_src_id, &ips);
        else
            ProtGetAttr(ip, ipv6_src_id, &ips);
        while (pkt->len == 0) {
            PktFree(pkt);
            pkt = FlowGetPktCp(flow_id);
            if (pkt == NULL)
                break;
        }
    }
    if (pkt != NULL) {
        pt_1 = pt_2 = -1;
        do {
            if (pkt->len > sizeof(rtp_hdr)) {
                rtp = (rtp_hdr *)pkt->data;
                if (rtp->version != 2) {
                    cnt = 0;
                    ecnt++;
                }
                else {
                    ip = ProtGetNxtFrame(pkt->stk);
                    if (ipv4 == TRUE) {
                        ProtGetAttr(ip, ip_src_id, &ipx);
                        cmp = FTCmp(&ips, &ipx, FT_IPv4, FT_OP_EQ, NULL);
                        if (cmp) {
                            if (pt_1 == -1) {
                                pt_1 = rtp->pt;
                                ssrc_1 = rtp->ssrc;
                            }
                            else if (pt_1 != rtp->pt || ssrc_1 != rtp->ssrc)
                                break;
                        }
                        else {
                            if (pt_2 == -1) {
                                pt_2 = rtp->pt;
                                ssrc_2 = rtp->ssrc;
                            }
                            else if (pt_2 != rtp->pt || ssrc_2 != rtp->ssrc)
                                break;
                        }
                        /* check size */
                        if (rtp->cc != 0) {
                            min_size = rtp->cc * 4; /* every CSRC has 4 byte */
                            min_size += sizeof(rtp_hdr);
                            if (pkt->len < min_size)
                                break;
                        }
                    }
                    else {
                        ProtGetAttr(ip, ipv6_src_id, &ipx);
                        cmp = FTCmp(&ips, &ipx, FT_IPv6, FT_OP_EQ, NULL);
                        if (cmp) {
                            if (pt_1 == -1) {
                                pt_1 = rtp->pt;
                            ssrc_1 = rtp->ssrc;
                            }
                            else if (pt_1 != rtp->pt || ssrc_1 != rtp->ssrc)
                                break;
                        }
                        else {
                            if (pt_2 == -1) {
                                pt_2 = rtp->pt;
                                ssrc_2 = rtp->ssrc;
                            }
                            else if (pt_2 != rtp->pt || ssrc_2 != rtp->ssrc)
                                break;
                        }
                        /* check size */
                        if (rtp->cc != 0) {
                            min_size = rtp->cc * 4; /* every CSRC has 4 byte */
                            min_size += sizeof(rtp_hdr);
                            if (pkt->len < min_size)
                                break;
                        }
                    }
                    cnt++;
                }
            }
            else {
                cnt = 0;
                ecnt++;
            }
            PktFree(pkt);
            pkt = FlowGetPktCp(flow_id);
        } while (ecnt != RTP_PKT_ERR_CHECK && cnt != RTP_PKT_CHECK && pkt != NULL);
    }
    
    if (pkt != NULL) {
        PktFree(pkt);
        pkt = NULL;
    }
    
    if (cnt == RTP_PKT_CHECK) {
        ret = TRUE;
    }

    return ret;
}
コード例 #20
0
ファイル: tcp_garbage.c プロジェクト: Lingnutter/xplico
packet *TcpGrbDissector(int flow_id)
{
    packet *pkt, *opkt;
    tgrb_priv *priv;
    const pstack_f *tcp, *ip;
    ftval port_src, port_dst, lost;
    struct in_addr ip_addr;
    struct in6_addr ipv6_addr;
    char ips_str[INET6_ADDRSTRLEN], ipd_str[INET6_ADDRSTRLEN];
    bool ipv4;
    int dig_s, dig_d, *dig_x;
    int count, i, j, k;
    int threshold;
    bool txt_data;
    FILE *txt_fp;
    char txt_file[TCP_GRB_FILENAME_PATH_SIZE];
    unsigned char *thrs;
    pei *ppei;
    time_t cap_sec, end_cap;
#if GRB_FILE
    int fd_pcap;
    char filename[TCP_GRB_FILENAME_PATH_SIZE];
    int prot;
    struct pcap_file_header fh;
    struct pcappkt_hdr pckt_header;
#endif
    size_t flow_size;
    bool first_lost, dig_end;
    dig *dig_srch_a, *dig_srch_b, *dig_srch;
    char buff[TCP_CFG_LINE_MAX_SIZE];
    char *l7prot_type;
    struct ndpi_flow_struct *l7flow;
    struct ndpi_id_struct *l7src, *l7dst;
    ndpi_protocol l7prot_id;
    unsigned char stage;
    
    LogPrintf(LV_DEBUG, "TCP garbage id: %d", flow_id);

    /* ndpi init */ 
    l7flow = xcalloc(1, ndpi_flow_struct_size);
    if (l7flow == NULL) {
        LogPrintf(LV_ERROR, "Out of memory");
        l7src = NULL;
        l7dst = NULL;
    }
    else {
        l7src = xcalloc(1, ndpi_proto_size);
        if (l7src != NULL) {
            l7dst = xcalloc(1, ndpi_proto_size);
            if (l7dst == NULL) {
                xfree(l7src);
                xfree(l7flow);
                l7src = NULL;
                l7flow = NULL;
            }
        }
        else {
            xfree(l7flow);
            l7flow = NULL;
            l7dst = NULL;
        }
    }
    
    /* dig init */
    dig_srch_a = dig_srch_b = NULL;
    if (enable_dig) {
        dig_s = dig_d = -1;
        dig_x = NULL;
        dig_srch_a = xmalloc(sizeof(dig) * dig_type_dim);
        dig_srch_b = xmalloc(sizeof(dig) * dig_type_dim);
        if (dig_srch_a != NULL && dig_srch_b != NULL) {
            memset(dig_srch_a, 0, sizeof(dig) * dig_type_dim);
            memset(dig_srch_b, 0, sizeof(dig) * dig_type_dim);
            for (i=0; i!=dig_type_dim; i++) {
                dig_srch_a[i].ft = &(dig_tbl[i]);
                dig_srch_b[i].ft = &(dig_tbl[i]);
                dig_srch_a[i].dig_sync = -1;
                dig_srch_b[i].dig_sync = -1;
            }
        }
        else {
            if (dig_srch_a != NULL)
                xfree(dig_srch_a);
            if (dig_srch_b != NULL)
                xfree(dig_srch_b);
            dig_srch_a = dig_srch_b = NULL;
        }
    }

    /* init */
    priv = DMemMalloc(sizeof(tgrb_priv));
    memset(priv, 0, sizeof(tgrb_priv));
    tcp = FlowStack(flow_id);
    ip = ProtGetNxtFrame(tcp);
    ProtGetAttr(tcp, port_src_id, &port_src);
    ProtGetAttr(tcp, port_dst_id, &port_dst);
    priv->port_s = port_src.uint16;
    priv->port_d = port_dst.uint16;
    priv->stack = tcp;
    if (priv->port_s != port_dst.uint16)
        priv->port_diff = TRUE;
    priv->ipv6 = TRUE;
    ipv4 = FALSE;
    first_lost = FALSE;
    stage = 0;
    if (ProtFrameProtocol(ip) == ip_id) {
        ipv4 = TRUE;
        priv->ipv6 = FALSE;
    }
    if (ipv4) {
        ProtGetAttr(ip, ip_src_id, &priv->ip_s);
        ProtGetAttr(ip, ip_dst_id, &priv->ip_d);
        ip_addr.s_addr = priv->ip_s.uint32;
        inet_ntop(AF_INET, &ip_addr, ips_str, INET6_ADDRSTRLEN);
        ip_addr.s_addr = priv->ip_d.uint32;
        inet_ntop(AF_INET, &ip_addr, ipd_str, INET6_ADDRSTRLEN);
    }
    else {
        ProtGetAttr(ip, ipv6_src_id, &priv->ip_s);
        ProtGetAttr(ip, ipv6_dst_id, &priv->ip_d);
        memcpy(ipv6_addr.s6_addr, priv->ip_s.ipv6, sizeof(priv->ip_s.ipv6));
        inet_ntop(AF_INET6, &ipv6_addr, ips_str, INET6_ADDRSTRLEN);
        memcpy(ipv6_addr.s6_addr, priv->ip_d.ipv6, sizeof(priv->ip_d.ipv6));
        inet_ntop(AF_INET6, &ipv6_addr, ipd_str, INET6_ADDRSTRLEN);    
    }
    LogPrintf(LV_DEBUG, "\tSRC: %s:%d", ips_str, port_src.uint16);
    LogPrintf(LV_DEBUG, "\tDST: %s:%d", ipd_str, port_dst.uint16);
    
    /* file pcap */
#if GRB_FILE
    sprintf(filename, "%s/tcp_%d_grb_%s_%s.pcap", ProtTmpDir(), serial, ips_str, ipd_str);
    serial++;
    fd_pcap = open(filename, O_WRONLY | O_CREAT, 0x01B6);
    memset(&fh, 0, sizeof(struct pcap_file_header));
    fh.magic = 0xA1B2C3D4;
    fh.version_major = PCAP_VERSION_MAJOR;
    fh.version_minor = PCAP_VERSION_MINOR;
    fh.snaplen = 65535;
    if (ProtGetNxtFrame(ip) != NULL) {
        prot = ProtFrameProtocol(ProtGetNxtFrame(ip));
        if (prot == eth_id)
            fh.linktype = DLT_EN10MB;
        else if (prot == ppp_id)
            fh.linktype = DLT_PPP;
        else
            fh.linktype = DLT_RAW;
    }
    if (fd_pcap != -1)
        write(fd_pcap, (char *)&fh, sizeof(struct pcap_file_header));
#endif
    
    l7prot_type = NULL;
    flow_size = 0;
    count = 0;
    opkt = pkt = NULL;
    ppei = NULL;
    txt_data = FALSE;
    txt_fp = NULL;
    threshold = 0;
#if GRB_TXT_ENABLE
    thrs = xmalloc(TCP_GRB_THRESHOLD+1);
#else
    thrs = NULL;
#endif
    do {
        pkt = FlowGetPkt(flow_id);
        if (pkt != NULL) {
            ProtGetAttr(pkt->stk, lost_id, &lost);
            if (lost.uint8 == FALSE) {
                /* create pei */
                PeiNew(&ppei, tcp_grb_id);
                PeiCapTime(ppei, pkt->cap_sec);
                PeiMarker(ppei, pkt->serial);
                PeiStackFlow(ppei, tcp);
                cap_sec = pkt->cap_sec;
                end_cap = pkt->cap_sec;
                break;
            }
            else {
                first_lost = TRUE;
            }
        }
    } while (pkt != NULL);
    while (pkt != NULL) {
        flow_size += pkt->len;
        //ProtStackFrmDisp(pkt->stk, TRUE);
        ProtGetAttr(pkt->stk, lost_id, &lost);
        if (lost.uint8 == FALSE) {
            count++;
            end_cap = pkt->cap_sec;
            /* protocol type -ndpi- */
            if (stage != 4 && (l7prot_type == NULL || l7prot_id.master_protocol == NDPI_PROTOCOL_HTTP) && l7flow != NULL) {
                if (TcpGrbClientPkt(priv, pkt)) {
                    l7prot_id = nDPIPacket(pkt, l7flow, l7src, l7dst, ipv4);
                }
                else {
                    l7prot_id = nDPIPacket(pkt, l7flow, l7dst, l7src, ipv4);
                }
                if (l7prot_id.protocol != NDPI_PROTOCOL_UNKNOWN) {
                    stage++;
                    l7prot_type = ndpi_protocol2name(ndpi, l7prot_id, buff, TCP_CFG_LINE_MAX_SIZE);
                }
            }
#ifdef XPL_CHECK_CODE
            if (pkt->raw_len != 0 && ((pkt->raw + pkt->raw_len) < pkt->data)) {
                LogPrintf(LV_OOPS, "TCP data location error %p %p %lu %lu", pkt->raw, pkt->data, pkt->raw_len, pkt->len);
                ProtStackFrmDisp(pkt->stk, TRUE);
                exit(-1);
            }
            if (pkt->raw_len != 0 && (pkt->data + pkt->len) > (pkt->raw + pkt->raw_len)) {
                LogPrintf(LV_OOPS, "TCP data dim error %p %p %lu %lu", pkt->raw, pkt->data, pkt->raw_len, pkt->len);
                ProtStackFrmDisp(pkt->stk, TRUE);
                exit(-1);
            }
#endif

#if GRB_FILE
            pckt_header.caplen = pkt->raw_len;
            pckt_header.len = pkt->raw_len;
            pckt_header.tv_sec = pkt->cap_sec;
            pckt_header.tv_usec = pkt->cap_usec;
            if (fd_pcap != -1) {
                write(fd_pcap, (char *)&pckt_header, sizeof(struct pcappkt_hdr));
                write(fd_pcap, (char *)pkt->raw, pkt->raw_len);
            }
#endif
        }
        else {
#if GRB_FILE || GRB_CHECK_LOST
            LogPrintf(LV_WARNING, "Packet Lost (size:%lu)", pkt->len);
            ProtStackFrmDisp(pkt->stk, TRUE);
#endif
        }
        if (thrs != NULL) {
            /* check stream to find text */
            if (lost.uint8 == FALSE && pkt->len != 0) {
                if (threshold + pkt->len >= TCP_GRB_THRESHOLD) {
                    if (txt_data == FALSE) {
                        /* text flow */
                        txt_data = TcpGrbMajorityText(thrs, threshold);
                        if (txt_data == FALSE) {
                            xfree(thrs);
                            thrs = NULL;
                            threshold = 0;
                        }
                        else {
                            sprintf(txt_file, "%s/%s/tcp_grb_%lu_%p_%i.txt", ProtTmpDir(), TCP_GRB_TMP_DIR, time(NULL), txt_file, incr++);
                            txt_fp = fopen(txt_file, "w");
                            if (txt_fp != NULL) {
                                TcpGrbText(txt_fp, thrs, threshold);
                                threshold = 0;
                                memcpy(thrs+threshold, pkt->data,  pkt->len);
                                threshold += pkt->len;
                                thrs[threshold] = '\0';
                            }
                            else {
                                LogPrintf(LV_ERROR, "Unable to open file: %s", txt_file);
                                txt_data = FALSE;
                                xfree(thrs);
                                thrs = NULL;
                                threshold = 0;
                            }
                        }
                    }
                    else {
                        TcpGrbText(txt_fp, thrs, threshold);
                        threshold = 0;
                        if (pkt->len > TCP_GRB_THRESHOLD) {
                            TcpGrbText(txt_fp, (unsigned char *)pkt->data, pkt->len);
                        }
                        else {
                            memcpy(thrs+threshold, pkt->data,  pkt->len);
                            threshold += pkt->len;
                        }
                        thrs[threshold] = '\0';
                    }
                }
                else {
                    memcpy(thrs+threshold, pkt->data,  pkt->len);
                    threshold += pkt->len;
                    thrs[threshold] = '\0';
                }
            }
        }

        /* dig */
        if (dig_srch_a != NULL && pkt->len != 0) {
            if (TcpGrbClientPkt(priv, pkt)) {
                dig_srch = dig_srch_a;
                dig_x = &dig_s;
            }
            else {
                dig_srch = dig_srch_b;
                dig_x = &dig_d;
            }

            for (i=0; i!=dig_type_dim; i++) {
#if 0
                if (*dig_x != -1 && *dig_x != dig_srch[i].dig_sync)
                    continue;
#endif
                bool nmatch = FALSE;
                do {
                    if (dig_srch[i].head == FALSE) {
                        if (lost.uint8 == FALSE && (nmatch == TRUE || TcpGrbDigMatchStart(&(dig_srch[i]), pkt) == 1)) {
                            nmatch = FALSE;
                            *dig_x = i;
                            dig_srch[i].head = TRUE;
                            dig_srch[i].dig_sync = i;
                            dig_srch[i].start_cap = pkt->cap_sec;
                            dig_srch[i].serial = pkt->serial;
                            j = 0;
                            k = dig_srch[i].ft->end_id[0];
                            while (k != -1) {
                                dig_srch[k].head = TRUE;
                                dig_srch[k].dig_sync = i;
                                j++;
                                k = dig_srch[i].ft->end_id[j];
                            }
                            /* save file */
                            sprintf(dig_srch[i].filename, "%s/%s/file_%lu%i.%s", ProtTmpDir(), TCP_GRB_TMP_DIR, time(NULL), incr_dig++, dig_srch[i].ft->ename);
                            LogPrintf(LV_DEBUG, "File %s found (%s)", dig_srch[i].ft->ename, dig_srch[i].filename);
                            dig_srch[i].fp = fopen(dig_srch[i].filename, "wb");
                            if (dig_srch[i].fp != NULL) {
                                if (pkt == dig_srch[i].pkt) {
                                    //ProtStackFrmDisp(pkt->stk, TRUE);
                                    dig_srch[i].fsize = pkt->len - dig_srch[i].pkt_offset;
                                    fwrite(pkt->data + dig_srch[i].pkt_offset, 1, dig_srch[i].fsize, dig_srch[i].fp);
                                }
                                else {
                                    if (opkt == dig_srch[i].pkt) {
                                        //ProtStackFrmDisp(pkt->stk, TRUE);
                                        dig_srch[i].fsize = opkt->len - dig_srch[i].pkt_offset;
                                        fwrite(opkt->data + dig_srch[i].pkt_offset, 1, dig_srch[i].fsize, dig_srch[i].fp);
                                    }
                                    else {
                                        LogPrintf(LV_ERROR, "Improve dig code");
                                    }
                                    fwrite(pkt->data, 1, pkt->len, dig_srch[i].fp);
                                    dig_srch[i].fsize = pkt->len;
                                }
                            }
                            dig_srch[i].pkt_offset = 0;
                            dig_srch[i].pkt = NULL;
                        }
                    }
                    else {
                        dig_end = FALSE;
                        if (lost.uint8 == FALSE) {
                            if (dig_srch[i].ft->elen != 0) {
                                if (TcpGrbDigMatchEnd(&(dig_srch[i]), pkt) == 1) {
                                    ProtStackFrmDisp(pkt->stk, TRUE);
                                    dig_end = TRUE;
                                    k = dig_srch[i].dig_sync;
                                    dig_srch[k].fsize += dig_srch[i].pkt_offset + 1;
                                    if (dig_srch[k].fp != NULL) {
                                        fwrite(pkt->data, 1, dig_srch[i].pkt_offset + 1, dig_srch[k].fp);
                                        fclose(dig_srch[k].fp);
                                    }
                                    dig_srch[i].pkt_offset = 0;
                                    dig_srch[i].pkt = NULL;
                                }
                                if (dig_srch[i].ft->stend == TRUE) {
                                    if (TcpGrbDigMatchStart(&(dig_srch[i]), pkt) == 1) {
                                        dig_end = TRUE;
                                        nmatch = TRUE;
                                        k = dig_srch[i].dig_sync;
                                        dig_srch[k].fsize += dig_srch[i].pkt_offset;
                                        if (dig_srch[k].fp != NULL) {
                                            fwrite(pkt->data, 1, dig_srch[i].pkt_offset, dig_srch[k].fp);
                                            fclose(dig_srch[k].fp);
                                        }
                                    }
                                }
                            }
                            if (dig_end == FALSE) {
                                if (dig_srch[i].fsize + pkt->len >= dig_srch[i].ft->msize) {
                                    dig_end = TRUE;
                                    k = dig_srch[i].dig_sync;
                                    if (dig_srch[k].fp != NULL) {
                                        if (lost.uint8 == FALSE)
                                            fwrite(pkt->data, 1, dig_srch[i].ft->msize - dig_srch[i].fsize, dig_srch[k].fp);
                                        fclose(dig_srch[k].fp);
                                        dig_srch[k].fsize = dig_srch[i].ft->msize;
                                    }
                                }
                            }
                            if (dig_end == TRUE) {
                                dig_srch[i].head = FALSE;
                                *dig_x = -1;
                                j = 0;
                                k = dig_srch[i].ft->end_id[0];
                                while (k != -1) {
                                    dig_srch[k].head = FALSE;
                                    if (k != i) {
                                        dig_srch[k].fs = 0;
                                        dig_srch[k].dig_sync = -1;
                                    }
                                    j++;
                                    k = dig_srch[i].ft->end_id[j];
                                }
                                k = dig_srch[i].dig_sync;
                                
                                dig_srch[i].fs = 0;
                                dig_srch[i].dig_sync = -1;
                                LogPrintf(LV_DEBUG, "End file %s (%s)", dig_srch[i].ft->ename, dig_srch[k].filename);
                                dig_srch[k].end_cap = pkt->cap_sec;

                                GrbDigPei(&dig_srch[k], tcp);
                                dig_srch[k].fsize = 0;
                                dig_srch[k].fp = NULL;
                                dig_srch[k].filename[0] = '\0';
                            }
                            else if (i == dig_srch[i].dig_sync) {
                                dig_srch[i].fsize += pkt->len;
                                if (dig_srch[i].fp != NULL) {
                                    if (lost.uint8 == FALSE)
                                        fwrite(pkt->data, 1, pkt->len, dig_srch[i].fp);
                                    else {
                                        char *zero;
                                        zero = xmalloc(pkt->len);
                                        if (zero != NULL) {
                                            memset(zero, 0, pkt->len);
                                            fwrite(zero, 1, pkt->len, dig_srch[i].fp);
                                            xfree(zero);
                                        }
                                    }
                                }
                            }
                        }
                    }
                } while(nmatch == TRUE);
            }
        }
        
        if (opkt != NULL)
            PktFree(opkt);
        opkt = pkt;
        pkt = FlowGetPkt(flow_id);
    }
    if (opkt != NULL) {
        PktFree(opkt);
        opkt = NULL;
    }
    
    /* text flows */
    if (thrs != NULL) {
        if (txt_data == FALSE) {
            /* text flow */
            if (TcpGrbMajorityText(thrs, threshold) == TRUE) {
                sprintf(txt_file, "%s/%s/tcp_grb_%lu_%p_%i.txt", ProtTmpDir(), TCP_GRB_TMP_DIR, time(NULL), txt_file, incr++);
                txt_fp = fopen(txt_file, "w");
            }
        }
        if (txt_fp != NULL) {
            TcpGrbText(txt_fp, thrs, threshold);
        }
        xfree(thrs);
    }
    
    /* ndpi free */
    if (l7flow != NULL) {
        xfree(l7flow);
        xfree(l7src);
        xfree(l7dst);
    }
    if (l7prot_type == NULL)
        l7prot_type = "Unknown";

    /* dig flow */
    for (i=0; i!=dig_type_dim; i++) {
        if (dig_srch_a[i].head == TRUE) {
            if (i == dig_srch_a[i].dig_sync) {
                if (dig_srch_a[i].fp != NULL)
                    fclose(dig_srch_a[i].fp);
                LogPrintf(LV_DEBUG, "End stream of file %s", dig_srch_a[i].ft->ename);
                dig_srch_a[i].end_cap = end_cap;
                GrbDigPei(&dig_srch_a[i], tcp);
                dig_srch_a[i].fsize = 0;
                dig_srch_a[i].fp = NULL;
                dig_srch_a[i].filename[0] = '\0';
            }
        }
        if (dig_srch_b[i].head == TRUE) {
            if (i == dig_srch_b[i].dig_sync) {
                if (dig_srch_b[i].fp != NULL)
                    fclose(dig_srch_b[i].fp);
                LogPrintf(LV_DEBUG, "End stream of file %s", dig_srch_b[i].ft->ename);
                dig_srch_b[i].end_cap = end_cap;
                GrbDigPei(&dig_srch_b[i], tcp);
                dig_srch_b[i].fsize = 0;
                dig_srch_b[i].fp = NULL;
                dig_srch_b[i].filename[0] = '\0';
            }
        }
        
    }
    /* tcp reset */
    if (first_lost && (count < 5 || flow_size == 0)) {
        if (txt_fp != NULL) {
            fclose(txt_fp);
            remove(txt_file);
            txt_fp = NULL;
        }
    }
    else {
        if (txt_fp != NULL) {
            fclose(txt_fp);
            /* insert data */
            GrbPei(ppei, l7prot_type, flow_size, txt_file, &cap_sec, &end_cap);
            /* insert pei */
            PeiIns(ppei);
        }
        else  {
            /* insert data */
            GrbPei(ppei, l7prot_type, flow_size, NULL, &cap_sec, &end_cap);
            /* insert pei */
            PeiIns(ppei);
        }
    }
    /* end */
#if GRB_FILE
    if (fd_pcap != -1)
        close(fd_pcap);
#endif

    if (dig_srch_a != NULL) {
        xfree(dig_srch_a);
        xfree(dig_srch_b);
    }
    DMemFree(priv);

    LogPrintf(LV_DEBUG, "TCP->%s garbage... bye bye  fid:%d count:%i", l7prot_type, flow_id, count);

    return NULL;
}