예제 #1
0
void fifo_service (output_plugin *p, asset *main, serv_asset *service, connection *cxt)
{
    FILE *fd;
    static char sip[INET6_ADDRSTRLEN];
    static char dip[INET6_ADDRSTRLEN];
    char *role = B64_PRADS_CLIENT;
    if(!cxt)
        cxt = &NULL_CXT;

    /* Print to FIFO */
    if (p->data == NULL) {
        elog("[!] ERROR:  File handle not open!\n");
        return;
    }
    fd = (FILE *)p->data;
    /* prads_agent.tcl process each line until it receivs a dot by itself */
    u_ntop(main->ip_addr, main->af, sip);
    u_ntop(cxt->d_ip, cxt->af, dip);
    
    if ( service->role == SC_SERVER ) { /* SERVER ASSET */
        role = B64_PRADS_SERVER;
    }
    fprintf(fd, "01\n%s\n%u\n%s\n%u\n%d\n%d\n%d\n%s\n%s\n%lu\n%s\n.\n",
            sip, htonl(IP4ADDR(&cxt->s_ip)),
            dip, htonl(IP4ADDR(&cxt->d_ip)), 
            ntohs(cxt->s_port), ntohs(cxt->d_port), service->proto, 
            bdata(service->service), bdata(service->application), 
            main->first_seen, role);
    fflush(fd);
}
예제 #2
0
파일: log_file.c 프로젝트: alandekok/prads
/* ----------------------------------------------------------
 * FUNCTION : file_service
 * DESC     : Prints a service asset to the log file.
 * INPUT    : 0 - Main asset
 *          : 1 - Serice asset
 * ---------------------------------------------------------- */
void
file_service (output_plugin* log,asset *main, serv_asset *service, connection *cxt)
{
    if ((FILE*)log->data != NULL) {
        uint8_t tmp_ttl;
        static char ip_addr_s[INET6_ADDRSTRLEN];
        u_ntop(main->ip_addr, main->af, ip_addr_s);
        /* ip,vlan,port,proto,SERVICE,application,timstamp*/
        fprintf((FILE*)log->data, "%s,%u,%d,%d,",
            ip_addr_s, main->vlan ? ntohs(main->vlan) : 0,
            ntohs(service->port),service->proto);
        if (service->role == SC_SERVER) {
            fprintf((FILE*)log->data, "SERVER,[%s:%s]",
                (char*)bdata(service->service),
                (char *)bdata(service->application));
        } else {
            fprintf((FILE*)log->data, "CLIENT,[%s:%s]",
                (char*)bdata(service->service),
                (char*)bdata(service->application));
        }

        tmp_ttl = normalize_ttl(service->ttl);
        fprintf((FILE*)log->data, ",%d,%lu\n",tmp_ttl - service->ttl,service->last_seen);
        fflush((FILE*)log->data);
    } else {
        if(log->flags & CONFIG_VERBOSE )
           elog("[!] ERROR:  File handle not open!\n");
    }
}
예제 #3
0
파일: util.c 프로젝트: awilfox/tethys
void u_cidr_to_str(u_cidr *cidr, char *s)
{
	struct in_addr in;

	in.s_addr = htonl(cidr->addr);
	u_ntop(&in, s);
	s += strlen(s);
	sprintf(s, "/%d", cidr->netsize);
}
예제 #4
0
파일: log_dispatch.c 프로젝트: Ammaro/prads
void log_asset_os (asset *main, os_asset *os, connection *cxt)
{
#ifdef DEBUG
    static char ip_addr_s[INET6_ADDRSTRLEN];
    u_ntop(main->ip_addr, main->af, ip_addr_s);
#ifdef DEBUG_LOG
    dlog("[%lu] Incoming asset, %s: %s:%u [%s]\n",
    os->last_seen, (char*)bdata(os->detection),ip_addr_s,ntohs(os->port),(char*)bdata(os->raw_fp));
#endif
#endif
    log_foo(os, log_output, n_outputs, main, os, cxt);
}
예제 #5
0
파일: log_dispatch.c 프로젝트: Ammaro/prads
void log_asset_service (asset *main, serv_asset *service, connection *cxt)
{
#ifdef DEBUG
    static char ip_addr_s[INET6_ADDRSTRLEN];
    u_ntop(main->ip_addr, main->af, ip_addr_s);
    if (service->role == SC_SERVER ) {
        fprintf(stderr, "[*] new service: %s:%d %s\n",ip_addr_s,ntohs(service->port),(char *)bdata(service->application));
    } else {
        fprintf(stderr, "[*] new client: %s:%d %s\n",ip_addr_s,ntohs(service->port),(char *)bdata(service->application));
    }
#endif
    log_foo(service, log_output, n_outputs, main, service, cxt);
}
예제 #6
0
파일: cxt.c 프로젝트: alandekok/prads
int connection_tracking(packetinfo *pi)
{
    static char ip_addr_s[INET6_ADDRSTRLEN];
    static char ip_addr_d[INET6_ADDRSTRLEN];
    struct in_addr *ipa; 
    cx_track(pi);

    if(pi->af == AF_INET6) {
      u_ntop(pi->ip6->ip_src, pi->af, ip_addr_s);
      u_ntop(pi->ip6->ip_dst, pi->af, ip_addr_d);
    } else {
      ipa = pi->ip4->ip_src;
      inet_ntop(pi->af, &ipa, ip_addr_s, INET6_ADDRSTRLEN);
      ipa = pi->ip4->ip_dst;
      inet_ntop(pi->af, &ipa, ip_addr_d, INET6_ADDRSTRLEN);
    }
    if(config.cflags & CONFIG_CONNECT)
        printf("conn[%4lu] %s:%u -> %s:%u [%s]\n", pi->cxt->cxid, 
               ip_addr_s, ntohs(pi->s_port),
               ip_addr_d, ntohs(pi->d_port),
               pi->sc?pi->sc==SC_SERVER? "server":"client":"NONE"); 
    return 0;
}
예제 #7
0
/* ----------------------------------------------------------
 * FUNCTION : print_stat_sguil
 * DESC     : This function prints stats info to the FIFO file
 * INPUT    : 0 - IP Address
 *          : 1 - Port
 *          : 2 - Protocol
 * Example  : ID \n IP \n NumIP \n PORT \n PROTO \n timestamp \n . \n
 *            03\n10.10.10.83\n168430163\n22\n6\n1100847309\n.\n
 * ---------------------------------------------------------- */
