source: umon/main/common/dns.c @ 87db514

Last change on this file since 87db514 was 87db514, checked in by Amar Takhar <amar@…>, on 04/16/15 at 19:26:21

Initial commit of the umon repository.

Prior to this three changes were made:

  • Remove umon_ prefix from parent directories.
  • Collapse main/target/ into main/
  • Remove ports/template/flashtest.scr.ucon script.
  • Property mode set to 100755
File size: 18.1 KB
Line 
1/**************************************************************************
2 *
3 * Copyright (c) 2013 Alcatel-Lucent
4 *
5 * Alcatel Lucent licenses this file to You under the Apache License,
6 * Version 2.0 (the "License"); you may not use this file except in
7 * compliance with the License.  A copy of the License is contained the
8 * file LICENSE at the top level of this repository.
9 * You may also obtain a copy of the License at:
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 **************************************************************************
20 *
21 * dns.c:
22 *
23 * This file implements a basic DNS client and some form of a multicast-DNS
24 * reponder.  The functionality provides the basic ability to retrieve an IP
25 * address from a domain name.
26 * Refer to RFC 1035 section 4.1 for the packet format.
27 *
28 *
29 * Original author:     Ed Sutter (ed.sutter@alcatel-lucent.com)
30 *
31 */
32#include "config.h"
33#if INCLUDE_DNS
34#include "endian.h"
35#include "genlib.h"
36#include "stddefs.h"
37#include "ether.h"
38#include "cli.h"
39#include "timer.h"
40
41const char mDNSIp[] = { 224, 0, 0, 251 };
42const char mDNSMac[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb };
43
44char * dnsErrStr(int errno);
45
46short DnsPort;
47static unsigned short dnsId;
48static unsigned long dnsIP;
49static char dnsErrno, dnsWaiting, dnsCacheInitialized;
50static struct dnscache hostnames[MAX_CACHED_HOSTNAMES];
51
52/* ip_to_bin...
53 * Essentially identical to IpToBin() in ethernet.c, but without
54 * the error message.
55 */
56int
57ip_to_bin(char *ascii,uchar *binary)
58{
59        int     i, digit;
60        char    *acpy;
61
62        acpy = ascii;
63        for(i=0;i<4;i++) {
64                digit = (int)strtol(acpy,&acpy,10);
65                if (((i != 3) && (*acpy++ != '.')) ||
66                        ((i == 3) && (*acpy != 0)) ||
67                        (digit < 0) || (digit > 255)) {
68                        return(-1);
69                }
70                binary[i] = (uchar)digit;
71        }
72        return(0);
73}
74
75
76/* getHostAddr():
77 * This function is a simplified version of gethostbyname().
78 * Given a domain name, this function will first query a
79 * locally maintained cache then, if not found there, it will
80 * issue a DNS query to retrieve the hosts IP address.
81 */
82unsigned long
83getHostAddr(char *hostname)
84{
85        short   port;
86        struct ip *ipp;
87        struct Udphdr *udpp;
88        struct dnshdr *dnsp;
89        struct elapsed_tmr tmr;
90        struct ether_header *enetp;
91        uchar   binenet[8], *enetaddr;
92        unsigned long   srvrip, binip;
93        char    *pp, *np, *srvrname, *dot;
94        int             i, namelen, pktsize, ip_len;
95
96        /* First check to see if the incoming host name is simply a
97         * decimal-dot-formatted IP address.  If it is, then just
98         * convert it to a 32-bit long and return here...
99         */
100        if (ip_to_bin(hostname,(uchar *)&binip) == 0)
101                return(binip);
102               
103        if (!dnsCacheInitialized)
104                dnsCacheInit();
105
106        dnsErrno = DNSERR_NULL;
107
108        /* First try to find the hostname in our local cache...
109         */
110        for(i=0;i<MAX_CACHED_HOSTNAMES;i++) {
111                if (strcmp(hostnames[i].name,hostname) == 0)
112                        return(hostnames[i].addr);
113        }
114
115        /* If not in the cache, we query the network.  First look
116         * for a DNSSRVR defined in the environment.  If found, use
117         * it; else, use IP broadcast.
118         */
119       
120        /* See if this is a mDNS request...
121         */
122        if (strstr(hostname,".local")) {
123                DnsPort = port = DNSMCAST_PORT;
124                srvrip = htonl(DNSMCAST_IP);
125                memcpy((char *)binenet,(char *)mDNSMac,sizeof(mDNSMac));
126                enetaddr = binenet;
127        }
128        else {
129                port = IPPORT_DNS;
130                DnsPort = port+1;
131                srvrname = getenv("DNSSRVR");
132                if (srvrname == (char *)0)
133                        srvrip = 0xffffffff;
134                else {
135                        if (IpToBin(srvrname,(uchar *)&srvrip) < 0)
136                                return(0);
137                }
138
139                /* Get the ethernet address for the IP:
140                 */
141                enetaddr = ArpEther((uchar *)&srvrip,binenet,0);
142                if (!enetaddr) {
143                        printf("ARP failed for 0x%x\n",srvrip);
144                        return(0);
145                }
146        }
147
148        /* Retrieve an ethernet buffer from the driver and populate the
149         * ethernet level of packet:
150         */
151        enetp = (struct ether_header *) getXmitBuffer();
152        memcpy((char *)&enetp->ether_shost,(char *)BinEnetAddr,6);
153        memcpy((char *)&enetp->ether_dhost,(char *)binenet,6);
154        enetp->ether_type = htons(ETHERTYPE_IP);
155
156        /* Move to the IP portion of the packet and populate it
157         * appropriately:
158         */
159        ipp = (struct ip *) (enetp + 1);
160        ipp->ip_vhl = IP_HDR_VER_LEN;
161        ipp->ip_tos = 0;
162        ipp->ip_id = ipId();
163        ipp->ip_off = 0;
164        ipp->ip_ttl = UDP_TTL;
165        ipp->ip_p = IP_UDP;
166        memcpy((char *)&ipp->ip_src.s_addr,(char *)BinIpAddr,4);
167        memcpy((char *)&ipp->ip_dst.s_addr,(char *)&srvrip,4);
168
169        /* Now UDP...
170         */
171        udpp = (struct Udphdr *) (ipp + 1);
172        udpp->uh_sport = htons(DnsPort);
173        udpp->uh_dport = htons(port);
174
175        /* Finally, the DNS data ...
176         */
177        dnsp = (struct dnshdr *)(udpp+1);
178
179        /* Build the message.  This query supports a single internet
180         * host-address question.
181         *
182         * Fixed header...
183         */
184        dnsId = ipId();
185        dnsp->id = htons(dnsId);                /* Unique id */
186        dnsp->param = 0;                                /* Parameter field */
187        dnsp->num_questions = htons(1); /* # of questions */
188        dnsp->num_answers = 0;                  /* # of answers */
189        dnsp->num_authority = 0;                /* # of authority */
190        dnsp->num_additional = 0;               /* # of additional */
191
192        /* The formatted name list..
193         * Each name is preceded by a single-byte length, so for our
194         * query, the list is "LNNNLNNNLNNN0", where...
195         *      'L' is the single-byte length of the name.
196         *      'NN..N' is variable-lenght domain.
197         *      '0' is the length of the next name in the list; hence,
198         *              indicating the end of the list.
199         *
200         * For each '.' (dot)  in the hostname, there is a
201         * LNNN pair.
202         */
203        pp = (char *)dnsp->question;
204        np = (char *)hostname;
205        namelen = strlen(hostname);
206        do {
207                dot = strchr(np,'.');
208                if (dot) {
209                        *pp++ = dot-np;
210                        memcpy(pp,np,dot-np);
211                        pp += (dot-np);
212                        np = dot + 1;
213                }
214                else {
215                        *pp++ = strlen(np);
216                        strcpy(pp,np);
217                }
218        } while(dot);
219
220
221        /* Since the size of the name can be arbitrary (not aligned),
222         * we must populate the TYPE and CLASS fields one byte at
223         * a time...
224         */
225        pp += (strlen(np) + 1);
226        *pp++ = 0;
227        *pp++ = 1;      /* type = 'A' (host address) */
228        *pp++ = 0;
229        *pp = 1;        /* class = 'IN' (the internet) */
230
231        /* Send the DNS query:
232         * Total message size is...
233         * FIXED_HDR_SIZE + NAME_SIZE + TYPE_SIZE + CLASS_SIZE + (NAMELEN_SIZE*2)
234         * where...
235         *      FIXED_HDR_SIZE  = 12
236         *  NAME_SIZE           = strlen(hostname) = namelen
237         *  TYPE_SIZE           = sizeof(short) = 2
238         *  CLASS_SIZE          = sizeof(short) = 2
239         *  NAMELEN_SIZE        = sizeof(char) = 1
240         *
241         * There are 2 name lengths.  The first one is the size of the host
242         * name we are querying for and the second one is zero (indicating no
243         * more names in the list).
244         * So, the total length of the packet is <namelen + 18>.
245         */
246
247        pktsize = namelen+18;
248        ip_len = sizeof(struct ip) + sizeof(struct Udphdr) + pktsize;
249        ipp->ip_len = htons(ip_len);
250        udpp->uh_ulen = htons((ushort)(ip_len - sizeof(struct ip)));
251
252        ipChksum(ipp);                  /* Compute csum of ip hdr */
253        udpChksum(ipp);                 /* Compute UDP checksum */
254
255//      printf("Sending DNS rqst id=%04x (%d %d)\n",dnsId,pktsize,ip_len);
256
257        dnsWaiting = 1;
258        sendBuffer(ETHERSIZE + IPSIZE + UDPSIZE + pktsize);
259
260        /* Wait for 3 seconds for a response...
261         */
262        startElapsedTimer(&tmr,3000);
263        while(!msecElapsed(&tmr)) {
264                if (dnsErrno != DNSERR_NULL)
265                        break;
266                pollethernet();
267        }
268        if (dnsErrno == DNSERR_COMPLETE) {
269                dnsCacheAdd(hostname,dnsIP);
270                shell_sprintf("DNSIP","%d.%d.%d.%d",
271                        IP1(dnsIP),IP2(dnsIP),IP3(dnsIP), IP4(dnsIP));
272                return(dnsIP);
273        }
274        else {
275                if (dnsErrno == DNSERR_NULL)
276                        printf("DNS attempt timeout\n");
277                else
278                        printf("DNSErr: %s\n",dnsErrStr((int)dnsErrno));
279                setenv("DNSIP",0);
280        }
281        return(0);
282}
283
284/* Note two different processDNS/processMCASTDNS functions...
285 * processDNS() provides the necessary code to deal with responses
286 * that we should expect to get as a result of issuing a dns request.
287 * processMCASTDNS() provides the necessary code to deal with requests
288 * from other machines querying for our hostname/ip info.
289 */
290
291/* processDNS():
292 * This function provides the recieving half of the DNS query above.
293 */
294int
295processDNS(struct ether_header *ehdr,ushort size)
296{
297        int     i;
298        char    *pp;
299        struct  ip *ihdr;
300        struct  Udphdr *uhdr;
301        struct  dnshdr *dhdr;
302        unsigned short  rtype, qtot, atot;
303
304        if (dnsWaiting == 0)
305                return(0);
306
307        dnsWaiting = 0;
308        ihdr = (struct ip *)(ehdr + 1);
309        uhdr = (struct Udphdr *)((char *)ihdr + IP_HLEN(ihdr));
310        dhdr = (struct dnshdr *)(uhdr + 1);
311
312//      printf("DNS: (%d)\n",size);
313//      printf("  dnsid: %04x\n",htons(dhdr->id));
314//      printf("  param: %04x\n",htons(dhdr->param));
315//      printf("  quest: %04x\n",htons(dhdr->num_questions));
316//      printf("  answe: %04x\n",htons(dhdr->num_answers));
317//      printf("  autho: %04x\n",htons(dhdr->num_authority));
318//      printf("  addit: %04x\n",htons(dhdr->num_additional));
319//      printMem(dhdr->question, size - UDPSIZE - IPSIZE - ETHERSIZE - 12,1); 
320
321        /* Verify the DNS response...
322         */
323        if ((htons(dhdr->param) & 0x8000) == 0) {                       /* response? */
324                dnsErrno = DNSERR_NOTARESPONSE;
325                return(0);
326        }
327        if (htons(dhdr->id) != dnsId) {                                         /* correct id? */
328                dnsErrno = DNSERR_BADRESPID;
329                return(0);
330        }
331        if ((rtype = (htons(dhdr->param) & 0xf)) != 0) {        /* response normal? */
332                switch(rtype) {
333                        case 1:
334                                dnsErrno = DNSERR_FORMATERR;
335                                break;
336                        case 2:
337                                dnsErrno = DNSERR_SRVRFAILURE;
338                                break;
339                        case 3:
340                                dnsErrno = DNSERR_NAMENOEXIST;
341                                break;
342                        default:
343                                dnsErrno = DNSERR_BADRESPTYPE;
344                                break;
345                }
346                return(0);
347        }
348        qtot = htons(dhdr->num_questions);
349        if ((atot = htons(dhdr->num_answers)) < 1) {    /* answer count >= 1? */
350                dnsErrno = DNSERR_BADANSWRCOUNT;
351                return(0);
352        }
353
354        /* At this point we can assume that the received packet format
355         * is ok.  Now we need to parse the packet for the "answer" to
356         * our query...
357         */
358
359        /* Set 'pp' to point to the start of the question list.
360         * There should only be one question in the response.
361         */
362        pp = (char *)&dhdr->question;
363
364        /* Skip over the questions:
365         */
366        for(i=0;i<qtot;i++) {
367                while(*pp)                      /* while 'L' is nonzero */
368                        pp += (*pp + 1);
369                pp += 5;                        /* Account for last 'L' plus TYPE/CLASS */
370        }
371
372        /* The 'pp' pointer is now pointing a list of resource records that
373         * correspond to the answer list.  It is from this list that we
374         * must retrieve the information we are looking for...
375         */
376
377        for(i=0;i<atot;i++) {
378                unsigned short type, len;
379
380                /* The first portion of the record is the resource domain name
381                 * and it may be literal string (a 1-octet count followed by
382                 * characters that make up the name) or a pointer to a literal
383                 * string.
384                 */
385                if ((*pp & 0xc0) == 0xc0) {     /* compressed? (section 4.1.4 RFC1035) */
386                        pp += 2;
387                }
388                else {
389                        while(*pp)                              /* while 'L' is nonzero */
390                                pp += (*pp + 1);
391                        pp += 1;
392                }
393                memcpy((char *)&type,pp,2);
394                type = htons(type);
395                pp += 8;
396                memcpy((char *)&len,pp,2);
397                len = htons(len);
398                if ((type == TYPE_A) && (len == 4)) {
399                        pp += 2;
400                        memcpy((char *)&dnsIP,pp,4);
401                        dnsIP = htonl(dnsIP);
402                }
403                else
404                        pp += (len+2);
405        }
406        dnsErrno = DNSERR_COMPLETE;
407        return(0);
408}
409
410/* processMCASTDNS():
411 * If we're here, then we've received a request over the Multi-cast
412 * DNS address for some host name.  If the hostname in this request
413 * matches this board's hostname, then return this board's IP address.
414 * If the shell variable HOSTNAME isn't set, then just return immediately.
415 */
416int
417processMCASTDNS(struct ether_header *ehdr,ushort size)
418{
419        int     l1, ql = 0;
420        struct  ip *ihdr;
421        char    *pp, *myname;
422        struct  Udphdr *uhdr;
423        struct  dnshdr *dhdr;
424
425        ihdr = (struct ip *)(ehdr + 1);
426        uhdr = (struct Udphdr *)(ihdr + 1);
427        dhdr = (struct dnshdr *)(uhdr + 1);
428
429        // If this message is DNS response, branch to processDNS()...
430        if ((htons(dhdr->param) & 0x8000) == 0x8000) {
431                processDNS(ehdr,size);
432                return(0);
433        }
434
435        if ((myname = getenv("HOSTNAME")) == 0)
436                return(0);
437
438        // If this isn't a normal query type, return...
439        if ((htons(dhdr->param) & 0xf) != 0)
440                return(0);
441
442        // If there isn't exactly 1 question, return...
443        if (htons(dhdr->num_questions) != 1)
444                return(0);
445
446        /* At this point we can assume that the received packet format
447         * is ok.  Now we need to parse the packet for the "question"...
448         */
449
450        /* Set 'pp' to point to the start of the question list.
451         */
452        pp = (char *)dhdr->question;
453        l1 = *pp;
454        while(*pp) {
455                ql += *pp;
456                ql++;
457                pp += (*pp + 1);
458        }
459
460        /* If the name in the question matches our hostname, then send a
461         * reply...
462         *
463         * Referring to top of pg 20 of the document
464         *  http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt...
465         *
466         * Multicast DNS responses MUST be sent to UDP port 5353 on the
467         * 224.0.0.251 multicast address.
468         */
469        if ((l1 == strlen(myname)) &&
470                (memcmp(myname,(char *)&dhdr->question[1],l1) == 0)) {
471                struct ip *ti, *ri;
472                struct Udphdr *tu, *ru;
473                struct ether_header *te;
474                struct  dnshdr *td;
475                short   type, class;
476                long    ttl;
477                struct  elapsed_tmr tmr;
478
479                te = EtherCopy(ehdr);
480                ti = (struct ip *) (te + 1);
481                ri = (struct ip *) (ehdr + 1);
482                ti->ip_vhl = ri->ip_vhl;
483                ti->ip_tos = ri->ip_tos;
484                ti->ip_id = ri->ip_id;
485                ti->ip_off = ri->ip_off;
486                ti->ip_ttl = UDP_TTL;
487                ti->ip_p = IP_UDP;
488                memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr,
489                        sizeof(struct in_addr));
490                memcpy((char *)&(ti->ip_dst.s_addr),(char *)mDNSIp,
491                        sizeof(struct in_addr));
492
493                tu = (struct Udphdr *) (ti + 1);
494                ru = (struct Udphdr *) (ri + 1);
495                tu->uh_sport = ru->uh_dport;
496                tu->uh_dport = htons(DNSMCAST_PORT);
497
498                td = (struct dnshdr *)(tu+1);
499
500                /* Flags: */
501                td->id = dhdr->id;
502                td->param = htons(0x8400);             
503                td->num_questions = 0;
504                td->num_answers = htons(1);
505                td->num_authority = 0;
506                td->num_additional = 0;
507
508                /* Answers: */
509                pp = (char *)td->question;
510                memcpy(pp,(char *)dhdr->question,ql+1);
511                pp += (ql+1);
512
513                type = htons(TYPE_A);
514                memcpy(pp,(char *)&type,2);
515                pp += 2;
516
517                class = htons(CLASS_IN);
518                memcpy(pp,(char *)&class,2);
519                pp += 2;
520               
521                ttl = htonl(900);
522                memcpy(pp,(char *)&ttl,4);
523                pp += 4;
524
525                *pp++ = 0;      /* 2-byte length of address */
526                *pp++ = 4;     
527                memcpy(pp,(char *)BinIpAddr,4);
528
529                tu->uh_ulen = ecs((UDPSIZE + 27 + ql));
530                ti->ip_len = ecs((UDPSIZE + 27 + ql + sizeof(struct ip)));
531
532                ipChksum(ti);           /* Compute checksum of ip hdr */
533                udpChksum(ti);          /* Compute UDP checksum */
534
535                /* Delay for some random time between 20-120msec...
536                 */
537                startElapsedTimer(&tmr,20 + (BinEnetAddr[5] & 0x3f));
538                while(!msecElapsed(&tmr));
539               
540                sendBuffer(ETHERSIZE + IPSIZE + UDPSIZE + 27 + ql);
541        }
542        return(0);
543}
544
545/* DNS Cache utilities:
546 */
547void
548dnsCacheInit(void)
549{
550        int     i;
551
552        for(i=0;i<MAX_CACHED_HOSTNAMES;i++) {
553                hostnames[i].idx = 0;
554                hostnames[i].addr = 0;
555                hostnames[i].name[0] = 0;
556        }
557        dnsCacheInitialized = 1;
558}
559
560int
561dnsCacheDump(void)
562{
563        int     i, tot;
564        struct  dnscache *hnp;
565
566        tot = 0;
567        hnp = hostnames;
568        for(i=0;i<MAX_CACHED_HOSTNAMES;i++,hnp++) {
569                if (hnp->addr) {
570                        printf("%3d %30s: %d.%d.%d.%d\n",hnp->idx,hnp->name, IP1(hnp->addr),
571                                IP2(hnp->addr), IP3(hnp->addr), IP4(hnp->addr));
572                        tot++;
573                }
574        }
575        return(tot);
576}
577
578int
579dnsCacheAdd(char *name, unsigned long inaddr)
580{
581        int     i, li, lowest;
582        struct  dnscache *hnp;
583        static  int idx = 0;
584
585        if (!dnsCacheInitialized)
586                dnsCacheInit();
587
588        /* Validate incoming name size:
589         */
590        if ((strlen(name) >= MAX_HOSTNAME_SIZE) || (inaddr == 0))
591                return(-1);
592
593        lowest = 0x70000000;
594
595        /* First look for an empty slot...
596         */
597        hnp = hostnames;
598        li = MAX_CACHED_HOSTNAMES;
599        for(i=0;i<MAX_CACHED_HOSTNAMES;i++,hnp++) {
600                if (hnp->addr == 0) {
601                        strcpy(hnp->name,name);
602                        hnp->addr = inaddr;
603                        hnp->idx = idx++;
604                        return(1);
605                }
606                else {
607                        if (hnp->idx < lowest) {
608                                lowest = hnp->idx;
609                                li = i;
610                        }
611                }
612        }
613
614        if (i == MAX_CACHED_HOSTNAMES)
615                return(-1);
616       
617        /* If all slots are filled, use the slot that had the
618         * the lowest idx value (this would be the oldest entry)...
619         */
620        hnp = &hostnames[li];
621        strcpy(hnp->name,name);
622        hnp->addr = inaddr;
623        hnp->idx = idx++;
624        return(1);
625}
626
627int
628dnsCacheDelAddr(unsigned long addr)
629{
630        int     i;
631
632        if (!dnsCacheInitialized) {
633                dnsCacheInit();
634                return(0);
635        }
636
637        for(i=0;i<MAX_CACHED_HOSTNAMES;i++) {
638                if (hostnames[i].addr == addr) {
639                        hostnames[i].name[0] = 0;
640                        hostnames[i].addr = 0;
641                        return(1);
642                }
643        }
644        return(0);
645}
646
647int
648dnsCacheDelName(char *name)
649{
650        int     i;
651
652        if (!dnsCacheInitialized) {
653                dnsCacheInit();
654                return(0);
655        }
656
657        for(i=0;i<MAX_CACHED_HOSTNAMES;i++) {
658                if (strcmp(hostnames[i].name,name) == 0) {
659                        hostnames[i].name[0] = 0;
660                        hostnames[i].addr = 0;
661                        return(1);
662                }
663        }
664        return(0);
665}
666
667struct dnserr dnsErrTbl[] = {
668        { DNSERR_NOSRVR,                        "no dns server" },
669        { DNSERR_SOCKETFAIL,            "socket fail" },
670        { DNSERR_FORMATERR,                     "format error" },
671        { DNSERR_SRVRFAILURE,           "server error" },
672        { DNSERR_NAMENOEXIST,           "no name exists" },
673        { DNSERR_BADRESPTYPE,           "bad dns server response" },
674        { DNSERR_BADQSTNCOUNT,          "bad question count" },
675        { DNSERR_BADANSWRCOUNT,         "bad answer count" },
676        { DNSERR_NOTARESPONSE,          "replay not a dns response" },
677        { DNSERR_BADRESPID,                     "bad dns response id" },
678
679        /* Must be last entry in table: */
680        { DNSERR_NULL,                          "no error" }
681};
682
683char *
684dnsErrStr(int errno)
685{
686        struct  dnserr *dep;
687
688        dep = dnsErrTbl;
689        while(dep->errno != DNSERR_NULL) {
690                if (dep->errno == errno)
691                        return(dep->errstr);
692                dep++;
693        }
694        return("invalid dns errno");
695}
696
697char *DnsHelp[] = {
698        "DNS Client",
699        "{hostname} | {cmd args}",
700        " Valid cmd values:",
701        "  add   {name} {ip}",
702        "  cache {dump | init}",
703        "  mdns {on | off}",
704        "  del   {name}",
705        0,
706};
707
708int
709DnsCmd(int argc, char *argv[])
710{
711        unsigned long addr;
712
713        if (argc == 2) {
714                if ((addr = getHostAddr(argv[1])) != 0) {
715                        printf("%s: %d.%d.%d.%d\n",argv[1],
716                                IP1(dnsIP),IP2(dnsIP),IP3(dnsIP), IP4(dnsIP));
717                }
718        }
719        else if (argc == 3) {
720                if (strcmp(argv[1],"cache") == 0) {
721                        if (strcmp(argv[2],"dump") == 0)
722                                dnsCacheDump();
723                        else if (strcmp(argv[2],"init") == 0)
724                                dnsCacheInit();
725                        else
726                                return(CMD_PARAM_ERROR);
727                }
728                else if (strcmp(argv[1],"mdns") == 0) {
729                        extern void enableMulticastReception(void);
730                        extern void disableMulticastReception(void);
731
732                        if (strcmp(argv[2],"on") == 0)
733                                enableMulticastReception();
734                        else if (strcmp(argv[2],"off") == 0)
735                                disableMulticastReception();
736                        else
737                                return(CMD_PARAM_ERROR);
738                }
739                else if (strcmp(argv[1],"del") == 0) {
740                        dnsCacheDelName(argv[2]);
741                }
742                else
743                        return(CMD_PARAM_ERROR);
744        }
745        else if (argc == 4) {
746                if (strcmp(argv[1],"add") == 0) {
747                        if (IpToBin(argv[3],(uchar *)&addr) < 0)
748                                return(CMD_FAILURE);
749                        dnsCacheAdd(argv[2],addr);
750                }
751                else
752                        return(CMD_PARAM_ERROR);
753        }
754        else
755                return(CMD_PARAM_ERROR);
756
757        return(CMD_SUCCESS);
758}
759
760#endif
Note: See TracBrowser for help on using the repository browser.