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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [redboot/] [v2_0/] [src/] [net/] [dns.c] - Blame information for rev 1773

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

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

powered by: WebSVN 2.1.0

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