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; } }
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; }
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; }