コード例 #1
0
ファイル: jdns_packet.c プロジェクト: AmesianX/ambrosia
static int process_rrsection(jdns_list_t *dest, int count, const unsigned char *data, int size, const unsigned char **bufp)
{
	int n;
	int offset, at;
	jdns_string_t *name = 0;
	const unsigned char *buf;

	buf = *bufp;
	for(n = 0; n < count; ++n)
	{
		jdns_packet_resource_t *r;

		offset = buf - data;
		at = 0;

		if(!readlabel(data + offset, size - offset, data, size, &at, &name))
			goto error;

		offset += at;

		// need 10 more bytes
		if(offset + 10 > size)
			goto error;

		buf = data + offset;

		r = jdns_packet_resource_new();
		r->qname = name;
		name = 0;
		r->qtype = net2short(&buf);
		r->qclass = net2short(&buf);
		r->ttl = net2long(&buf);
		r->rdlength = net2short(&buf);

		offset = buf - data;

		// make sure we have enough for the rdata
		if(size - offset < r->rdlength)
		{
			jdns_packet_resource_delete(r);
			goto error;
		}

		r->rdata = jdns_copy_array(buf, r->rdlength);
		buf += r->rdlength;

		jdns_list_insert_value(dest, r, -1);
		jdns_packet_resource_delete(r);
	}

	*bufp = buf;
	return 1;

error:
	jdns_string_delete(name);
	return 0;
}
コード例 #2
0
ファイル: jdns_packet.c プロジェクト: AlexeyProkhin/jreen
static int process_qsection(jdns_list_t *dest, int count, const unsigned char *data, int size, const unsigned char **bufp)
{
	int n;
	int offset, at;
	jdns_string_t *name = 0;
	const unsigned char *buf;

	buf = *bufp;
	for(n = 0; n < count; ++n)
	{
		jdns_packet_question_t *q;

		offset = buf - data;
		at = 0;

		if(!readlabel(data + offset, size - offset, data, size, &at, &name))
			goto error;

		offset += at;

		// need 4 more bytes
		if(size - offset < 4)
			goto error;

		buf = data + offset;

		q = jdns_packet_question_new();
		q->qname = name;
		name = 0;
		q->qtype = net2short(&buf);
		q->qclass = net2short(&buf);

		jdns_list_insert_value(dest, q, -1);
		jdns_packet_question_delete(q);
	}

	*bufp = buf;
	return 1;

error:
	jdns_string_delete(name);
	return 0;
}
コード例 #3
0
ファイル: 1035.c プロジェクト: Jerome-PS/wxservdisc
void message_parse(struct message *m, unsigned char *packet)
{
    unsigned char *buf;
    int i;
    
    if(packet == 0 || m == 0) return;

    // keep all our mem in one (aligned) block for easy freeing    
    #define my(x,y) while(m->_len&7) m->_len++; x = (void*)(m->_packet + m->_len); m->_len += y;

    // header stuff bit crap
    m->_buf = buf = packet;
    m->id = net2short(&buf);
    if(buf[0] & 0x80) m->header.qr = 1;
    m->header.opcode = (buf[0] & 0x78) >> 3;
    if(buf[0] & 0x04) m->header.aa = 1;
    if(buf[0] & 0x02) m->header.tc = 1;
    if(buf[0] & 0x01) m->header.rd = 1;
    if(buf[1] & 0x80) m->header.ra = 1;
    m->header.z = (buf[1] & 0x70) >> 4;
    m->header.rcode = buf[1] & 0x0F;
    buf += 2;
    m->qdcount = net2short(&buf);
    if(m->_len + (sizeof(struct question) * m->qdcount) > MAX_PACKET_LEN - 8) { m->qdcount = 0; return; }
    m->ancount = net2short(&buf);
    if(m->_len + (sizeof(struct resource) * m->ancount) > MAX_PACKET_LEN - 8) { m->ancount = 0; return; }
    m->nscount = net2short(&buf);
    if(m->_len + (sizeof(struct resource) * m->nscount) > MAX_PACKET_LEN - 8) { m->nscount = 0; return; }
    m->arcount = net2short(&buf);
    if(m->_len + (sizeof(struct resource) * m->arcount) > MAX_PACKET_LEN - 8) { m->arcount = 0; return; }

    // process questions
    my(m->qd, sizeof(struct question) * m->qdcount);
    
    for(i=0; i < m->qdcount; i++)
    {
        _label(m, &buf, &(m->qd[i].name));
        m->qd[i].type = net2short(&buf);
        m->qd[i].rr_class = net2short(&buf);
    }

    // process rrs
    my(m->an, sizeof(struct resource) * m->ancount);
    my(m->ns, sizeof(struct resource) * m->nscount);
    my(m->ar, sizeof(struct resource) * m->arcount);
    if(! _rrparse(m,m->an,m->ancount,&buf))
      m->ancount = 0; // some error in parsing, set those counts to 0
    if(! _rrparse(m,m->ns,m->nscount,&buf)) 
      m->nscount = 0;
    if(! _rrparse(m,m->ar,m->arcount,&buf)) 
      m->arcount = 0;
}
コード例 #4
0
ファイル: 1035.c プロジェクト: Jerome-PS/wxservdisc
/** 
    Return 1 on success, 0 on failure. 
 */
