Exemple #1
0
/*%
 *  Convert an RR to presentation format.
 *
 * return:
 *\li   Number of characters written to buf, or -1 (check errno).
 */
int
ns_sprintrr(const ns_msg* handle, const ns_rr* rr,
            const char* name_ctx, const char* origin,
            char* buf, size_t buflen) {
    int n;
    n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
                     ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
                     ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
                     name_ctx, origin, buf, buflen);
    return (n);
}
Exemple #2
0
char* getMailserver(const char* domain) {
	int len;
	char answer[NS_PACKETSZ];
	char *mailserver = malloc(NS_PACKETSZ);
	ns_msg msg;
	ns_rr rr;

	if(res_init() == -1) {
		return NULL;
	}
	len = res_query(domain,C_ANY,T_MX,answer,NS_PACKETSZ);
	if(len == -1) {
		return NULL;
	}
	/* return first MX record */	
	ns_initparse(answer,len,&msg);
	ns_parserr(&msg,ns_s_an,0,&rr);
	dn_expand(ns_msg_base(msg),ns_msg_base(msg)+ns_msg_size(msg),ns_rr_rdata(rr)+NS_INT16SZ,mailserver,NS_PACKETSZ);
	return mailserver; 
}
Exemple #3
0
static int
app_parse_srv(radiodns_app_t *app, ns_msg handle, ns_rr rr, char *dnbuf, radiodns_srv_t *srv)
{
	const unsigned char *rdata;
	
	(void) app;

	rdata = ns_rr_rdata(rr);
	srv->priority = ns_get16(rdata);
	rdata += NS_INT16SZ;

	srv->weight = ns_get16(rdata);
	rdata += NS_INT16SZ;
	
	srv->port = ns_get16(rdata);
	rdata += NS_INT16SZ;
	
	dn_expand(ns_msg_base(handle), ns_msg_base(handle) + ns_msg_size(handle), rdata, dnbuf, MAXDNAME);
	if(!(srv->target = strdup(dnbuf)))
	{
		return -2;
	}
	return 0;
}
Exemple #4
0
void royparse_output(const char* descr, iaddr from, iaddr to, uint8_t proto, unsigned flags,
    unsigned sport, unsigned dport, my_bpftimeval ts,
    const u_char* pkt_copy, unsigned olen,
    const u_char* payload, unsigned payloadlen)
{
    if (flags & DNSCAP_OUTPUT_ISDNS) {
        int    rrmax;
        ns_msg msg;
        ns_rr  rr;
        if (ns_initparse(payload, payloadlen, &msg) < 0) {
            fprintf(r_out, "ERR\n");
            return;
        }
        if (ns_msg_getflag(msg, ns_f_qr) != 0 && sport == 53) {
            fprintf(r_out, "%cD_", ns_msg_getflag(msg, ns_f_rd) ? 'R' : 'N');

            switch (ns_msg_getflag(msg, ns_f_opcode)) {
            case ns_o_query:
                fprintf(r_out, "QUERY");
                break;
            case ns_o_notify:
                fprintf(r_out, "NOTIFY");
                break;
            case ns_o_update:
                fprintf(r_out, "UPDATE");
                break;
            default:
                fprintf(r_out, "ELSE");
            }

            fprintf(r_out, "_%u_%cA_", ns_msg_count(msg, ns_s_an) ? 1 : 0, ns_msg_getflag(msg, ns_f_aa) ? 'A' : 'N');

            switch (ns_msg_getflag(msg, ns_f_rcode)) {
            case ns_r_noerror:
                fprintf(r_out, "NOERROR");
                break;
            case ns_r_formerr:
                fprintf(r_out, "FORMERR");
                break;
            case ns_r_nxdomain:
                fprintf(r_out, "NXDOMAIN");
                break;
            case ns_r_notimpl:
                fprintf(r_out, "NOTIMP");
                break;
            case ns_r_refused:
                fprintf(r_out, "REFUSED");
                break;
            case ns_r_notauth:
                fprintf(r_out, "NOTAUTH");
                break;
            default:
                fprintf(r_out, "ELSE");
            }

            fprintf(r_out, " %s,", royparse_ia_str(to));

            if (ns_msg_count(msg, ns_s_qd) > 0) {
                if (ns_parserr(&msg, ns_s_qd, 0, &rr) == 0) {
                    royparse_normalize(ns_rr_name(rr));
                    fprintf(r_out, "%s%s,%u", ns_rr_name(rr), (ns_rr_name(rr)[0] == '.') ? "" : ".", ns_rr_type(rr));
                } else
                    fprintf(r_out, "ERR,ERR");
            } else
                fprintf(r_out, ",");

            fprintf(r_out, ",%ld,%s%s%s%s", ns_msg_size(msg), ns_msg_id(msg) < 256 ? "-L" : "",
                ns_msg_getflag(msg, ns_f_tc) ? "-TC" : "",
                ns_msg_getflag(msg, ns_f_ad) ? "-AD" : "",
                ns_msg_getflag(msg, ns_f_cd) ? "-CD" : "");
            rrmax = ns_msg_count(msg, ns_s_ar);

            while (rrmax > 0) {
                rrmax--;
                if (ns_parserr(&msg, ns_s_ar, rrmax, &rr) == 0) {
                    if (ns_rr_type(rr) == ns_t_opt) {
                        fprintf(r_out, "-%c", (u_long)ns_rr_ttl(rr) & NS_OPT_DNSSEC_OK ? 'D' : 'E');
                        break;
                    }
                }
            }
            fprintf(r_out, "\n");
        } else if (opt_q != 0 && ns_msg_getflag(msg, ns_f_qr) == 0 && dport == 53) {
            struct pcap_pkthdr h;
            if (flags & DNSCAP_OUTPUT_ISLAYER)
                return;
            memset(&h, 0, sizeof h);
            h.ts  = ts;
            h.len = h.caplen = olen;
            pcap_dump((u_char*)q_out, &h, pkt_copy);
        }
    }
}
/**
 *  create_naptr_record()
 */
