static void recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
                 ip_addr_t *addr, u16_t port)
{
    struct mdns_state *ms = (struct mdns_state *) arg;
    struct mdns_header *h = (struct mdns_header *) p->payload;
    char *questions = (char *) &h[1];
    int qlen = p->len - sizeof(*h);

    h->flags = ntohs(h->flags);
    h->questions = ntohs(h->questions);

    LWIP_DEBUGF(MDNS_DEBUG | LWIP_DBG_STATE,
                ("mdns: packet from "));
    ip_addr_debug_print(MDNS_DEBUG | LWIP_DBG_STATE, addr);
    LWIP_DEBUGF(MDNS_DEBUG | LWIP_DBG_STATE,
                (" %04x %04x\n", h->flags, h->questions));

    if (h->id != 0 || h->questions == 0)
        goto free_and_return;

    for (int i = 0; i < h->questions; i++) {
        int offset = parse_question(ms, upcb, questions, qlen, p);

        if (offset < 0)
            goto free_and_return;

        questions += offset;
        qlen -= offset;
        if (qlen <= 0)
            break;
    }

free_and_return:
    pbuf_free(p);
}
Example #2
0
// public method
void AsyncDNS::handleReadData()
{
    QByteArray datagram;
    QString host;
    QList<QHostAddress> host_set;

    while(socket->hasPendingDatagrams()) {
        datagram.resize(socket->pendingDatagramSize());

        socket->readDatagram(datagram.data(), datagram.size());
    }
    unsigned int offset = 0;

    //parse datagram
    char * dat = datagram.data();

    DNSHeader header;
    DNS_QD    question;
    DNS_RR    rr;
    offset = parse_header(dat, &header);

    dat += offset;
    //parse question
    offset = parse_question(dat, &question);

    host   = question.host;
    dat += offset;

    //cache
    if( !cache.contains(host) ) {
        cache.insert(host, host_set);
    }

    //parse RRs
    int an_rr = header.an_count;
    for(int j = 0; j < an_rr ; j++ ) {
        dat += parse_RR(dat, &rr);

        if( rr.type == QTYPE::A && rr.rclass == QCLASS::IN ) {
            if(rr.rdlength == 4) { // IPV4 data
                bool lock = false;
                QHostAddress addr = QHostAddress(parse_ip(rr.rdata));

                if(cache.contains(host)) {
                    for(QHostAddress item : cache[host])
                    {
                        if(item == addr) {
                            lock = true;
                        }
                    }
                    if(lock == false)
                    {
                        (cache[host]).append(addr);
                    }
                }
            } else {
                qDebug() << "[ERROR] parse RR error!";
                return ;
            }
        }
    }

    emit resolve(host);
}
Example #3
0
Parse_stat MCAsk::parse(MCScriptPoint &sp)
{
	Parse_errors t_error = PE_UNDEFINED;

	Symbol_type t_type;
	const LT *t_literal;

	initpoint(sp);
	getit(sp, it);

	if (sp . next(t_type) == PS_NORMAL)
		if (sp . lookup(SP_ASK, t_literal) == PS_NORMAL)
			mode = (Ask_type)t_literal -> which;
		else
			sp . backup();

	// MW-2008-07-23: [[ Bug 6821 ]] ask files "foo" crashes.
	//   This is because the mode check is not strict enough. If the given ask
	//   mode is not known, we backup and then parse it as a question form.
	switch(mode)
	{
		case AT_PASSWORD:
			t_error = parse_password(sp);
		break;
	
		case AT_FILE:
			t_error = parse_file(sp);
		break;

		case AT_INFORMATION:
		case AT_QUESTION:
		case AT_ERROR:
		case AT_WARNING:
		case AT_UNDEFINED:
			t_error = parse_question(sp);
		break;

		default:
			sp . backup();
			t_error = parse_question(sp);
		break;
	}

	if (t_error == PE_UNDEFINED && sp . skip_token(SP_ASK, TT_UNDEFINED, AT_TITLED) == PS_NORMAL)
		if (sp . parseexp(False, True, &title) != PS_NORMAL)
			t_error = PE_ANSWER_BADTITLE;
	
	if (t_error == PE_UNDEFINED && sp . skip_token(SP_FACTOR, TT_PREP, PT_AS) == PS_NORMAL)
		if (sp . skip_token(SP_ASK, TT_UNDEFINED, AT_SHEET) == PS_NORMAL)
			sheet = True;
		else
			t_error = PE_ANSWER_BADRESPONSE;
			
	if (t_error != PE_UNDEFINED)
	{
		MCperror -> add(t_error, sp);
		return PS_ERROR;
	}
	
	return PS_NORMAL;
}
Example #4
0
        /*
         *  res_parse:
         *      Parse a DNS response buffer
         *
         *  returns a pointer to the expanded tree (or NULL on failure).
         */
