Mercurial > flash_v2
annotate packages/net/ns/dns/current/src/dns.c @ 1777:c16341b1bac6 default tip
* Added execute permissions to files missed in conversion from CVS
| author | alexs |
|---|---|
| date | Mon, 12 Oct 2009 02:26:09 +0100 |
| parents | f7cb1caf8d2a |
| children |
| rev | line source |
|---|---|
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
1 //============================================================================= |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
2 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
3 // dns.c |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
4 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
5 // DNS client code |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
6 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
7 //============================================================================= |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
9 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
12 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later version. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
16 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
20 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
21 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
22 // You should have received a copy of the GNU General Public License along |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
23 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
25 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
26 // As a special exception, if other files instantiate templates or use macros |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
27 // or inline functions from this file, or you compile this file and link it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
28 // with other works to produce a work based on this file, this file does not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
29 // by itself cause the resulting work to be covered by the GNU General Public |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
30 // License. However the source code for this file must still be made available |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
31 // in accordance with section (3) of the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
32 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
33 // This exception does not invalidate any other reasons why a work based on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
34 // this file might be covered by the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
35 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
37 // at http://sources.redhat.com/ecos/ecos-license/ |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
38 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
39 //####ECOSGPLCOPYRIGHTEND#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
40 //============================================================================= |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
41 //#####DESCRIPTIONBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
42 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
43 // Author(s): andrew.lunn |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
44 // Contributors:andrew.lunn, jskov |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
45 // Date: 2001-09-18 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
46 // Description: Provides DNS lookup as per RFC 1034/1035. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
47 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
48 // Note: Does only support A and PTR lookups. Maybe add for other |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
49 // types as well? |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
50 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
51 // parse_answer() only returns the first found record. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
52 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
53 // Add tracing and assertions. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
54 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
55 //####DESCRIPTIONEND#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
56 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
57 //============================================================================= |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
58 |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
59 #include <pkgconf/system.h> |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
60 #ifdef CYGPKG_KERNEL |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
61 # include <pkgconf/kernel.h> |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
62 # include <cyg/kernel/kapi.h> |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
63 #endif |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
64 #include <cyg/hal/drv_api.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
65 #include <cyg/infra/cyg_type.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
66 #include <cyg/infra/cyg_trac.h> /* Tracing support */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
67 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
68 #include <netdb.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
69 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
70 #include <sys/time.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
71 #include <sys/types.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
72 #include <sys/socket.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
73 #include <arpa/inet.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
74 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
75 #include <ctype.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
76 #include <unistd.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
77 #include <stdio.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
78 #include <string.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
79 #include <stdlib.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
80 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
81 #include <cyg/ns/dns/dns_priv.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
82 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
83 static short id = 0; /* ID of the last query */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
84 static int s = -1; /* Socket to the DNS server */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
85 static cyg_drv_mutex_t dns_mutex; /* Mutex to stop multiple queries as once */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
86 static cyg_ucount32 ptdindex; /* Index for the per thread data */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
87 static char * domainname=NULL; /* Domain name used for queries */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
88 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
89 /* Allocate space for string of length len. Return NULL on failure. */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
90 static inline char* |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
91 alloc_string(int len) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
92 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
93 return malloc(len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
94 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
95 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
96 static inline void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
97 free_string(char* s) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
98 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
99 free(s); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
100 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
101 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
102 /* Deallocate the memory taken to hold a hent structure */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
103 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
104 free_hent(struct hostent * hent) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
105 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
106 if (hent->h_name) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
107 free_string(hent->h_name); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
108 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
109 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
110 if (hent->h_addr_list) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
111 int i = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
112 while (hent->h_addr_list[i]) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
113 free(hent->h_addr_list[i]); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
114 i++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
115 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
116 free(hent->h_addr_list); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
117 } |
|
211
6eb55882e01c
Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents:
210
diff
changeset
|
118 free(hent); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
119 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
120 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
121 /* Allocate hent structure with room for one in_addr. Returns NULL on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
122 failure. */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
123 static struct hostent* |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
124 alloc_hent(void) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
125 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
126 struct hostent *hent; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
127 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
128 hent = malloc(sizeof(struct hostent)); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
129 if (hent) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
130 memset(hent, 0, sizeof(struct hostent)); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
131 hent->h_addr_list = malloc(sizeof(char *)*2); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
132 if (!hent->h_addr_list) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
133 free_hent(hent); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
134 return NULL; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
135 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
136 hent->h_addr_list[0] = malloc(sizeof(struct in_addr)); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
137 if (!hent->h_addr_list[0]) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
138 free_hent(hent); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
139 return NULL; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
140 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
141 hent->h_addr_list[1] = NULL; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
142 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
143 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
144 return hent; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
145 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
146 |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
147 /* Thread destructor used to free stuff stored in per-thread data slot. */ |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
148 static void |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
149 thread_destructor(CYG_ADDRWORD data) |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
150 { |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
151 struct hostent *hent; |
|
212
94b558c9fb67
Merge from eCos master repository on 2002-05-31-00:05:29-BST
jlarmour
parents:
211
diff
changeset
|
152 hent = (struct hostent *)cyg_thread_get_data(ptdindex); |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
153 if (hent) |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
154 free_hent(hent); |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
155 return; |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
156 data=data; |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
157 } |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
158 |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
159 /* Store the hent away in the per-thread data. */ |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
160 static void |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
161 store_hent(struct hostent *hent) |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
162 { |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
163 // Prevent memory leaks by setting a destructor to be |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
164 // called on thread exit to free per-thread data. |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
165 cyg_thread_add_destructor( &thread_destructor, 0 ); |
|
212
94b558c9fb67
Merge from eCos master repository on 2002-05-31-00:05:29-BST
jlarmour
parents:
211
diff
changeset
|
166 cyg_thread_set_data(ptdindex, (CYG_ADDRWORD)hent); |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
167 } |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
168 |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
169 /* If there is an answer to an old query, free the memory it uses. */ |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
170 static void |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
171 free_stored_hent(void) |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
172 { |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
173 struct hostent *hent; |
|
212
94b558c9fb67
Merge from eCos master repository on 2002-05-31-00:05:29-BST
jlarmour
parents:
211
diff
changeset
|
174 hent = (struct hostent *)cyg_thread_get_data(ptdindex); |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
175 if (hent) { |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
176 free_hent(hent); |
|
212
94b558c9fb67
Merge from eCos master repository on 2002-05-31-00:05:29-BST
jlarmour
parents:
211
diff
changeset
|
177 cyg_thread_set_data(ptdindex, (CYG_ADDRWORD)NULL); |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
178 cyg_thread_rem_destructor( &thread_destructor, 0 ); |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
179 } |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
180 } |
|
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
181 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
182 /* Send the query to the server and read the response back. Return -1 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
183 if it fails, otherwise put the response back in msg and return the |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
184 length of the response. */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
185 static int |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
186 send_recv(char * msg, int len, int msglen) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
187 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
188 struct dns_header *dns_hdr; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
189 struct timeval timeout; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
190 int finished = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
191 int backoff = 1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
192 fd_set readfds; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
193 int written; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
194 int ret; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
195 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
196 CYG_REPORT_FUNCNAMETYPE( "send_recv", "returning %d" ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
197 CYG_REPORT_FUNCARG3( "msg=%08x, len=%d, msglen", msg, len, msglen ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
198 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
199 CYG_CHECK_DATA_PTR( msg, "msg is not a valid pointer!" ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
200 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
201 dns_hdr = (struct dns_header *) msg; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
202 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
203 do { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
204 written = write(s, msg, len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
205 if (written < 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
206 ret = -1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
207 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
208 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
209 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
210 FD_ZERO(&readfds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
211 FD_SET(s, &readfds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
212 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
213 timeout.tv_sec = backoff; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
214 timeout.tv_usec = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
215 backoff = backoff << 1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
216 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
217 ret = select(s+1, &readfds, NULL, NULL, &timeout); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
218 if (ret < 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
219 ret = -1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
220 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
221 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
222 /* Timeout */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
223 if (ret == 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
224 if (backoff > 16) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
225 h_errno = TRY_AGAIN; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
226 ret = -1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
227 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
228 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
229 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
230 if (ret == 1) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
231 ret = read(s, msg, msglen); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
232 if (ret < 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
233 ret = -1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
234 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
235 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
236 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
237 /* Reply to an old query. Ignore it */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
238 if (ntohs(dns_hdr->id) != (id-1)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
239 continue; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
240 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
241 finished = true; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
242 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
243 } while (!finished); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
244 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
245 CYG_REPORT_RETVAL( ret ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
246 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
247 return ret; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
248 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
249 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
250 /* Include the DNS client implementation code */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
251 #include <cyg/ns/dns/dns_impl.inl> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
252 |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
253 /* (re)Start the DNS client. This opens a socket to the DNS server |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
254 who's address is passed in. This address can be either an IPv4 or |
| 1069 | 255 IPv6 address. This function can be called multiple times. If we |
| 256 are being called a second time we have to be careful to allow any | |
| 257 ongoing lookups to finish before we close the socket and connect to | |
| 258 a different DNS server. The danger here is that we may have to wait | |
| 259 for up to 32 seconds if the DNS server is down. | |
| 260 Each invocation will close any previous connection and make a new | |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
261 connection to the new server. Note the address of the server must |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
262 be in numeric form since its not possible to do a DNS lookup! */ |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
263 |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
264 int cyg_dns_res_start(char * dns_server) { |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
265 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
266 static int init =0; |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
267 struct addrinfo * res; |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
268 int err; |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
269 |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
270 CYG_REPORT_FUNCNAMETYPE( "cyg_dns_res_start", "returning %d" ); |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
271 CYG_REPORT_FUNCARG1( "dns_server=%s", dns_server ); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
272 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
273 CYG_CHECK_DATA_PTR( dns_server, "dns_server is not a valid pointer!" ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
274 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
275 if (init) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
276 cyg_drv_mutex_lock(&dns_mutex); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
277 cyg_thread_free_data_index(ptdindex); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
278 if (s >= 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
279 close(s); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
280 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
281 } else { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
282 init = 1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
283 cyg_drv_mutex_init(&dns_mutex); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
284 cyg_drv_mutex_lock(&dns_mutex); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
285 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
286 |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
287 err = getaddrinfo(dns_server,"domain", NULL, &res); |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
288 if (err != 0) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
289 cyg_drv_mutex_unlock(&dns_mutex); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
290 CYG_REPORT_RETVAL( -1 ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
291 return -1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
292 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
293 |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
294 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
295 if (s == -1) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
296 cyg_drv_mutex_unlock(&dns_mutex); |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
297 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
298 CYG_REPORT_RETVAL( -1 ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
299 return -1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
300 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
301 |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
302 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
303 s = -1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
304 cyg_drv_mutex_unlock(&dns_mutex); |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
305 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
306 CYG_REPORT_RETVAL( -1 ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
307 return -1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
308 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
309 ptdindex = cyg_thread_new_data_index(); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
310 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
311 cyg_drv_mutex_unlock(&dns_mutex); |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
312 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
313 CYG_REPORT_RETVAL( 0 ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
314 return 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
315 } |
| 1005 | 316 |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
317 /* This is the old interface to start the resolver. It is only IPv4 |
| 1069 | 318 capable and so is now deprecated in favor of cyg_dns_res_start(). |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
319 Initialise the resolver. Open a socket and bind it to the |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
320 address of the server. return -1 if something goes wrong, |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
321 otherwise 0. If we are being called a second time we have to be |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
322 careful to allow any ongoing lookups to finish before we close the |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
323 socket and connect to a different DNS server. The danger here is |
| 1069 | 324 that we may have to wait for up to 32 seconds if the DNS server is |
|
1040
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
325 down. */ |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
326 int |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
327 cyg_dns_res_init(struct in_addr *dns_server) |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
328 { |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
329 char name[20]; |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
330 unsigned char *bytes = (unsigned char *)dns_server; |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
331 int ret; |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
332 |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
333 CYG_REPORT_FUNCNAMETYPE( "cyg_dns_res_init", "returning %d" ); |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
334 CYG_REPORT_FUNCARG1( "dns_server=%08x", dns_server ); |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
335 |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
336 diag_sprintf(name, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
337 |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
338 ret = cyg_dns_res_start(name); |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
339 |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
340 CYG_REPORT_RETVAL( ret ); |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
341 return ret; |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
342 } |
|
1aaed612fe59
* src/dns.c: (cyg_dns_res_start) New: Allow IPv6 to be used to
asl
parents:
1005
diff
changeset
|
343 |
| 1005 | 344 /* add_answer checks to see if we already have this answer and if not, |
| 345 adds it to the answers. */ | |
| 346 static int | |
| 347 add_answer(char *rdata, short rr_type, int family, | |
| 348 struct sockaddr addrs[], int num, int used) { | |
| 349 int i; | |
| 350 int found = 0; | |
| 351 | |
| 352 for (i = 0; i < used ; i++) { | |
| 353 if ((addrs[i].sa_family == family) && | |
| 354 !memcmp(addrs[i].sa_data, rdata, addrs[i].sa_len)) { | |
| 355 found = 1; | |
| 356 break; | |
| 357 } | |
| 358 } | |
| 359 if (!found) { | |
| 360 memset(&addrs[used],0,sizeof(addrs[used])); | |
| 361 addrs[used].sa_family = family; | |
| 362 | |
| 363 switch(family) { | |
| 364 case AF_INET: { | |
| 365 struct sockaddr_in * addr = (struct sockaddr_in *) &addrs[used]; | |
| 366 addr->sin_len = sizeof(*addr); | |
| 367 memcpy(&addr->sin_addr, rdata, sizeof(struct in_addr)); | |
| 368 used++; | |
| 369 break; | |
| 370 } | |
| 371 #ifdef CYGPKG_NET_INET6 | |
| 372 case AF_INET6: { | |
| 373 struct sockaddr_in6 * addr = (struct sockaddr_in6 *) &addrs[used]; | |
| 374 addr->sin6_len = sizeof(*addr); | |
| 375 memcpy(&addr->sin6_addr, rdata, sizeof(struct in6_addr)); | |
| 376 used++; | |
| 377 break; | |
| 378 } | |
| 379 #endif | |
| 380 default: | |
| 381 used = -EAI_FAMILY; | |
| 382 } | |
| 383 } | |
| 384 return used; | |
| 385 } | |
| 386 | |
| 387 /* This decodes the answer and puts the results into the addrs | |
| 388 array. This function can deal with IPv6 AAAA records as well as A | |
| 389 records. Thus its more complex than the parse_answer function in | |
| 390 the inline code. This complexity is only needed by getaddrinfo, so | |
| 391 i decided to leave parse_anser alone. */ | |
| 392 | |
| 393 static int | |
| 394 decode(char *msg, short rr_type, int family, | |
| 395 struct sockaddr addrs[], int num, int used, char **canon) { | |
| 396 | |
| 397 struct dns_header *dns_hdr; | |
| 398 struct resource_record rr, *rr_p = NULL; | |
| 399 char *qname = NULL; | |
| 400 char *ptr; | |
| 401 | |
| 402 dns_hdr = (struct dns_header *)msg; | |
| 403 | |
| 404 if (DNS_REPLY_NAME_ERROR == dns_hdr->rcode) { | |
| 405 h_errno = HOST_NOT_FOUND; | |
| 406 return -EAI_NONAME; | |
| 407 } | |
| 408 | |
| 409 if ((dns_hdr->qr != 1) || | |
| 410 (dns_hdr->opcode != DNS_QUERY)) { | |
| 411 return -EAI_FAIL; | |
| 412 } | |
| 413 | |
| 414 if (dns_hdr->rcode != DNS_REPLY_NOERR) { | |
| 415 return -EAI_NONAME; | |
| 416 } | |
| 417 | |
| 418 dns_hdr->ancount = ntohs(dns_hdr->ancount); | |
| 419 dns_hdr->qdcount = ntohs(dns_hdr->qdcount); | |
| 420 ptr = (char *)&dns_hdr[1]; | |
| 421 | |
| 422 /* Skip over the query section */ | |
| 423 if (dns_hdr->qdcount > 0) { | |
| 424 while (dns_hdr->qdcount) { | |
| 425 ptr += qname_len(ptr); | |
| 426 ptr += 4; /* skip type & class */ | |
| 427 dns_hdr->qdcount--; | |
| 428 } | |
| 429 } | |
| 430 | |
| 431 /* Read the answers resource records to find an answer of the | |
| 432 correct type. */ | |
| 433 while (dns_hdr->ancount && (used >= 0) && (used < num)) { | |
| 434 qname = ptr; | |
| 435 ptr += qname_len(ptr); | |
| 436 rr_p = (struct resource_record *)ptr; | |
| 437 memcpy(&rr, ptr, sizeof(rr)); | |
| 438 if ((rr.rr_type == htons(rr_type)) && | |
| 439 (rr.class == htons(DNS_CLASS_IN))) { | |
| 440 used = add_answer(rr_p->rdata, rr_type, family, addrs, num, used); | |
| 441 if (canon && !*canon) { | |
| 442 *canon = real_name(msg,qname); | |
| 443 } | |
| 444 } | |
| 445 ptr += sizeof(struct resource_record) - | |
| 446 sizeof(rr.rdata) + ntohs(rr.rdlength); | |
| 447 dns_hdr->ancount--; | |
| 448 } | |
| 449 if (used == 0) { | |
| 450 return -EAI_NONAME; | |
| 451 } | |
| 452 return used; | |
| 453 } | |
| 454 | |
| 455 /* Do a lookup for a particular type of resource record. */ | |
| 456 static int | |
| 457 do_lookup (const char * hostname, | |
| 458 struct sockaddr addrs[], int num, int used, | |
| 459 short rr_type, int family, char **canon) { | |
| 460 | |
| 461 unsigned char msg[MAXDNSMSGSIZE]; | |
| 462 int error; | |
| 463 int len; | |
| 464 | |
| 465 /* First try the name as passed in */ | |
| 466 memset(msg, 0, sizeof(msg)); | |
| 467 len = build_query(msg, hostname, rr_type); | |
| 468 if (len < 0) { | |
| 469 return -EAI_FAIL; | |
| 470 } | |
| 471 | |
| 472 /* Send the query and wait for an answer */ | |
| 473 len = send_recv(msg, len, sizeof(msg)); | |
| 474 if (len < 0) { | |
| 475 return -EAI_FAIL; | |
| 476 } | |
| 477 | |
| 478 /* Decode the answer */ | |
| 479 error = decode(msg, rr_type, family, addrs, num, used, canon); | |
| 480 return error; | |
| 481 } | |
| 482 | |
| 483 static int do_lookups(const char * hostname, | |
| 484 struct sockaddr addrs[], int num, | |
| 485 int family, char ** canon) { | |
| 486 int error; | |
| 487 #ifdef CYGPKG_NET_INET6 | |
| 488 int error6; | |
| 489 #endif | |
| 490 | |
| 491 switch (family) { | |
| 492 case AF_INET: | |
| 493 error = do_lookup(hostname, addrs, num, 0, DNS_TYPE_A, AF_INET, canon); | |
| 494 break; | |
| 495 #ifdef CYGPKG_NET_INET6 | |
| 496 case AF_INET6: | |
| 497 error = do_lookup(hostname, addrs, num, 0, DNS_TYPE_AAAA, AF_INET6, canon); | |
| 498 break; | |
| 499 #endif | |
| 500 case PF_UNSPEC: | |
| 501 #ifndef CYGPKG_NET_INET6 | |
| 502 error = do_lookup(hostname, addrs, num, 0, DNS_TYPE_A, AF_INET, canon); | |
| 503 #else | |
| 504 #ifdef CYGOPT_NS_DNS_FIRST_FAMILTY_AF_INET | |
| 505 error = do_lookup(hostname, addrs, num, 0, DNS_TYPE_A, AF_INET, canon); | |
| 506 if (error > 0 ) { | |
| 507 error6 = do_lookup(hostname, addrs, num, error, DNS_TYPE_AAAA, | |
| 508 AF_INET6, canon); | |
| 509 } else { | |
| 510 error6 = do_lookup(hostname, addrs, num, 0, DNS_TYPE_AAAA, | |
| 511 AF_INET6, canon); | |
| 512 } | |
| 513 if (error6 > 0) { | |
| 514 error = error6; | |
| 515 } | |
| 516 #else // CYGOPT_NS_DNS_FIRST_FAMILY_AF_INET | |
| 517 error6 = do_lookup(hostname, addrs, num, 0, DNS_TYPE_AAAA, | |
| 518 AF_INET6, canon); | |
| 519 if (error6> 0 ) { | |
| 520 error = do_lookup(hostname, addrs, num, error6, DNS_TYPE_A, | |
| 521 AF_INET, canon); | |
| 522 } else { | |
| 523 error = do_lookup(hostname, addrs, num, 0, DNS_TYPE_A, | |
| 524 AF_INET, canon); | |
| 525 } | |
| 526 #endif // CYGOPT_NS_DNS_FIRST_FAMILY_AF_INET | |
| 527 #endif // CYGPKG_NET_INET6 | |
| 528 break; | |
| 529 default: | |
| 530 error = -EAI_FAMILY; | |
| 531 } | |
| 532 return error; | |
| 533 } | |
| 534 | |
| 535 /* This implements the interface between getaddrinfo and the dns | |
| 536 client. hostent is not used here since that only works with IPv4 | |
| 537 addresses, where as this function needs to be protocol | |
| 538 independent. */ | |
| 539 int | |
| 540 cyg_dns_getaddrinfo(const char * hostname, | |
| 541 struct sockaddr addrs[], int num, | |
| 542 int family, | |
| 543 char ** canon) | |
| 544 { | |
| 545 int error; | |
| 546 char name[256]; | |
| 547 char * dot; | |
| 548 | |
| 549 CYG_REPORT_FUNCNAMETYPE( "cyg_dns_getaddrinfo", "returning %08x" ); | |
| 550 CYG_REPORT_FUNCARG3( "hostname=%08x, addrs=%08x, num=%2d", | |
| 551 hostname, addrs, num ); | |
| 552 | |
| 553 if ( !hostname || !addrs || !num ) { | |
| 554 CYG_REPORT_RETVAL( NULL ); | |
| 555 return -EAI_FAIL; | |
| 556 } | |
| 557 | |
| 558 CYG_CHECK_DATA_PTR( hostname, "hostname is not a valid pointer!" ); | |
| 559 CYG_CHECK_DATA_PTR( addrs, "addrs is not a valid pointer!"); | |
| 560 CYG_ASSERT( num > 0, "Invalid number of sockaddr stuctures"); | |
| 561 | |
| 562 if (!valid_hostname(hostname)) { | |
| 563 /* it could be a dot address */ | |
| 564 struct sockaddr_in * sa4 = (struct sockaddr_in *)&addrs[0]; | |
| 565 memset(&addrs[0],0,sizeof(struct sockaddr)); | |
| 566 if (inet_pton(AF_INET, hostname, (char *)&sa4->sin_addr.s_addr)) { | |
| 567 sa4->sin_family = AF_INET; | |
| 568 sa4->sin_len = sizeof(*sa4); | |
| 569 CYG_REPORT_RETVAL (1); | |
| 570 return 1; | |
| 571 } | |
| 572 #ifdef CYGPKG_NET_INET6 | |
| 573 { | |
| 574 /* it could be a colon address */ | |
| 575 struct sockaddr_in6 * sa6 = (struct sockaddr_in6 *)&addrs[0]; | |
| 576 memset(&addrs[0],0,sizeof(struct sockaddr)); | |
| 577 if (inet_pton(AF_INET6, hostname, (char *)&sa6->sin6_addr.s6_addr)) { | |
| 578 sa6->sin6_family = AF_INET6; | |
| 579 sa6->sin6_len = sizeof(*sa6); | |
| 580 CYG_REPORT_RETVAL (1); | |
| 581 return 1; | |
| 582 } | |
| 583 } | |
| 584 #endif | |
| 585 CYG_REPORT_RETVAL (-EAI_NONAME); | |
| 586 return -EAI_NONAME; | |
| 587 } | |
| 588 | |
| 589 /* Has the socket to the DNS server been opened? */ | |
| 590 if (s < 0) { | |
|
1691
c81db0785971
* src/dns.c (cyg_dns_getaddrinfo): Typo spotted by Andy Jackson.
asl
parents:
1069
diff
changeset
|
591 CYG_REPORT_RETVAL( -EAI_FAIL ); |
| 1005 | 592 return -EAI_FAIL; |
| 593 } | |
| 594 | |
| 595 if (domainname) { | |
| 596 if ((strlen(hostname) + strlen(domainname)) > 254) { | |
| 597 cyg_drv_mutex_unlock(&dns_mutex); | |
| 598 CYG_REPORT_RETVAL( -EAI_FAIL ); | |
| 599 return -EAI_FAIL; | |
| 600 } | |
| 601 strcpy(name, hostname); | |
| 602 strcat(name, "."); | |
| 603 strcat(name, domainname); | |
| 604 } | |
| 605 cyg_drv_mutex_lock(&dns_mutex); | |
| 606 | |
| 607 /* If the hostname ends with . it a FQDN. Don't bother adding the | |
| 608 domainname. If it does not contain a . , try appending with the | |
| 609 domainname first. If it does have a . , try without a domain name | |
| 610 first. */ | |
| 611 | |
| 612 dot = rindex(hostname,'.'); | |
| 613 if (dot) { | |
| 614 if (*(dot+1) == '\0') { | |
| 615 /* FQDN */ | |
| 616 error = do_lookups(hostname, addrs, num, family, canon); | |
| 617 } else { | |
| 618 /* Dot somewhere */ | |
| 619 error = do_lookups(hostname, addrs, num, family, canon); | |
| 620 if (domainname && (error == -EAI_NONAME)) { | |
| 621 error = do_lookups(name, addrs, num, family, canon); | |
| 622 } | |
| 623 } | |
| 624 } else { | |
| 625 /* No Dot. Try adding domainname first */ | |
| 626 error = -EAI_NONAME; | |
| 627 if (domainname) { | |
| 628 error = do_lookups(name, addrs, num, family, canon); | |
| 629 } | |
| 630 if (error == -EAI_NONAME) { | |
| 631 error = do_lookups(hostname, addrs, num, family, canon); | |
| 632 } | |
| 633 } | |
| 634 cyg_drv_mutex_unlock(&dns_mutex); | |
| 635 CYG_REPORT_RETVAL( error ); | |
| 636 return error; | |
| 637 } | |
| 638 | |
| 639 /* This implements the interface between getnameinfo and the dns | |
| 640 client. */ | |
| 641 externC int | |
| 642 cyg_dns_getnameinfo(const struct sockaddr * sa, char * host, size_t hostlen) | |
| 643 { | |
| 644 char hostname[80]; | |
| 645 unsigned char msg[MAXDNSMSGSIZE]; | |
| 646 struct hostent * hent; | |
| 647 int len; | |
| 648 | |
| 649 CYG_REPORT_FUNCNAMETYPE( "cyg_dns_getnameinfo", "returning %08x" ); | |
| 650 CYG_REPORT_FUNCARG3( "sa=%08x, host=%08x, hostlen=%3d", | |
| 651 sa, host, hostlen ); | |
| 652 | |
| 653 CYG_CHECK_DATA_PTR( sa, "sa is not a valid pointer"); | |
| 654 CYG_CHECK_DATA_PTR( host, "host is not a valid data pointer"); | |
| 655 CYG_ASSERT(hostlen >0, "Invalid host length"); | |
| 656 | |
| 657 /* Has the socket to the DNS server been opened? */ | |
| 658 if (s < 0) { | |
| 1692 | 659 CYG_REPORT_RETVAL( -EAI_FAIL ); |
| 1005 | 660 return -EAI_FAIL; |
| 661 } | |
| 662 | |
| 663 cyg_drv_mutex_lock(&dns_mutex); | |
| 664 | |
| 665 switch (sa->sa_family) { | |
| 666 case AF_INET: { | |
| 667 struct sockaddr_in * sa4 = (struct sockaddr_in *)sa; | |
| 668 unsigned char * addr = (char *)&sa4->sin_addr.s_addr; | |
| 669 sprintf(hostname, "%d.%d.%d.%d.IN-ADDR.ARPA.", | |
| 670 addr[3],addr[2],addr[1],addr[0]); | |
| 671 break; | |
| 672 } | |
| 673 #ifdef CYGPKG_NET_INET6 | |
| 674 case AF_INET6: { | |
| 675 struct sockaddr_in6 * sa6 = (struct sockaddr_in6 *)sa; | |
| 676 int i; | |
| 677 | |
| 678 for (i=15; i >= 0; i--) { | |
| 679 sprintf(&hostname[(15*2*2) - (i*2*2)], "%x.%x.", | |
| 680 sa6->sin6_addr.s6_addr[i] & 0x0f, | |
| 681 (sa6->sin6_addr.s6_addr[i] & 0xf0) >> 4); | |
| 682 } | |
| 683 sprintf(&hostname[16*2*2],"IP6.INT"); | |
| 684 break; | |
| 685 } | |
| 686 #endif | |
| 687 default: | |
| 688 cyg_drv_mutex_lock(&dns_mutex); | |
| 689 CYG_REPORT_RETVAL( -EAI_FAMILY); | |
| 690 return -EAI_FAMILY; | |
| 691 } | |
| 692 | |
| 693 memset(msg, 0, sizeof(msg)); | |
| 694 | |
| 695 /* Build a PTR type request using the hostname */ | |
| 696 len = build_query(msg, hostname, DNS_TYPE_PTR); | |
| 697 if (len < 0) { | |
| 698 cyg_drv_mutex_unlock(&dns_mutex); | |
| 699 CYG_REPORT_RETVAL( -EAI_FAIL ); | |
| 700 return -EAI_FAIL; | |
| 701 } | |
| 702 | |
| 703 /* Send the request and wait for an answer */ | |
| 704 len = send_recv(msg, len, sizeof(msg)); | |
| 705 if (len < 0) { | |
| 706 cyg_drv_mutex_unlock(&dns_mutex); | |
| 707 CYG_REPORT_RETVAL( -EAI_FAIL ); | |
| 708 return -EAI_FAIL; | |
| 709 } | |
| 710 | |
| 711 /* Parse the answer for the host name */ | |
| 712 hent = parse_answer(msg, DNS_TYPE_PTR); | |
| 713 | |
| 714 /* If no name is known return an error */ | |
| 715 if (!hent) { | |
| 716 cyg_drv_mutex_unlock(&dns_mutex); | |
| 717 CYG_REPORT_RETVAL( -EAI_NONAME ); | |
| 718 return -EAI_NONAME; | |
| 719 } | |
| 720 | |
| 721 /* Otherwise copy it into our results buffer and tidy up */ | |
| 722 strncpy(host, hent->h_name,hostlen); | |
| 723 free_hent(hent); | |
| 724 | |
| 725 cyg_drv_mutex_unlock(&dns_mutex); | |
| 726 CYG_REPORT_RETVAL( -EAI_NONE ); | |
| 727 return -EAI_NONE; | |
| 728 } |
