示例#1
0
void MDNS::writeResponses(uint16_t responses) {
    // Reset output offsets for name compression
    for (uint8_t i = 0; i < NAME_COUNT; i++) {
        labels[i]->reset();
    }

    // Don't send additional responses where we are already sending answers
    responses &= ~(responses << FLAG_COUNT);

    uint8_t answerCount = count(responses);
    uint8_t additionalCount = count(responses >> FLAG_COUNT);

    buffer->writeUInt16(0x0);
    buffer->writeUInt16(0x8400);
    buffer->writeUInt16(0x0);
    buffer->writeUInt16(answerCount);
    buffer->writeUInt16(0x0);
    buffer->writeUInt16(additionalCount);

    while (responses > 0) {
        if ((responses & A_FLAG) != 0) {
            writeARecord();
        }
        if ((responses & PTR_FLAG) != 0) {
            writePTRRecord();
        }
        if ((responses & SRV_FLAG) != 0) {
            writeSRVRecord();
        }
        if ((responses & TXT_FLAG) != 0) {
            writeTXTRecord();
        }
        if ((responses & NSEC_HOST_FLAG) != 0) {
            writeNSECHostRecord();
        }
        if ((responses & NSEC_INSTANCE_FLAG) != 0) {
            writeNSECInstanceRecord();
        }

        responses >>= FLAG_COUNT;
    }
}
示例#2
0
static void sendReply2(NyLPC_TcMDnsServer_t* i_inst, const struct NyLPC_TDnsHeader* i_dns_header, const struct NyLPC_TDnsQuestion* q)
{
    NyLPC_TInt16 ptr_recode;
    NyLPC_TInt16 i2;
    char* obuf;
    NyLPC_TUInt16 obuflen;
    NyLPC_TUInt16 l;
    //パケットヘッダの生成
    switch (q->qtype){
    case NyLPC_TDnsQuestion_QTYPR_SRV:
        //
        ptr_recode = NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record, q);
        if (ptr_recode<0){
            goto DROP;
        }
        //Bufferの取得
        obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0);
        if (obuf == NULL){
            goto DROP;
        }
        //SRV,(TXT,A,AAAA,NSEC)
        l = setResponseHeader(obuf, i_dns_header, 1, 0, 3);
        l = writeSRVRecord(i_inst, ptr_recode, obuf, l, obuflen);
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        l = writeTXTRecord(i_inst, ptr_recode, obuf, l, obuflen);
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        //Aレコード
        l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a, NyLPC_iUdpSocket_getSockIP(i_inst->_socket));
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
//        //AAAAレコード
//        l = writeAAAARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
//        if (l <= 0){
//            NyLPC_OnErrorGoto(ERROR);
//        }
        //NSEC
        l = writeNSECRecord(obuf, l, obuflen, i_inst->_ref_record->a);
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        break;
/*    case NyLPC_TDnsQuestion_QTYPR_AAAA:
        //自分宛?(name.local)
        if (!NyLPC_TDnsQuestion_isEqualName(q, i_inst->_ref_record->a, "")){
            goto DROP;
        }
        //Bufferの取得
        obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0);
        if (obuf == NULL){
            goto DROP;
        }
        //Headerのコピー
        //AAAA,(A,NSEC)
        l = setResponseHeader(obuf, i_dns_header, 1, 0, 2);
        //AAAAレコード
        l = writeAAAARecordByQuery(obuf, l, obuflen, q, &(i_inst->_super.uip_udp_conn.lipaddr));
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        //Aレコードのみ
        l = writeARecordByQuery(obuf, l, obuflen, q, &(i_inst->_super.uip_udp_conn.lipaddr));
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        //NSEC
        l = writeNSECRecordByQuery(obuf, l, obuflen, q);
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        break;*/
    case NyLPC_TDnsQuestion_QTYPR_A:
        //自分宛?(name.local)
        if (!NyLPC_TDnsQuestion_isEqualName(q, i_inst->_ref_record->a, "")){
            goto DROP;
        }
        //Bufferの取得
        obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0);
        if (obuf == NULL){
            goto DROP;
        }
        //Headerのコピー
        l = setResponseHeader(obuf, i_dns_header, 1, 0, 1);
        //A、(NSEC
        l = writeARecordByQuery(obuf, l, obuflen, q, NyLPC_iUdpSocket_getSockIP(i_inst->_socket));
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        l = writeNSECRecordByQuery(obuf, l, obuflen, q);
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        break;
    case NyLPC_TDnsQuestion_QTYPR_PTR:
        //_service._dns-sd._udpかどうか
        if (NyLPC_TDnsQuestion_isEqualName(q, NULL, "_services._dns-sd._udp")){
            //Bufferの取得
            obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0);
            if (obuf == NULL){
                goto DROP;
            }
            l = setResponseHeader(obuf, i_dns_header, i_inst->_ref_record->num_of_srv, 0, 0);
            for (i2 = 0; i2<i_inst->_ref_record->num_of_srv; i2++){
                l = writeSdPtrRecord(&(i_inst->_ref_record->srv[i2]), obuf, l, obuflen);
                if (l <= 0){
                    NyLPC_OnErrorGoto(ERROR);
                }
            }
        }
        else{
            //自分宛?(proto.local)
            ptr_recode = NyLPC_TDnsRecord_getMatchPtrIdx(i_inst->_ref_record, q);
            if (ptr_recode<0){
                goto DROP;
            }
            //Bufferの取得
            obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0);
            if (obuf == NULL){
                goto DROP;
            }
            l = setResponseHeader(obuf, i_dns_header, 1, 0, 4);
            l = writePtrRecord(i_inst->_ref_record, ptr_recode, obuf, l, obuflen);
            if (l <= 0){
                NyLPC_OnErrorGoto(ERROR);
            }
            //SRV
            l = writeSRVRecord(i_inst, ptr_recode, obuf, l, obuflen);
            if (l <= 0){
                NyLPC_OnErrorGoto(ERROR);
            }
            //TXT
            l = writeTXTRecord(i_inst, ptr_recode, obuf, l, obuflen);
            if (l <= 0){
                NyLPC_OnErrorGoto(ERROR);
            }
            //Aレコード
            l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a,NyLPC_iUdpSocket_getSockIP(i_inst->_socket));
            if (l <= 0){
                NyLPC_OnErrorGoto(ERROR);
            }