void fifo_stat (output_plugin *p, asset *rec, os_asset *os, /*UNUSED*/ connection *cxt)
{
    (void)(cxt); /* UNUSED */
    static char ip_addr_s[INET6_ADDRSTRLEN];
    if (p->data == NULL) {
        elog("[!] ERROR:  File handle not open!\n");
        return;
    }
    /* pads_agent.tcl process each line until it receivs a dot by itself */
    u_ntop(rec->ip_addr, rec->af, ip_addr_s);
    fprintf((FILE*)p->data, "03\n%s\n%u\n%d\n%d\n%ld\n.\n",
              ip_addr_s, htonl(IP4ADDR(&rec->ip_addr)), ntohs(os->port), 6 /*just for now*/, rec->last_seen);
    fflush((FILE*) p->data);
}
예제 #8
0
파일: assets.c 프로젝트: Ammaro/prads
/* ----------------------------------------------------------
 * FUNCTION     : add_asset
 * DESCRIPTION  : This function will add an asset to the
 *              : specified asset data structure.
 * INPUT        : 0 - packetinfo (af, ip_src, vlan)
 * RETURN       : None!
 * ---------------------------------------------------------- */
void add_asset(packetinfo *pi)
{
    uint64_t hash;
    asset *masset = NULL;

    config.pr_s.assets++;

    masset = (asset *) calloc(1, sizeof(asset));
    masset->af = pi->af;
    masset->vlan = pi->vlan;
    masset->i_attempts = 0;
    masset->first_seen = masset->last_seen = pi->pheader->ts.tv_sec;

    if (pi->af == AF_INET) {
        if(pi->arph) // mongo arp check
            //memcpy(&masset->ip_addr.__u6_addr.__u6_addr32[0], pi->arph->arp_spa, sizeof(uint32_t));
           IP4ADDR(&masset->ip_addr) = *(uint32_t*) pi->arph->arp_spa;
        else
           IP4ADDR(&masset->ip_addr)  = PI_IP4SRC(pi);
        hash = ASSET_HASH4(IP4ADDR(&masset->ip_addr));
    } else if (pi->af == AF_INET6) {
        masset->ip_addr = PI_IP6SRC(pi);
        hash = ASSET_HASH6(PI_IP6SRC(pi));
    }

    masset->next = passet[hash];

    if (passet[hash] != NULL)
        passet[hash]->prev = masset;
    masset->prev = NULL;
    masset->os = NULL;
    masset->services = NULL;
    masset->macentry = NULL;
    passet[hash] = masset;

#ifdef DEBUGG
    /* verbose info for sanity checking */
    static char ip_addr_s[INET6_ADDRSTRLEN];
    // pi->ip_src does not exist!
    u_ntop(pi->ip_src, pi->af, ip_addr_s);
    dlog("[*] asset added: %s\n",ip_addr_s);
#endif
    
    //return masset;
}
예제 #9
0
파일: log_file.c 프로젝트: alandekok/prads
/* ----------------------------------------------------------
 * FUNCTION : file_arp
 * DESC     : This function prints an ARP asset to the log file
 * INPUT    : 0 - Main asset
 * RETURN   : VOID
 * ---------------------------------------------------------- */