int _rrparse(struct message *m, struct resource *rr, int count, unsigned char **bufp)
{
    int i;
    for(i=0; i < count; i++)
    {
        _label(m, bufp, &(rr[i].name));
        rr[i].type = net2short(bufp);
        rr[i].rr_class = net2short(bufp);
        rr[i].ttl = net2long(bufp);
        rr[i].rdlength = net2short(bufp);

        // if not going to overflow, make copy of source rdata
        if(rr[i].rdlength + (*bufp - m->_buf) > MAX_PACKET_LEN || m->_len + rr[i].rdlength > MAX_PACKET_LEN) return 0;
        rr[i].rdata = m->_packet + m->_len;
        m->_len += rr[i].rdlength;
        memcpy(rr[i].rdata,*bufp,rr[i].rdlength);

        // parse commonly known ones
        switch(rr[i].type)
        {
        case 1:
            if(m->_len + 16 > MAX_PACKET_LEN) return 0;
            rr[i].known.a.name = m->_packet + m->_len;
            m->_len += 16;
            sprintf(rr[i].known.a.name,"%d.%d.%d.%d",(*bufp)[0],(*bufp)[1],(*bufp)[2],(*bufp)[3]);
            rr[i].known.a.ip = net2long(bufp);
            break;
        case 2:
            _label(m, bufp, &(rr[i].known.ns.name));
            break;
        case 5:
            _label(m, bufp, &(rr[i].known.cname.name));
            break;
        case 12:
            _label(m, bufp, &(rr[i].known.ptr.name));
            break;
        case 33:
            rr[i].known.srv.priority = net2short(bufp);
            rr[i].known.srv.weight = net2short(bufp);
            rr[i].known.srv.port = net2short(bufp);
            _label(m, bufp, &(rr[i].known.srv.name));
            break;            
        default:
            *bufp += rr[i].rdlength;
        }
    }

    return 1;
}
コード例 #5
0
ファイル: jdns_packet.c プロジェクト: AlexeyProkhin/jreen
int jdns_packet_import(jdns_packet_t **a, const unsigned char *data, int size)
{
	jdns_packet_t *tmp = 0;
	const unsigned char *buf;

	// need at least some data
	if(!data || size == 0)
		return 0;

	// header (id + options + item counts) is 12 bytes
	if(size < 12)
		goto error;

	tmp = jdns_packet_new();
	buf = data;

	// id
	tmp->id = net2short(&buf);

	// options
	if(buf[0] & 0x80)                        // qr is bit 7
		tmp->opts.qr = 1;
	tmp->opts.opcode = (buf[0] & 0x78) >> 3; // opcode is bits 6,5,4,3
	if(buf[0] & 0x04)                        // aa is bit 2
		tmp->opts.aa = 1;
	if(buf[0] & 0x02)                        // tc is bit 1
		tmp->opts.tc = 1;
	if(buf[0] & 0x01)                        // rd is bit 0
		tmp->opts.rd = 1;
	if(buf[1] & 0x80)                        // ra is bit 7 (second byte)
		tmp->opts.ra = 1;
	tmp->opts.z = (buf[1] & 0x70) >> 4;      // z is bits 6,5,4
	tmp->opts.rcode = buf[1] & 0x0f;         // rcode is bits 3,2,1,0
	buf += 2;

	// item counts
	tmp->qdcount = net2short(&buf);
	tmp->ancount = net2short(&buf);
	tmp->nscount = net2short(&buf);
	tmp->arcount = net2short(&buf);

	// if these fail, we don't count them as errors, since the packet
	//   might have been truncated
	if(!process_qsection(tmp->questions, tmp->qdcount, data, size, &buf))
		goto skip;
	if(!process_rrsection(tmp->answerRecords, tmp->ancount, data, size, &buf))
		goto skip;
	if(!process_rrsection(tmp->authorityRecords, tmp->nscount, data, size, &buf))
		goto skip;
	if(!process_rrsection(tmp->additionalRecords, tmp->arcount, data, size, &buf))
		goto skip;

	tmp->fully_parsed = 1;

skip:
	// keep the raw data for reference during rdata parsing
	tmp->raw_size = size;
	tmp->raw_data = jdns_copy_array(data, size);

	*a = tmp;
	return 1;

error:
	jdns_packet_delete(tmp);
	return 0;
}