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