void file_arp (output_plugin *log, asset *main)
{
    /* ip,vlan,port,proto,ARP (mac-resolved),mac-address,timstamp*/
    static char ip_addr_s[INET6_ADDRSTRLEN];
    if ((FILE*)log->data == NULL) {
        if(log->flags & CONFIG_VERBOSE )
           elog("[!] ERROR:  File handle not open!\n");
        return;
    }
    u_ntop(main->ip_addr, main->af, ip_addr_s);
    if (main->macentry != NULL) {
        /* ip,0,0,ARP (mac-resolved),mac-address,timstamp */
        /* XXX: vendor info breaks csv niceness */
        fprintf((FILE*)log->data, "%s,%u,0,0,ARP (%s),%s,0,%lu\n", ip_addr_s,
            main->vlan ? ntohs(main->vlan) : 0,main->macentry->vendor,
            hex2mac(main->mac_addr), main->last_seen);
    } else {
        /* ip,0,0,ARP,mac-address,timstamp */
        fprintf((FILE*)log->data, "%s,%u,0,0,ARP,[%s],0,%lu\n", ip_addr_s,
            main->vlan ? ntohs(main->vlan) : 0,hex2mac(main->mac_addr), main->last_seen);
    }
    fflush((FILE*)log->data);
}
예제 #10
0
/* ----------------------------------------------------------
 * FUNCTION : fifo_arp
 * DESC     : This function prints an ARP asset to the FIFO file.
 * INPUT    : 0 - IP Address
 *          : 1 - MAC Address
 * ---------------------------------------------------------- */
void fifo_arp (output_plugin *p, asset *main)
{
    static char ip_addr_s[INET6_ADDRSTRLEN];
    FILE *fd;
    /* Print to FIFO */
    if (p->data == NULL) {
        elog("[!] ERROR:  File handle not open!\n");
        return;
    }
    fd = (FILE *)p->data;
    u_ntop(main->ip_addr, main->af, ip_addr_s);
    if (main->macentry != NULL) {
        /* prads_agent.tcl process each line until it receivs a dot by itself */
        fprintf(fd, "02\n%s\n%u\n%s\n%s\n%lu\n.\n", ip_addr_s,
                htonl(IP4ADDR(&main->ip_addr)), main->macentry->vendor,
                hex2mac(main->mac_addr), main->last_seen);
    } else {
        /* prads_agent.tcl process each line until it receivs a dot by itself */
        fprintf(fd, "02\n%s\n%u\nunknown\n%s\n%lu\n.\n", ip_addr_s,
                htonl(IP4ADDR(&main->ip_addr)), hex2mac(main->mac_addr), main->last_seen);
    }
    fflush(fd);
}
예제 #11
0
파일: log_file.c 프로젝트: alandekok/prads
/* ----------------------------------------------------------
 * FUNCTION : file_os
 * DESC     : Prints a os asset to the log file.
 * INPUT    : 0 - Main asset
 *          : 1 - OS asset
 * RETURN   : VOID
 * ---------------------------------------------------------- */
