mDNS

Dependents:   OS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mDNSResponder.cpp Source File

mDNSResponder.cpp

00001 /*
00002     ----------------------------------------------------
00003     Made by JB RYU, KOR - 2015
00004     
00005     origin - C /  mdns-sd on CONTIKI-ipv6(uIP) I'd made
00006         
00007     now - mdns-sd on MBED-LWIP-ipv4
00008     ----------------------------------------------------
00009     More progressed things than others :
00010     {
00011         Parsing multi-records (OK),
00012         Check duplicated host and avoid (OK)
00013     }
00014     
00015     TODO : (Actully these are not necessary for my prj)
00016     {
00017         register multiple service, 
00018         managing records-caches
00019     }
00020     ----------------------------------------------------
00021     Notes :
00022         srv-instance-name = host-name
00023         SEP-<rand 2hex><IP 2hex>
00024     ----------------------------------------------------
00025 */
00026 
00027 
00028 #include "lwip/opt.h"
00029 #include "mbed.h"
00030 #include "EthernetInterface.h"
00031 #include <cstring>
00032 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
00033 
00034 #include "mDNSResponder.h"
00035 #include "dns-sd.h"
00036 
00037 #define MDNS_DBG    1
00038 #if (MDNS_DBG > 0)
00039 #define MDBG(x...)  printf(x)
00040 #else
00041 #define MDBG(x...)
00042 #endif
00043 
00044 mDNSResponder::mDNSResponder(EthernetInterface interface) : IP_str(NULL)
00045 {
00046     mdns_sock.open(&interface);
00047 }
00048 
00049 /* initialize static instance */
00050 char mDNSResponder::query_buf[1500] =
00051 {
00052     0,
00053 };
00054 
00055 MY_SD_DOMAINS mDNSResponder::SD_domains =
00056 {
00057     .numbers = N_CONTIKI_SERVICES,
00058     .elements =
00059     {
00060         {
00061             .inst_len = 5,
00062             .instance = {'s','p','y','o','s'},
00063             .serv_len = 12,
00064             .service = {'_','s','m','a','r','t','e','n','e','r','g','y',},
00065             .trl_len = 4,
00066             .trl = {'_','t','c','p'},
00067             .domain_len = 5,
00068             .domain = {'l','o','c','a','l'},
00069             .txt =
00070             {
00071                 .len_txtvers = 9,
00072                 .txtvers = {'t','x','t','v','e','r','s','=','1'},
00073                 .len_dcap = 10,
00074                 .dcap = {'d','c','a','p','=','/','d','c','a','p'},
00075                 .len_path = 9,
00076                 .path = {'p','a','t','h','=','/','u','p','t'},
00077                 .len_https = 9,
00078                 .https = {'h','t','t','p','s','=','4','4','3'},
00079                 .len_level = 9,
00080                 .level = {'l','e','v','e','l','=','-','S','0'},
00081             }
00082         },
00083     },
00084 };
00085 
00086 struct dns_hdr mDNSResponder::SD_res_hdr =
00087 {
00088     .id = 0x0000,
00089     .flags1 = DNS_FLAG1_RESPONSE | DNS_FLAG1_AUTHORATIVE,
00090     .flags2 = 0,
00091     .numquestions = 0,
00092     .numanswers = htons(1),
00093     .numauthrr = 0,
00094     .numextrarr = 0,
00095 };
00096 
00097 QR_MAP mDNSResponder::g_queries = {0,};
00098 
00099 /* end of initialize static instance */
00100 
00101 mDNSResponder::~mDNSResponder() 
00102 {
00103     close();
00104 }
00105 
00106 void mDNSResponder::
00107 register_service(char* number)
00108 {
00109     memcpy(&SD_domains.elements[0].instance[4], number, 4);
00110 }
00111 
00112 void mDNSResponder::
00113 query_domain(void)
00114 {
00115     volatile uint8_t i;
00116     struct dns_hdr* hdr;
00117     struct dns_question* question;
00118     uint8_t *query;
00119 
00120     MDBG("start probe duplicate domain\n\r");
00121 
00122     hdr = (struct dns_hdr *)query_buf;
00123     
00124     memset(hdr, 0, sizeof(struct dns_hdr));
00125     
00126     hdr->id = 0;
00127     hdr->flags1 = DNS_FLAG1_RD;
00128     hdr->numquestions = htons(1);
00129     
00130     query = (unsigned char *)query_buf + sizeof(*hdr);
00131     
00132     memcpy(query, &SD_domains.elements[0].inst_len, 
00133         SD_domains.elements[0].inst_len+1);
00134     query += SD_domains.elements[0].inst_len+1;
00135 
00136     memcpy(query, &SD_domains.elements[0].domain_len,
00137         SD_domains.elements[0].domain_len+1);
00138     query += SD_domains.elements[0].domain_len+1;
00139 
00140     *query = 0x00;
00141     query++;
00142     
00143     question = (struct dns_question*)query;
00144     question->type = htons(DNS_TYPE_ANY);
00145     question->obj = htons(DNS_CLASS_IN);
00146     
00147     query += 4;
00148 
00149     MDBG("send probe query(%d)\n\r", 
00150         (uint16_t)((uint32_t)query - (uint32_t)query_buf));
00151 
00152     mdns_sock.sendto(send_endpt, query_buf,
00153         (query - (uint8_t *) query_buf));
00154 }
00155 
00156 void mDNSResponder::announce(const char* ip) 
00157 {
00158     send_endpt.set_ip_address(MCAST);   
00159     send_endpt.set_port(MDNS_PORT);
00160 
00161     mdns_sock.bind(MDNS_PORT);
00162     if (mdns_sock.join_multicast_group(send_endpt) != 0) 
00163     {
00164         printf("Error joining the multicast group\n");
00165         while(true);
00166     }
00167     
00168     IP_str = new char[16];
00169     strcpy(IP_str, ip);
00170     
00171     IPstringToByte(IP_str);
00172 
00173     char instance_number[4];
00174 
00175     register_service(instance_number);
00176     
00177     query_domain();
00178 }
00179 
00180 void mDNSResponder::close() 
00181 {
00182     mdns_sock.close();
00183 }
00184 
00185 void mDNSResponder::IPstringToByte(char* IPstr)
00186 {
00187     char ip1[4] = {0,}; char ip2[4] = {0,};
00188     char ip3[4] = {0,}; char ip4[4] = {0,};
00189     char* p;
00190     char* p_dot;
00191 
00192     p_dot = strstr(IPstr, ".");
00193     memcpy(ip1, IPstr, p_dot - IPstr);
00194     IP_byte[0] = (uint8_t)atoi((const char*)ip1);
00195     
00196     p = p_dot + 1;
00197     p_dot = strstr(p, ".");
00198     memcpy(ip2, p, p_dot - p);
00199     IP_byte[1] = (uint8_t)atoi((const char*)ip2);
00200     
00201     p = p_dot + 1;
00202     p_dot = strstr(p, ".");
00203     memcpy(ip3, p, p_dot - p);
00204     IP_byte[2] = (uint8_t)atoi((const char*)ip3);
00205     
00206     p = p_dot + 1;
00207     memcpy(ip4, p, 3);
00208     IP_byte[3] = (uint8_t)atoi((const char*)ip4);
00209 }
00210 
00211 char* mDNSResponder::
00212 skip_name(char* query)
00213 {
00214   unsigned char n;
00215 
00216   do 
00217     {
00218     n = *query;
00219     if(n & 0xc0) 
00220         {
00221       ++query;
00222       break;
00223     }
00224 
00225     ++query;
00226 
00227     while(n > 0) 
00228         {
00229       ++query;
00230       --n;
00231     };
00232   } while(*query != 0);
00233     
00234   return query + 1;
00235 }
00236 
00237 char* mDNSResponder::
00238 decode_name(char* query, char* packet)
00239 {
00240     char c = 0xff;
00241     static char dest[MAX_DOMAIN_LEN];
00242     int len = 0;
00243 
00244     memset(dest, 0, MAX_DOMAIN_LEN);
00245 
00246     MDBG("\n\r");
00247     while((len < MAX_DOMAIN_LEN) && (c != 0x00)) 
00248     {
00249         c = *query;
00250         
00251         while (c == 0xc0) 
00252         {
00253             MDBG("%s : read offset\n\r", __FUNCTION__);
00254             query++;
00255             query  = (char*)((uint32_t)packet + *query);
00256             c = *query;
00257         }
00258 
00259         memset(&dest[len], c, 1);
00260 
00261         query++;
00262         len++;
00263     }
00264 
00265     MDBG("\n%s : %s\n\r", __FUNCTION__, dest);
00266     return dest;
00267 }
00268 
00269 void mDNSResponder::
00270 send_dns_ans(struct dns_hdr* hdr)
00271 {
00272     int i = 0;
00273     uint8_t* ptr;
00274     uint32_t off_inst = 0;
00275     uint32_t off_serv = 0;
00276     uint32_t off_domain = 0; 
00277     PTR_ANS* ptr_ans;
00278     SRV_ANS* srv_ans;
00279     struct dns_answer* A_ans;
00280     TXT_ANS* txt_ans;
00281     int numbers = g_queries.numbers;
00282 
00283     uint8_t ans_mask = DNS_TYPE_ANY; //later, for addtional ans
00284 
00285     memcpy(hdr, &SD_res_hdr, sizeof(struct dns_hdr));
00286     hdr->numanswers = htons(numbers);
00287     ptr = (uint8_t*)hdr + sizeof(struct dns_hdr);
00288 
00289     while (numbers--)
00290     {
00291         switch (g_queries.reqs[i])
00292         {
00293             case DNS_TYPE_PTR :
00294             {
00295                 ans_mask = ans_mask ^ DNS_TYPE_PTR;
00296                 if (off_serv == 0)
00297                 {
00298                     off_serv = (uint32_t)ptr - (uint32_t)hdr;
00299 
00300                     memcpy(ptr, &SD_domains.elements[0].serv_len,
00301                         SD_domains.elements[0].serv_len + 1);
00302                     ptr += SD_domains.elements[0].serv_len + 1;
00303 
00304                     memcpy(ptr, &SD_domains.elements[0].trl_len,
00305                         SD_domains.elements[0].trl_len + 1);
00306                     ptr += SD_domains.elements[0].trl_len + 1;
00307                 
00308                     memcpy(ptr, &SD_domains.elements[0].domain_len,
00309                         SD_domains.elements[0].domain_len + 1);
00310                     ptr += SD_domains.elements[0].domain_len + 1;
00311                     *ptr = 0x00;
00312                     ptr++;
00313                 }
00314                 else
00315                 {
00316                     *ptr = 0xc0;
00317                     ptr++;
00318                     *ptr = (uint8_t)off_serv;
00319                     ptr++;
00320                 }
00321 
00322                 ptr_ans = (PTR_ANS*)ptr;
00323                 
00324                 ptr_ans->type = htons(DNS_TYPE_PTR);
00325                 ptr_ans->obj = htons(DNS_CLASS_IN);
00326                 ptr_ans->ttl[0] = 0;
00327                 ptr_ans->ttl[1] = htons(120);
00328             
00329                 int instance_len = SD_domains.elements[0].inst_len;
00330                 
00331                 ptr = (uint8_t*)ptr_ans->name;
00332 
00333                 if (off_inst == 0)
00334                 {
00335                     off_inst = (uint32_t)ptr - (uint32_t)hdr;
00336 
00337                     ptr_ans->len = htons(instance_len + 3);
00338                     
00339                     memcpy(ptr_ans->name, 
00340                         &SD_domains.elements[0].inst_len, 
00341                         1 + SD_domains.elements[0].inst_len);
00342                 
00343                     ptr += instance_len + 1;
00344                     *ptr = 0xc0;
00345                     ptr++;
00346                     *ptr = (uint8_t)off_serv;
00347                     ptr++;
00348                 }
00349                 else
00350                 {
00351                     ptr_ans->len = htons(2);
00352                     
00353                     *ptr = 0xc0;
00354                     ptr++;
00355                     *ptr = (uint8_t)off_inst;
00356                     ptr++;
00357                 }
00358                 break;
00359             }
00360             case DNS_TYPE_SRV :
00361                 ans_mask = ans_mask ^ DNS_TYPE_SRV;
00362                 if (off_inst == 0)
00363                 {
00364                     off_inst = (uint32_t)ptr - (uint32_t)hdr;
00365                     
00366                     memcpy(ptr, 
00367                         &SD_domains.elements[0].inst_len, 
00368                         1 + SD_domains.elements[0].inst_len);
00369 
00370                     ptr += 1 + SD_domains.elements[0].inst_len;
00371 
00372                     if (off_serv == 0)
00373                     {
00374                         off_serv = (uint32_t)ptr - (uint32_t)hdr;
00375                         
00376                         memcpy(ptr, &SD_domains.elements[0].serv_len,
00377                             SD_domains.elements[0].serv_len + 1);
00378                         ptr += SD_domains.elements[0].serv_len + 1;
00379 
00380                         memcpy(ptr, &SD_domains.elements[0].trl_len,
00381                             SD_domains.elements[0].trl_len + 1);
00382                         ptr += SD_domains.elements[0].trl_len + 1;
00383                     
00384                         memcpy(ptr, &SD_domains.elements[0].domain_len,
00385                             SD_domains.elements[0].domain_len + 1);
00386                         ptr += SD_domains.elements[0].domain_len + 1;
00387 
00388                         *ptr = 0x00;
00389                         ptr++;
00390                     }
00391                     else
00392                     {
00393                         *ptr = 0xc0;
00394                         ptr++;
00395                         *ptr = (uint8_t)off_serv;
00396                         ptr++;
00397                     }
00398                 }
00399                 else
00400                 {
00401                     *ptr = 0xc0;
00402                     ptr++;
00403                     *ptr = (uint8_t)off_inst;
00404                     ptr++;
00405                 }
00406                 
00407                 srv_ans = (SRV_ANS*)(ptr);
00408                 srv_ans->type = htons(DNS_TYPE_SRV);
00409                 srv_ans->obj = htons(DNS_CLASS_IN | DNS_CASH_FLUSH);
00410                 srv_ans->ttl[0] = 0;
00411                 srv_ans->ttl[1] = htons(120);
00412                 srv_ans->pri = 0;
00413                 srv_ans->wei = 0;
00414                 srv_ans->port = htons(8080);
00415                 ptr = (uint8_t*)srv_ans->name;
00416 
00417                 if (off_domain == 0)
00418                 {
00419                     off_domain = (uint32_t)ptr - (uint32_t)hdr;
00420 
00421                     memcpy(ptr, 
00422                         &SD_domains.elements[0].inst_len,
00423                         1 + SD_domains.elements[0].inst_len);
00424 
00425                     ptr += 1 + SD_domains.elements[0].inst_len;
00426 
00427                     memcpy(ptr,
00428                         &SD_domains.elements[0].domain_len,
00429                         1 + SD_domains.elements[0].domain_len);
00430 
00431                     ptr+= 1 + SD_domains.elements[0].domain_len;
00432                     *ptr = 0x00;
00433                     ptr++;
00434                 }
00435                 else
00436                 {
00437                   *ptr = 0xc0;
00438                     ptr++;
00439                     *ptr = (uint8_t)off_domain;
00440                     ptr++;
00441                 }
00442                 srv_ans->len =
00443                     htons((uint16_t)((uint32_t)ptr - (uint32_t)&srv_ans->pri));
00444 
00445                 break;
00446             case DNS_TYPE_TXT :
00447                 ans_mask = ans_mask ^ DNS_TYPE_TXT;
00448                 if (off_inst == 0)
00449                 {
00450                     off_inst = (uint32_t)ptr - (uint32_t)hdr;
00451                     
00452                     memcpy(ptr, 
00453                         &SD_domains.elements[0].inst_len, 
00454                         1 + SD_domains.elements[0].inst_len);
00455 
00456                     ptr += 1 + SD_domains.elements[0].inst_len;
00457 
00458                     if (off_serv == 0)
00459                     {
00460                         off_serv = (uint32_t)ptr - (uint32_t)hdr;
00461                         
00462                         memcpy(ptr, &SD_domains.elements[0].serv_len,
00463                             SD_domains.elements[0].serv_len + 1);
00464                         ptr += SD_domains.elements[0].serv_len + 1;
00465 
00466                         memcpy(ptr, &SD_domains.elements[0].trl_len,
00467                             SD_domains.elements[0].trl_len + 1);
00468                         ptr += SD_domains.elements[0].trl_len + 1;
00469                     
00470                         memcpy(ptr, &SD_domains.elements[0].domain_len,
00471                             SD_domains.elements[0].domain_len + 1);
00472                         ptr += SD_domains.elements[0].domain_len + 1;
00473 
00474                         *ptr = 0x00;
00475                         ptr++;
00476                     }
00477                     else
00478                     {
00479                         *ptr = 0xc0;
00480                         ptr++;
00481                         *ptr = (uint8_t)off_serv;
00482                         ptr++;
00483                     }
00484                 }
00485                 else
00486                 {
00487                     *ptr = 0xc0;
00488                     ptr++;
00489                     *ptr = (uint8_t)off_inst;
00490                     ptr++;
00491                 }
00492                 
00493                 txt_ans = (TXT_ANS*)(ptr);
00494                 txt_ans->type = htons(DNS_TYPE_TXT);
00495                 txt_ans->obj = htons(DNS_CLASS_IN | DNS_CASH_FLUSH);
00496                 txt_ans->ttl[0] = 0;
00497                 txt_ans->ttl[1] = htons(120);
00498                 ptr = (uint8_t*)txt_ans->txt;
00499 
00500                 memcpy(ptr,
00501                     &SD_domains.elements[0].txt.len_txtvers,
00502                     1 + SD_domains.elements[0].txt.len_txtvers);
00503                 ptr += 1 + SD_domains.elements[0].txt.len_txtvers;
00504 
00505                 memcpy(ptr,
00506                     &SD_domains.elements[0].txt.len_dcap,
00507                     1 + SD_domains.elements[0].txt.len_dcap);
00508                 ptr += 1 + SD_domains.elements[0].txt.len_dcap;
00509 
00510                 memcpy(ptr,
00511                     &SD_domains.elements[0].txt.len_path,
00512                     1 + SD_domains.elements[0].txt.len_path);
00513                 ptr += 1 + SD_domains.elements[0].txt.len_path;
00514 
00515                 memcpy(ptr,
00516                     &SD_domains.elements[0].txt.len_https,
00517                     1 + SD_domains.elements[0].txt.len_https);
00518                 ptr += 1 + SD_domains.elements[0].txt.len_https;                
00519 
00520                 memcpy(ptr,
00521                     &SD_domains.elements[0].txt.len_level,
00522                     1 + SD_domains.elements[0].txt.len_level);
00523                 ptr += 1 + SD_domains.elements[0].txt.len_level;                
00524 
00525                 txt_ans->len =
00526                     htons((uint16_t)((uint32_t)ptr - (uint32_t)txt_ans->txt));
00527                 
00528                 break;
00529             case DNS_TYPE_A :
00530                 ans_mask = ans_mask ^ DNS_TYPE_A;
00531                 if (off_domain == 0)
00532                 {
00533                     off_domain = (uint32_t)ptr - (uint32_t)hdr;
00534                     
00535                     memcpy(ptr, 
00536                         &SD_domains.elements[0].inst_len, 
00537                         1 + SD_domains.elements[0].inst_len);
00538                     
00539                     ptr += 1 + SD_domains.elements[0].inst_len;
00540 
00541                     memcpy(ptr, 
00542                         &SD_domains.elements[0].domain_len, 
00543                         1 + SD_domains.elements[0].domain_len);
00544                     
00545                     ptr += 1 + SD_domains.elements[0].domain_len;
00546                     *ptr = 0x00;
00547                     ptr++;
00548                 }
00549                 else
00550                 {
00551                     *ptr = 0xc0;
00552                     ptr++;
00553                     *ptr = (uint8_t)off_domain;
00554                     ptr++;
00555                 }
00556                 
00557                 A_ans = (struct dns_answer*)(ptr);
00558                 
00559                 A_ans->type = htons(DNS_TYPE_A);
00560                 A_ans->obj = htons(DNS_CLASS_IN | DNS_CASH_FLUSH);
00561                 A_ans->ttl[0] = 0;
00562                 A_ans->ttl[1] = htons(120);
00563                 A_ans->len = htons(4);
00564                 memcpy((uint8_t*)A_ans->ipaddr, 
00565                     IP_byte, 4);
00566                 
00567                 ptr = (uint8_t*)&A_ans->ipaddr + 4;
00568                 break;
00569     
00570             default :
00571                 break;
00572         }
00573         i++;
00574     }
00575 
00576     int send_len = ptr - (uint8_t*)hdr;
00577 
00578     mdns_sock.sendto(send_endpt, (char*)hdr, send_len);
00579 }
00580 
00581 void mDNSResponder::
00582 MDNS_process()
00583 {
00584     char rcv_buf[ 1500 ];
00585     uint8_t nquestions, nanswers;
00586     struct dns_hdr* hdr;
00587     char *queryptr;
00588     uint8_t is_request;
00589         
00590     MDBG("MDNS Process\n\r");
00591 
00592     while(mdns_sock.recvfrom(&rcv_endpt, 
00593                     rcv_buf, sizeof(rcv_buf)) != 0)
00594     {
00595         hdr = (struct dns_hdr *)rcv_buf;
00596         queryptr = (char *)hdr + sizeof(*hdr);
00597         is_request = ((hdr->flags1 & ~1) == 0) && (hdr->flags2 == 0);
00598         nquestions = (uint8_t) ntohs(hdr->numquestions);
00599         nanswers = (uint8_t) ntohs(hdr->numanswers);
00600             
00601         MDBG("resolver: flags1=0x%02X flags2=0x%02X nquestions=%d,\
00602              nanswers=%d, nauthrr=%d, nextrarr=%d\n\r",\
00603              hdr->flags1, hdr->flags2, (uint8_t) nquestions, (uint8_t) nanswers,\
00604              (uint8_t) ntohs(hdr->numauthrr),\
00605              (uint8_t) ntohs(hdr->numextrarr));
00606         
00607         if(hdr->id != 0)
00608         {
00609             return;
00610         }
00611     
00612         /** ANSWER HANDLING SECTION ************************************************/
00613         struct dns_question* question = (struct dns_question *)skip_name(queryptr);
00614     
00615         uint16_t type;
00616     
00617         if (is_request)
00618         {
00619             char* name;
00620             
00621             memset(&g_queries, 0, sizeof(QR_MAP));
00622             
00623             while (nquestions--)
00624             {
00625                 type = ntohs(question->type);
00626                 name = decode_name(queryptr, (char*)hdr);
00627                 
00628                 if ((type & DNS_TYPE_PTR) == DNS_TYPE_PTR)
00629                 {
00630                     if (strncmp((const char*)name, 
00631                                 (const char*)&SD_domains.elements[0].serv_len, 
00632                                 SD_domains.elements[0].serv_len + 1) == 0)
00633                     {
00634                         MDBG("recv PTR request\n\r");
00635                         g_queries.reqs[g_queries.numbers] = DNS_TYPE_PTR;
00636                         g_queries.numbers++;
00637                     }
00638                 }
00639     
00640                 if ((type & DNS_TYPE_SRV) == DNS_TYPE_SRV)
00641                 {
00642                     if ((strncmp((const char*)name, 
00643                                 (const char*)&SD_domains.elements[0].inst_len, 
00644                                 SD_domains.elements[0].inst_len + 1) == 0) &&
00645                             (strncmp((const char*)(name + SD_domains.elements[0].inst_len+1),
00646                                     (const char*)&SD_domains.elements[0].serv_len,
00647                                     SD_domains.elements[0].serv_len+1) == 0))
00648                     {
00649                         MDBG("recv SRV request\n");
00650                         g_queries.reqs[g_queries.numbers] = DNS_TYPE_SRV;
00651                         g_queries.numbers++;
00652                     }
00653                 }
00654     
00655                 if ((type & DNS_TYPE_TXT) == DNS_TYPE_TXT)
00656                 {
00657                     if ((strncmp((const char*)name, 
00658                                 (const char*)&SD_domains.elements[0].inst_len, 
00659                                 SD_domains.elements[0].inst_len + 1) == 0) &&
00660                             (strncmp((const char*)(name + SD_domains.elements[0].inst_len+1),
00661                                     (const char*)&SD_domains.elements[0].serv_len,
00662                                     SD_domains.elements[0].serv_len+1) == 0))
00663                     {
00664                         MDBG("recv TXT request\n");
00665                         g_queries.reqs[g_queries.numbers] = DNS_TYPE_TXT;
00666                         g_queries.numbers++;
00667                     }
00668                 }
00669     
00670                 if ((type & DNS_TYPE_A) == DNS_TYPE_A)
00671                 {
00672                     if ((strncmp((const char*)name, 
00673                                 (const char*)&SD_domains.elements[0].inst_len, 
00674                                 SD_domains.elements[0].inst_len + 1) == 0) &&
00675                             (strncmp((const char*)(name + SD_domains.elements[0].inst_len + 1),
00676                                     (const char*)&SD_domains.elements[0].domain_len, 
00677                                     SD_domains.elements[0].domain_len + 1) == 0))
00678                     {
00679                         MDBG("recv AAAA request\n");
00680                         g_queries.reqs[g_queries.numbers] = DNS_TYPE_A;
00681                         g_queries.numbers++;
00682                     }
00683                 }
00684     
00685                 queryptr = (char*)question + sizeof(struct dns_question);
00686                 question = (struct dns_question *)skip_name(queryptr);
00687             }
00688     
00689             if (g_queries.numbers)
00690                 send_dns_ans(hdr);
00691         }
00692         else
00693         {
00694             if (strncmp((const char*)queryptr, 
00695                         (const char*)&SD_domains.elements[0].inst_len, 
00696                         SD_domains.elements[0].inst_len + 1) == 0)
00697             {
00698                 type = ntohs(question->type);
00699                 if (type == DNS_TYPE_A || type == DNS_TYPE_A)
00700                 {
00701                     char instance_number[4];
00702                     register_service(instance_number);
00703                     query_domain();
00704                 }
00705             }                           
00706         }
00707         
00708     }
00709 }
00710 #endif