OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [redboot/] [current/] [src/] [net/] [dns.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//=============================================================================
2
//
3
//      dns.c
4
//
5
//      DNS client code
6
//
7
//=============================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//=============================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):   jskov
43
// Contributors:jskov
44
// Date:        2001-09-26
45
// Description: Provides DNS lookup as per RFC 1034/1035.
46
// 
47
// Note:        This is a stripped down clone of dns.c from the CYGPKG_NS_DNS
48
//              package which does not use malloc/free and has been tweaked to
49
//              use UDP via RedBoot's network stack. Also adds commands
50
//              to set the DNS server IP at runtime.
51
//
52
//####DESCRIPTIONEND####
53
//
54
//=============================================================================
55
 
56
#include <cyg/hal/drv_api.h>
57
#include <cyg/infra/cyg_type.h>
58
#include <cyg/infra/cyg_trac.h>         /* Tracing support */
59
 
60
#include <net/net.h>
61
#include <redboot.h>
62
/* #include <cyg/ns/dns/dns.h> - it's been moved to redboot.h */
63
#include <cyg/ns/dns/dns_priv.h>
64
 
65
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
66
#include <flash_config.h>
67
 
68
RedBoot_config_option("DNS server IP address",
69
                      dns_ip,
70
                      ALWAYS_ENABLED, true,
71
                      CONFIG_IP,
72
 
73
    );
74
 
75
RedBoot_config_option("DNS domain name",
76
                      dns_domain,
77
                      ALWAYS_ENABLED, true,
78
                      CONFIG_STRING,
79
                      ""
80
        );
81
#endif
82
 
83
/* So we remember which ports have been used */
84
static int get_port = 7700;
85
 
86
#define DOMAIN_PORT           53
87
 
88
/* Some magic to make dns_impl.inl compile under RedBoot */
89
#define sprintf diag_sprintf
90
 
91
/* DNS server address possibly returned from bootp */
92
struct in_addr __bootp_dns_addr;
93
cyg_bool __bootp_dns_set = false;
94
 
95
/* DNS domain name possibly returned from bootp */
96
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_DHCP_DOMAIN
97
char __bootp_dns_domain[CYGNUM_REDBOOT_NETWORK_DNS_DOMAIN_BUFSIZE];
98
cyg_bool __bootp_dns_domain_set = false;
99
#endif
100
 
101
struct sockaddr_in server;
102
 
103
/* static buffers so we can make do without malloc */
104
static struct hostent _hent;
105
static char* _h_addr_list[2];
106
static struct in_addr _h_addr_list0;
107
static int _hent_alloc = 0;
108
 
109
#define _STRING_COUNT  2
110
#define _STRING_LENGTH 64
111
static char _strings[_STRING_COUNT][_STRING_LENGTH];
112
static int _strings_alloc = 0;
113
 
114
/* as in dns.c proper */
115
static short id = 0;              /* ID of the last query */
116
static int s = -1;                /* Socket to the DNS server */
117
static cyg_drv_mutex_t dns_mutex; /* Mutex to stop multiple queries as once */
118
static char * domainname=NULL;    /* Domain name used for queries */
119
 
120
 
121
/* Allocate space for string of length (len). Return NULL on
122
   failure. */
123
static char*
124
alloc_string(int len)
125
{
126
    int i;
127
 
128
    if (len > _STRING_LENGTH)
129
        return NULL;
130
 
131
    for (i = 0; i < _STRING_COUNT; i++) {
132
        if (_strings_alloc & (1 << i)) continue;
133
        _strings_alloc |= (1<<i);
134
        return _strings[i];
135
    }
136
    return NULL;
137
}
138
 
139
static void
140
free_string(char* s)
141
{
142
    int i;
143
    for (i = 0; i < _STRING_COUNT; i++) {
144
        if (_strings[i] == s) {
145
            _strings_alloc &= ~(1<<i);
146
            break;
147
        }
148
    }
149
}
150
 
151
/* Deallocate the memory taken to hold a hent structure */
152
static void
153
free_hent(struct hostent * hent)
154
{
155
    if (hent->h_name) {
156
        free_string(hent->h_name);
157
    }
158
    _hent_alloc = 0;
159
}
160
 
161
/* Allocate hent structure with room for one in_addr. Returns NULL on
162
   failure. */
163
static struct hostent*
164
alloc_hent(void)
165
{
166
    struct hostent *hent;
167
 
168
    if (_hent_alloc) return NULL;
169
 
170
    hent = &_hent;
171
    memset(hent, 0, sizeof(struct hostent));
172
    hent->h_addr_list = _h_addr_list;
173
    hent->h_addr_list[0] = (char*)&_h_addr_list0;
174
    hent->h_addr_list[1] = NULL;
175
    _hent_alloc = 1;
176
 
177
    return hent;
178
}
179
 
180
static __inline__ void
181
free_stored_hent(void)
182
{
183
    free_hent( &_hent );
184
}
185
 
186
static __inline__ void
187
store_hent(struct hostent *hent)
188
{
189
    hent=hent; // avoid warning
190
}
191
 
192
/* Send the query to the server and read the response back. Return -1
193
   if it fails, otherwise put the response back in msg and return the
194
   length of the response. */
195
static int
196
send_recv(char * msg, int len, int msglen)
197
{
198
    struct dns_header *dns_hdr;
199
    int finished = false;
200
    int read = 0;
201
 
202
    dns_hdr = (struct dns_header *) msg;
203
 
204
    do {
205
        int len_togo = len;
206
        struct timeval timeout;
207
        struct sockaddr_in local_addr, from_addr;
208
 
209
        memset((char *)&local_addr, 0, sizeof(local_addr));
210
        local_addr.sin_family = AF_INET;
211
        local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
212
        local_addr.sin_port = htons(get_port++);
213
 
214
        if (__udp_sendto(msg, len_togo, &server, &local_addr) < 0)
215
            return -1;
216
 
217
        memset((char *)&from_addr, 0, sizeof(from_addr));
218
 
219
        timeout.tv_sec = CYGNUM_REDBOOT_NETWORKING_DNS_TIMEOUT;
220
        timeout.tv_usec = 0;
221
 
222
        read = __udp_recvfrom(msg, len, &from_addr, &local_addr, &timeout);
223
        if (read < 0)
224
            return -1;
225
 
226
        /* Reply to an old query. Ignore it */
227
        if (ntohs(dns_hdr->id) != (id-1)) {
228
            continue;
229
        }
230
        finished = true;
231
    } while (!finished);
232
 
233
    return read;
234
}
235
 
236
void
237
set_dns(char* new_ip)
238
{
239
    in_addr_t dns_ip;
240
 
241
    memset(&server.sin_addr, 0, sizeof(server.sin_addr));
242
    if (!inet_aton(new_ip, &dns_ip)) {
243
        diag_printf("Bad DNS server address: %s\n", new_ip);
244
    } else {
245
        memcpy(&server.sin_addr, &dns_ip, sizeof(dns_ip));
246
        /* server config is valid */
247
        s = 0;
248
    }
249
}
250
 
251
void
252
show_dns(void)
253
{
254
    diag_printf("\nDNS server IP: %s, DNS domain name: %s",
255
                inet_ntoa((in_addr_t *)&server.sin_addr),
256
                domainname);
257
    if (0 == server.sin_addr.s_addr) {
258
        s = -1;
259
    }
260
}
261
 
262
/* Initialise the resolver. Open a socket and bind it to the address
263
   of the server.  return -1 if something goes wrong, otherwise 0 */
264
int
265
redboot_dns_res_init(void)
266
{
267
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN
268
  char *dns_domain = NULL;
269
#endif
270
    memset((char *)&server, 0, sizeof(server));
271
    server.sin_len = sizeof(server);
272
    server.sin_family = AF_INET;
273
    server.sin_port = htons(DOMAIN_PORT);
274
    cyg_drv_mutex_init(&dns_mutex);
275
 
276
    /* Set the default DNS domain first, so that it can be overwritten
277
       latter */
278
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_DEFAULT_DOMAIN
279
        setdomainname(__Xstr(CYGPKG_REDBOOT_NETWORKING_DNS_DEFAULT_DOMAIN),
280
                      strlen(__Xstr(CYGPKG_REDBOOT_NETWORKING_DNS_DEFAULT_DOMAIN)));
281
#endif
282
        /* Set the domain name from flash so that DHCP can later
283
           overwrite it. */
284
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN
285
        flash_get_config("dns_domain", &dns_domain, CONFIG_STRING);
286
        if(dns_domain != NULL && dns_domain[0] != '\0')
287
                setdomainname(dns_domain, strlen(dns_domain));
288
#endif
289
 
290
    /* If we got a DNS server address from the DHCP/BOOTP, then use
291
       that address */
292
    if ( __bootp_dns_set ) {
293
        memcpy(&server.sin_addr, &__bootp_dns_addr,
294
               sizeof(__bootp_dns_addr) );
295
 
296
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_DHCP_DOMAIN        
297
        if(__bootp_dns_domain_set)
298
            setdomainname(__bootp_dns_domain, strlen(__bootp_dns_domain));
299
#endif
300
        /* server config is valid */
301
        s = 0;
302
    }
303
    else {
304
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
305
    {
306
        ip_addr_t dns_ip;
307
 
308
        flash_get_config("dns_ip", &dns_ip, CONFIG_IP);
309
        if (dns_ip[0] == 0 && dns_ip[1] == 0 &&
310
            dns_ip[2] == 0 && dns_ip[3] == 0)
311
            return -1;
312
        memcpy(&server.sin_addr, &dns_ip, sizeof(dns_ip));
313
        /* server config is valid */
314
        s = 0;
315
    }
316
#else
317
    // Use static configuration. If CYGPKG_REDBOOT_NETWORKING_DNS_IP
318
    // is valid s will set set as a side effect.
319
    set_dns(__Xstr(CYGPKG_REDBOOT_NETWORKING_DNS_IP));
320
#endif
321
    }
322
 
323
    return 0;
324
}
325
 
326
/* Include the DNS client implementation code */
327
#include <cyg/ns/dns/dns_impl.inl>

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.