void
file_os (output_plugin *log, asset *main, os_asset *os, connection *cxt)
{
    static char ip_addr_s[INET6_ADDRSTRLEN];
    uint8_t tmp_ttl;

    if (!log) {
       return; // nah..
    }
    if(log->data == NULL){
        if(log->flags & CONFIG_VERBOSE)
           elog("[!] ERROR:  File handle not open: %s!\n", log->path);
        return;
    }

    u_ntop(main->ip_addr, main->af, ip_addr_s);

    /* ip,vlan,port,proto,OS-FP,FP,timstamp*/
    fprintf((FILE*)log->data, "%s,%u,%d,", ip_addr_s,
            main->vlan ? ntohs(main->vlan) : 0, os->port);
            //ntohs(main->port),service->proto);

    switch (os->detection) {
        case CO_SYN:
            fprintf((FILE*)log->data, "6,SYN");
            break;
        case CO_SYNACK:
            fprintf((FILE*)log->data, "6,SYNACK");
            break;
        case CO_ACK:
            fprintf((FILE*)log->data, "6,ACK");
            break;
        case CO_RST:
            fprintf((FILE*)log->data, "6,RST");
            break;
        case CO_FIN:
            fprintf((FILE*)log->data, "6,FIN");
            break;
        case CO_UDP:
            fprintf((FILE*)log->data, "17,UDP");
            break;
        case CO_ICMP:
            // 58 is ICMPv6
            fprintf((FILE*)log->data, "1,ICMP");
            break;

        default:
        fprintf(stderr,
            "[!] error in detection type %d (isn't implemented!)\n", os->detection);
    }

    if (os->raw_fp != NULL) {
        fprintf((FILE*)log->data, ",[%s:", (char *)bdata(os->raw_fp));
    } else {
        //bstring b = gen_fp_tcp(&os->fp, os->fp.zero_stamp, 0);
        bstring b = gen_fp_tcp(&os->fp, os->uptime, 0);
        os->raw_fp = b;
        fprintf((FILE*)log->data, ",[%s:", (char *)bdata(os->raw_fp));
    }
    if (os->fp.os != NULL) fprintf((FILE*)log->data,"%s", os->fp.os);
        else fprintf((FILE*)log->data, "unknown");
    if (os->fp.desc != NULL) fprintf((FILE*)log->data, ":%s", os->fp.desc);
        else fprintf((FILE*)log->data, ":unknown");

    if (os->fp.mss) fprintf((FILE*)log->data, ":link:%s",lookup_link(os->fp.mss,1));
    if (os->uptime) fprintf((FILE*)log->data, ":uptime:%dhrs",os->uptime/360000);

    tmp_ttl = normalize_ttl(os->ttl);
    fprintf((FILE*)log->data, "],%d,%lu\n",tmp_ttl - os->ttl, os->last_seen);   
    fflush((FILE*)log->data);
}
예제 #12
0
파일: dns.c 프로젝트: ariosx/passivedns
void print_passet(pdns_record *l, pdns_asset *p, ldns_rr *rr,
                  ldns_rdf *lname, uint16_t rcode)
{
    FILE *fd = NULL;
    static char ip_addr_s[INET6_ADDRSTRLEN];
    static char ip_addr_c[INET6_ADDRSTRLEN];
    char *d = config.log_delimiter;
    char *rr_class;
    char *rr_type;
    char *rr_rcode;
    char buffer[1000] = "";
    char *output = buffer;
    int offset = 0;
    uint8_t is_err_record = 0;

#ifdef HAVE_JSON
    json_t *jdata;
    size_t data_flags = 0;

    /* Print in the same order as inserted */
    data_flags |= JSON_PRESERVE_ORDER;

    /* No whitespace between fields */
    data_flags |= JSON_COMPACT;
#endif /* HAVE_JSON */

    /* If pdns_asset is not defined, then this is a NXD record */
    if (p == NULL) {
        is_err_record = 1;
    }

    /* Use the correct file descriptor */
    if (is_err_record && config.output_log_nxd) {
        if (config.logfile_all) {
            fd = config.logfile_fd;
        }
        else {
            fd = config.logfile_nxd_fd;
        }
        if (fd == NULL) return;
    }
    else if (!is_err_record && config.output_log) {
        fd = config.logfile_fd;
        if (fd == NULL) return;
    }


    if (is_err_record) {
        u_ntop(l->sip, l->af, ip_addr_s);
        u_ntop(l->cip, l->af, ip_addr_c);
    }
    else {
        u_ntop(p->sip, p->af, ip_addr_s);
        u_ntop(p->cip, p->af, ip_addr_c);
    }

    rr_class = malloc(10);
    rr_type  = malloc(10);
    rr_rcode = malloc(20);

    switch (ldns_rr_get_class(rr)) {
        case LDNS_RR_CLASS_IN:
            snprintf(rr_class, 10, "IN");
            break;
        case LDNS_RR_CLASS_CH:
            snprintf(rr_class, 10, "CH");
            break;
        case LDNS_RR_CLASS_HS:
            snprintf(rr_class, 10, "HS");
            break;
        case LDNS_RR_CLASS_NONE:
            snprintf(rr_class, 10, "NONE");
            break;
        case LDNS_RR_CLASS_ANY:
            snprintf(rr_class, 10, "ANY");
            break;
        default:
            snprintf(rr_class, 10, "%d", ldns_rr_get_class(rr));
            break;
    }

    switch (ldns_rr_get_type(rr)) {
        case LDNS_RR_TYPE_PTR:
            snprintf(rr_type, 10, "PTR");
            break;
        case LDNS_RR_TYPE_A:
            snprintf(rr_type, 10, "A");
            break;
        case LDNS_RR_TYPE_AAAA:
            snprintf(rr_type, 10, "AAAA");
            break;
        case LDNS_RR_TYPE_CNAME:
            snprintf(rr_type, 10, "CNAME");
            break;
        case LDNS_RR_TYPE_DNAME:
            snprintf(rr_type, 10, "DNAME");
            break;
        case LDNS_RR_TYPE_NAPTR:
            snprintf(rr_type, 10, "NAPTR");
            break;
        case LDNS_RR_TYPE_RP:
            snprintf(rr_type, 10, "RP");
            break;
        case LDNS_RR_TYPE_SRV:
            snprintf(rr_type, 10, "SRV");
            break;
        case LDNS_RR_TYPE_TXT:
            snprintf(rr_type, 10, "TXT");
            break;
        case LDNS_RR_TYPE_SOA:
            snprintf(rr_type, 10, "SOA");
            break;
        case LDNS_RR_TYPE_NS:
            snprintf(rr_type, 10, "NS");
            break;
        case LDNS_RR_TYPE_MX:
            snprintf(rr_type, 10, "MX");
            break;
        default:
            if (is_err_record) {
                snprintf(rr_type, 10, "%d", ldns_rdf_get_type(lname));
            }
            else {
                snprintf(rr_type, 10, "%d", p->rr->_rr_type);
            }
            break;
    }

    if (is_err_record) {
        switch (rcode) {
            case 1:
                snprintf(rr_rcode, 20, "FORMERR");
                break;
            case 2:
                snprintf(rr_rcode, 20, "SERVFAIL");
                break;
            case 3:
                snprintf(rr_rcode, 20, "NXDOMAIN");
                break;
            case 4:
                snprintf(rr_rcode, 20, "NOTIMPL");
                break;
            case 5:
                snprintf(rr_rcode, 20, "REFUSED");
                break;
            case 6:
                snprintf(rr_rcode, 20, "YXDOMAIN");
                break;
            case 7:
                snprintf(rr_rcode, 20, "YXRRSET");
                break;
            case 8:
                snprintf(rr_rcode, 20, "NXRRSET");
                break;
            case 9:
                snprintf(rr_rcode, 20, "NOTAUTH");
                break;
            case 10:
                snprintf(rr_rcode, 20, "NOTZONE");
                break;
            default:
                snprintf(rr_rcode, 20, "UNKNOWN-ERROR-%d", rcode);
                break;
        }
    }

#ifdef HAVE_JSON
    if ((is_err_record && config.use_json_nxd) ||
        (!is_err_record && config.use_json)) {
        jdata = json_object();
        if (config.fieldsf & FIELD_TIMESTAMP_S)
            json_object_set_new(jdata, JSON_TIMESTAMP_S,  json_integer(l->last_seen.tv_sec));
        if (config.fieldsf & FIELD_TIMESTAMP_MS)
            json_object_set_new(jdata, JSON_TIMESTAMP_MS, json_integer(l->last_seen.tv_usec));
        if (config.fieldsf & FIELD_CLIENT)
            json_object_set_new(jdata, JSON_CLIENT,       json_string(ip_addr_c));
        if (config.fieldsf & FIELD_SERVER)
            json_object_set_new(jdata, JSON_SERVER,       json_string(ip_addr_s));
        if (config.fieldsf & FIELD_CLASS)
            json_object_set_new(jdata, JSON_CLASS,        json_string(rr_class));
        if (config.fieldsf & FIELD_QUERY)
            json_object_set_new(jdata, JSON_QUERY,        json_string((const char *)l->qname));
        if (config.fieldsf & FIELD_TYPE)
            json_object_set_new(jdata, JSON_TYPE,         json_string(rr_type));

        if (is_err_record) {
            if (config.fieldsf & FIELD_ANSWER)
                json_object_set_new(jdata, JSON_ANSWER,   json_string(rr_rcode));
            if (config.fieldsf & FIELD_TTL)
                json_object_set_new(jdata, JSON_TTL,      json_integer(PASSET_ERR_TTL));
            if (config.fieldsf & FIELD_COUNT)
                json_object_set_new(jdata, JSON_COUNT,    json_integer(PASSET_ERR_COUNT));
        }
        else {
            if (config.fieldsf & FIELD_ANSWER)
                json_object_set_new(jdata, JSON_ANSWER,   json_string((const char *)p->answer));
            if (config.fieldsf & FIELD_TTL)
                json_object_set_new(jdata, JSON_TTL,      json_integer(p->rr->_ttl));
            if (config.fieldsf & FIELD_COUNT)
                json_object_set_new(jdata, JSON_COUNT,    json_integer(p->seen));
        }

        output = json_dumps(jdata, data_flags);
        if (output == NULL)
            return;
    }
    else {
#endif /* HAVE_JSON */
        /* Print timestamp */
        if ((config.fieldsf & FIELD_TIMESTAMP_S) &&
            (config.fieldsf & FIELD_TIMESTAMP_MS)) {
            if (is_err_record) {
                offset += snprintf(output, sizeof(buffer) - offset, "%lu.%06lu",
                                   l->last_seen.tv_sec, l->last_seen.tv_usec);
            }
            else {
                offset += snprintf(output, sizeof(buffer) - offset, "%lu.%06lu",
                                   p->last_seen.tv_sec, p->last_seen.tv_usec);
            }
        }
        else if (config.fieldsf & FIELD_TIMESTAMP_S) {
            if (is_err_record) {
                offset += snprintf(output, sizeof(buffer) - offset, "%lu", l->last_seen.tv_sec);
            }
            else {
                offset += snprintf(output, sizeof(buffer) - offset, "%lu", p->last_seen.tv_sec);
            }
        }
        else if (config.fieldsf & FIELD_TIMESTAMP_MS) {
            if (is_err_record) {
                offset += snprintf(output, sizeof(buffer) - offset, "%06lu", l->last_seen.tv_usec);
            }
            else {
                offset += snprintf(output, sizeof(buffer) - offset, "%06lu", p->last_seen.tv_usec);
            }
        }

        /* Print client IP */
        if (config.fieldsf & FIELD_CLIENT) {
            if (offset != 0)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", d);
            offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", ip_addr_c);
        }

        /* Print server IP */
        if (config.fieldsf & FIELD_SERVER) {
            if (offset != 0)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", d);
            offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", ip_addr_s);
        }

        /* Print class */
        if (config.fieldsf & FIELD_CLASS) {
            if (offset != 0)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", d);
            offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", rr_class);
        }

        /* Print query */
        if (config.fieldsf & FIELD_QUERY) {
            if (offset != 0)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", d);
            offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", l->qname);
        }

        /* Print type */
        if (config.fieldsf & FIELD_TYPE) {
            if (offset != 0)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", d);
            offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", rr_type);
        }

        /* Print answer */
        if (config.fieldsf & FIELD_ANSWER) {
            if (offset != 0)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", d);
            if (is_err_record)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", rr_rcode);
            else
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", p->answer);
        }

        /* Print TTL */
        if (config.fieldsf & FIELD_TTL) {
            if (offset != 0)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", d);
            if (is_err_record)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%d", PASSET_ERR_TTL);
            else
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%u", p->rr->_ttl);
        }

        /* Print count */
       if (config.fieldsf & FIELD_COUNT) {
            if (offset != 0)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%s", d);
            if (is_err_record)
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%d", PASSET_ERR_COUNT);
            else
                offset += snprintf(output+offset, sizeof(buffer) - offset, "%lu", p->seen);
        }
#ifdef HAVE_JSON
    }
#endif /* HAVE_JSON */

    /* Print to log file */
    if (fd) {
        fprintf(fd, "%s\n", output);
        fflush(fd);
    }

    /* Print to syslog */
    if ((is_err_record && config.output_syslog_nxd) ||
        (!is_err_record && config.output_syslog)) {
        openlog(PDNS_IDENT, LOG_NDELAY, LOG_LOCAL7);
        syslog(LOG_INFO, "%s", output);
        closelog();
    }

    if (is_err_record) {
        l->last_print = l->last_seen;
        l->seen = 0;
    }
    else {
        p->last_print = p->last_seen;
        p->seen = 0;
    }

    free(rr_class);
    free(rr_type);
    free(rr_rcode);

}