//            //AAAAレコード
//            l = writeAAAARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
//            if (l <= 0){
//                NyLPC_OnErrorGoto(ERROR);
//            }
            //NSEC
            l = writeNSECRecord(obuf, l, obuflen, i_inst->_ref_record->a);
            if (l <= 0){
                NyLPC_OnErrorGoto(ERROR);
            }
        }
        break;
    case NyLPC_TDnsQuestion_QTYPR_TXT:
        //自分宛?(proto.local)
        ptr_recode = NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record, q);
        if (ptr_recode<0){
            goto DROP;
        }
        //Bufferの取得
        obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0);
        l = setResponseHeader(obuf, i_dns_header, 1, 0, 2);
        l = writeTXTRecord(i_inst, ptr_recode, obuf, l, obuflen);
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        //A recoad
        l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a,NyLPC_iUdpSocket_getSockIP(i_inst->_socket));
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
//        //AAAAレコード
//        l = writeAAAARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
//        if (l <= 0){
//            NyLPC_OnErrorGoto(ERROR);
//        }
        //NSEC
        l = writeNSECRecord(obuf, l, obuflen, i_inst->_ref_record->a);
        if (l <= 0){
            NyLPC_OnErrorGoto(ERROR);
        }
        break;
    default:
        goto DROP;
    }
    if (!NyLPC_iUdpSocket_psend(i_inst->_socket, &MDNS_MCAST_IPADDR, MDNS_MCAST_PORT, obuf, l)){
        NyLPC_OnErrorGoto(ERROR);
    }
    return;
ERROR:
    NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket, obuf);
DROP:
    return;
}
示例#3
0
static void sendAnnounse(NyLPC_TcMDnsServer_t* i_inst)
{
    char* obuf;
    NyLPC_TUInt16 obuflen;
    NyLPC_TUInt16 l;
    int i,i2;
    for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
        //Bufferの取得
        obuf=NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket,512,&obuflen,TIMEOUT_IN_MS);
        if(obuf==NULL){
            return;
        }
        l=setAnnounceHeader(obuf,1+i_inst->_ref_record->num_of_srv+4,0,0);
        //<Answer />
        //PTR
        l=writePtrRecord(i_inst->_ref_record,i2,obuf,l,obuflen);
        //SD-PTR
        if(l<=0){
            NyLPC_OnErrorGoto(ERROR);
        }
        for (i = 0; i<i_inst->_ref_record->num_of_srv; i++){
            l = writeSdPtrRecord(&(i_inst->_ref_record->srv[i]), obuf, l, obuflen);
            if (l <= 0){
                NyLPC_OnErrorGoto(ERROR);
            }
        }
        //<Additional/>
        //SRV
        l=writeSRVRecord(i_inst,i2,obuf,l,obuflen);
        if(l<=0){
            NyLPC_OnErrorGoto(ERROR);
        }
        //TXT
        l=writeTXTRecord(i_inst,i2,obuf,l,obuflen);
        if(l<=0){
            NyLPC_OnErrorGoto(ERROR);
        }
        //Aレコード
        l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,NyLPC_iUdpSocket_getSockIP(i_inst->_socket));
        if(l<=0){
            NyLPC_OnErrorGoto(ERROR);
        }
//        //AAAAレコード
//        l=writeAAAARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
//        if(l<=0){
//            NyLPC_OnErrorGoto(ERROR);
//        }
        //NSEC
        l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
        if(l<=0){
            NyLPC_OnErrorGoto(ERROR);
        }          
        if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
            NyLPC_OnErrorGoto(ERROR);
        }
    }
    return;
ERROR:
    NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,obuf);
    return;
}