static NAPTR_record *create_naptr_record(const ns_msg *handle,
                                         const ns_rr *rr) {
   size_t rdchars;
   const u_char *rdata, *edata;
   const u_char *message = ns_msg_base(*handle);
   size_t message_len = ns_msg_size(*handle);
   char buf[NS_MAXDNAME]; /* defined in nameser.h */
   NAPTR_record *naptr_record = malloc(sizeof(NAPTR_record));
   memset(naptr_record,0,sizeof(NAPTR_record));

   /*
   ** Domain field
   */
   naptr_record->domain = strdup(ns_rr_name(*rr));

   /*
   ** TTL field
   */
   naptr_record->ttl = ns_rr_ttl(*rr);

   /*
   ** Copy from rdata
   ** (borrowed from BIND-8.2.2 ns_print.c)
   */
   rdata = ns_rr_rdata(*rr);
   edata = rdata+ns_rr_rdlen(*rr);

   /*
   ** Order & preference field
   */
   naptr_record->order = ns_get16(rdata);
   rdata += NS_INT16SZ;
   naptr_record->preference = ns_get16(rdata);
   rdata += NS_INT16SZ;

   /*
   ** Flags field
   */
   if((naptr_record->flags = get_rdata_str(rdata,edata,&rdchars))==NULL) {
      free_naptr_record(naptr_record);
      return NULL;
   }
   rdata += rdchars;

   /*
   ** Service field
   */
   if((naptr_record->service = get_rdata_str(rdata,edata,&rdchars))==NULL) {
      free_naptr_record(naptr_record);
      return NULL;
   }
   rdata += rdchars;

   /*
   ** RegExp field
   */
   if((naptr_record->regexp = get_rdata_str(rdata,edata,&rdchars))==NULL) {
      free_naptr_record(naptr_record);
      return NULL;
   }
   rdata += rdchars;

   /*
   ** Replacement field
   **  Note: dn_expand() sets the first character to '\0' for the root,
   **        we are going to set it back to '.'
   */
   if(dn_expand(message,message+message_len,rdata,buf,NS_MAXDNAME)==-1) {
      free_naptr_record(naptr_record);
      return NULL;
   }
   if(buf[0]=='\0') {
      buf[0]='.';
      buf[1]='\0';
   }
   naptr_record->replacement = strdup(buf);

   return naptr_record;
}
Exemple #6
0
static int 
app_follow_ptr(radiodns_app_t *app, unsigned char *abuf, ns_msg phandle, ns_rr prr)
{
	char dnbuf[MAXDNAME + 1], dbuf[4];
	char *d, *p, *endp;
	ns_msg handle;
	ns_rr rr;
	int c, len, r;
	
	dn_expand(ns_msg_base(phandle), ns_msg_base(phandle) + ns_msg_size(phandle), ns_rr_rdata(prr), dnbuf, sizeof(dnbuf));	
	if(!(app->name = (char *) calloc(1, strlen(dnbuf))))
	{
		return -2;
	}
	d = app->name;
	p = dnbuf;
	while(*p && *p != '.')
	{
		if(*p == '\\' && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]))
		{
			dbuf[0] = p[1];
			dbuf[1] = p[2];
			dbuf[2] = p[3];
			dbuf[3] = 0;
			c = strtol(dbuf, NULL, 10);
			*d = c;
			d++;
			p += 4;
			continue;
		}
		else if(*p == '\\' && p[1])
		{
			/* Skip the backslash, allowing it to escape the '.' */
			p++;
		}
		*d = *p;
		d++;
		p++;
	}
	*d = 0;
	if(0 >= (len = res_query(dnbuf, ns_c_in, ns_t_any, abuf, RDNS_ANSWERBUFLEN)))
	{
		return -1;
	}
	if(0 > ns_initparse(abuf, len, &handle))
	{
		return -1;
	}
	if(0 > (len = ns_msg_count(handle, ns_s_an)))
	{
		return -1;
	}
	if(!(app->srv = (radiodns_srv_t *) calloc(len, sizeof(radiodns_srv_t))))
	{
		return -2;
	}
	for(c = 0; c < len; c++)
	{
		if(ns_parserr(&handle, ns_s_an, c, &rr))
		{
			continue;
		}
		if(ns_rr_class(rr) != ns_c_in)
		{
			continue;
		}
		if(ns_rr_type(rr) == ns_t_txt)
		{
			app_parse_txt(app, handle, rr, dnbuf);
		}
		if(ns_rr_type(rr) == ns_t_srv)
		{
			r = app_parse_srv(app, handle, rr, dnbuf, &(app->srv[app->nsrv]));
			if(r == 0)
			{
				app->nsrv++;
			}
			else
			{
				return r;
			}
		}
				
	}
	if(app->nsrv)
	{
		return 0;
	}
	return -1;
}
Exemple #7
0
/* Attempt to resolve the target FQDN for a context */
const char *
radiodns_resolve_target(radiodns_t *context)
{
	int len, c;
	ns_msg handle;
	ns_rr rr;
	char domain[MAXDNAME + 1], dnbuf[MAXDNAME + 1];

	/* reset these to help with error handling in callers */
	h_errno = NETDB_INTERNAL;
	errno = 0;
	if(!context->answer)
	{
		if(NULL == (context->answer = (unsigned char *) malloc(RDNS_ANSWERBUFLEN)))
		{
			return NULL;
		}
	}
	free(context->target);
	context->target = NULL;
	strcpy(domain, context->domain);
	for(;;)
	{
		h_errno = 0;
		if(0 >= (len = res_query(domain, ns_c_in, ns_t_any, context->answer, RDNS_ANSWERBUFLEN)))
		{
			if(NETDB_INTERNAL == h_errno)
			{
				return NULL;
			}
			break;
		}
		if(0 > ns_initparse(context->answer, len, &handle))
		{
			break;
		}
		if(0 > (len = ns_msg_count(handle, ns_s_an)))
		{
			break;
		}
		/* Resolvers tend towards the sane: the last result in a set of
		 * DNAME and CNAME replies will be the one we care about. If
		 * you're building against a resolver which for some reason
		 * behaves differently, you'll need a workaround here.
		 */
		dnbuf[0] = 0;
		for(c = 0; c < len; c++)
		{
			if(ns_parserr(&handle, ns_s_an, c, &rr))
			{
				/* Parse failed? Hmm. */
				continue;
			}
			if(ns_rr_class(rr) != ns_c_in)
			{
				continue;
			}
			if(ns_rr_type(rr) == ns_t_dname || ns_rr_type(rr) == ns_t_cname)
			{
				dn_expand(ns_msg_base(handle), ns_msg_base(handle) + ns_msg_size(handle), ns_rr_rdata(rr), dnbuf, sizeof(dnbuf));
			}
		}      
		if(dnbuf[0])
		{
			if(0 == strcmp(domain, dnbuf))
			{
				break;
			}
			strcpy(domain, dnbuf);
			continue;
		}
		break;
	}
	/* Whatever we found last is the target, unless we found nothing at all,
	 * in which case the target is the same as the original domain.
	 */
	if(NULL == (context->target = strdup(domain)))
	{
		return NULL;
	}    
	return context->target;
}