res_response *
res_parse(char *msg)
{
        char *cp;
        HEADER *hp;
        res_response *resp;
        int i;

        u_short qdcount, ancount, nscount, arcount;


        /*
         * Set up the response structure,
         *  and copy across the header fields.
         */
        if ((resp = (res_response *)malloc(sizeof(res_response))) == NULL )
                return(NULL);
        memcpy((void *)&(resp->header), (void *)msg, sizeof(HEADER));
        hp = &(resp->header);
        cp = msg + sizeof(HEADER);


        /*
         * Temporarily clear the number of records to expect
         *    (allows the tree to be freed in case of problems)
         * Also handle network/host ordering
         */
        qdcount = ntohs((u_short)resp->header.qdcount); resp->header.qdcount = 0;
        ancount = ntohs((u_short)resp->header.ancount); resp->header.ancount = 0;
        nscount = ntohs((u_short)resp->header.nscount); resp->header.nscount = 0;
        arcount = ntohs((u_short)resp->header.arcount); resp->header.arcount = 0;
        resp->question = NULL;
        resp->answer = NULL;
        resp->authority = NULL;
        resp->additional = NULL;

        /*
         * Handle question records.
         */
        if ( qdcount ) {
                if ((resp->question = (s_question **)malloc(qdcount*sizeof(s_question*))) == NULL )
                        return(NULL);
                for ( i=0 ; i<qdcount ; i++ )           /* Clear, in case of free */
                        resp->question[i] = NULL;
                resp->header.qdcount = qdcount;  /* Stores swapped byte order!  Requires change to free_response. --GAT */
                for ( i=0 ; i<qdcount ; i++ )
                        if ((resp->question[i] = parse_question(&cp, msg)) == NULL ) {
                                free_response(resp);
                                free(resp);
                                return(NULL);
                        }
        }


        /*
         * Handle authoritative answer records
         */
        if ( ancount ) {
                if ((resp->answer = (s_rr **)malloc(ancount*sizeof(s_rr*))) == NULL ) {
                        resp->header.ancount = 0;
                        free_response(resp);
                        free(resp);
                        return(NULL);
                }
                for ( i=0 ; i<ancount ; i++ )
                        resp->answer[i] = NULL;
                resp->header.ancount = ancount;  /* Stores swapped byte order!  Requires change to free_response. --GAT */
                for ( i=0 ; i<ancount ; i++ )
                        if ((resp->answer[i] = parse_rr(&cp, msg)) == NULL ) {
                                free_response(resp);
                                free(resp);
                                return(NULL);
                        }
        }


        /*
         * Handle name server records
         */
        if ( nscount ) {
                if ((resp->authority = (s_rr **)malloc(nscount*sizeof(s_rr*))) == NULL ) {
                        resp->header.nscount = 0;
                        free_response(resp);
                        free(resp);
                        return(NULL);
                }
                for ( i=0 ; i<nscount ; i++ )
                        resp->authority[i] = NULL;
                resp->header.nscount = nscount;  /* Stores swapped byte order!  Requires change to free_response. --GAT */
                for ( i=0 ; i<nscount ; i++ )
                        if ((resp->authority[i] = parse_rr(&cp, msg)) == NULL ) {
                                free_response(resp);
                                free(resp);
                                return(NULL);
                        }
        }


        /*
         * Handle additional records
         */
        if ( arcount ) {
                if ((resp->additional = (s_rr **)malloc(arcount*sizeof(s_rr*))) == NULL ) {
                        resp->header.arcount = 0;
                        free_response(resp);
                        free(resp);
                        return(NULL);
                }
                for ( i=0 ; i<arcount ; i++ )
                        resp->additional[i] = NULL;
                resp->header.arcount = arcount;  /* Stores swapped byte order!  Requires change to free_response. --GAT */
                for ( i=0 ; i<arcount ; i++ )
                        if ((resp->additional[i] = parse_rr(&cp, msg)) == NULL ) {
                                free_response(resp);
                                free(resp);
                                return(NULL);
                        }
        }

        return(resp);
}
Example #5
0
File: main.c Project: xandout/CDNS
int main(int argc, char** argv)
{
    WSADATA w;
    unsigned short PORT = 53;
    int CLIENT_LENGTH;
    int BYTES_RECVD;
    SOCKET sd;
    struct sockaddr_in SERVER, CLIENT;
    char BUFFER[4096];
    memset((void*)&SERVER, '\0', sizeof(struct sockaddr_in));
    SERVER.sin_family = AF_INET;
    SERVER.sin_port = htons(PORT);

    //    Open winsock

    if(WSAStartup(0x0101, &w) != 0) {
        fprintf(stderr, "Could not get winsock\n");
        exit(0);
    }

    sd = socket(AF_INET, SOCK_DGRAM, 0);

    if(sd == INVALID_SOCKET) {
        fprintf(stderr, "Could not create socket\n");
        WSACleanup();
        exit(0);
    }

    strtosockaddr_in("0.0.0.0", &SERVER);
    if(bind(sd, (struct sockaddr*)&SERVER, sizeof(struct sockaddr_in)) == -1) {
        fprintf(stderr, "Could not bind to socket\n");
        closesocket(sd);
        WSACleanup();
        exit(0);
    }
    printf("Server running on %u.%u.%u.%u\n",
           (unsigned char)SERVER.sin_addr.S_un.S_un_b.s_b1,
           (unsigned char)SERVER.sin_addr.S_un.S_un_b.s_b2,
           (unsigned char)SERVER.sin_addr.S_un.S_un_b.s_b3,
           (unsigned char)SERVER.sin_addr.S_un.S_un_b.s_b4);
    printf("Press CTRL + C to quit\n");

    
    while(1) {
        CLIENT_LENGTH = (int)sizeof(struct sockaddr_in);

        BYTES_RECVD = recvfrom(sd, BUFFER, 4096, 0, (struct sockaddr*)&CLIENT, &CLIENT_LENGTH);
        if(BYTES_RECVD < 0) {
            fprintf(stderr, "Could not recieve datagram\n");
            closesocket(sd);
            WSACleanup();
            exit(0);
        }      
        QUESTION* qq = parse_question(BUFFER, BYTES_RECVD);
        char *connected_ip = inet_ntoa(CLIENT.sin_addr);
        printf("QUERY TYPE:%d from %s:%d is %s\n", qq->TYPE, connected_ip, CLIENT.sin_port, qq->QUERY);
    }
    closesocket(sd);
    WSACleanup();

    return 0;
}