sl@0
|
1 |
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// Support for hostname & hostaddr related functions
|
sl@0
|
15 |
//
|
sl@0
|
16 |
//
|
sl@0
|
17 |
|
sl@0
|
18 |
#include "SYSIF.H"
|
sl@0
|
19 |
#include "FDESC.H"
|
sl@0
|
20 |
#include <unistd.h>
|
sl@0
|
21 |
#include <stdlib.h>
|
sl@0
|
22 |
#include <sys/errno.h>
|
sl@0
|
23 |
#include "LPOSIX.H"
|
sl@0
|
24 |
#include <sys/socket.h>
|
sl@0
|
25 |
#include <libc/netinet/in.h>
|
sl@0
|
26 |
#include <netdb_r.h>
|
sl@0
|
27 |
#include <string.h>
|
sl@0
|
28 |
#include <in_sock.h>
|
sl@0
|
29 |
#include <networking/dnd_err.h>
|
sl@0
|
30 |
|
sl@0
|
31 |
extern "C" {
|
sl@0
|
32 |
|
sl@0
|
33 |
/**
|
sl@0
|
34 |
Get the internet name of this host. Actually this will always return a null
|
sl@0
|
35 |
string with TCPIP 030 and onwards because the "name" of a mobile host
|
sl@0
|
36 |
isn't really very meaningful - in practice the IP address is chosen dynamically
|
sl@0
|
37 |
once you start doing real networking, at which time the ISP can resolve the
|
sl@0
|
38 |
IP address into a name of some sort if you really want.
|
sl@0
|
39 |
@return
|
sl@0
|
40 |
@param name
|
sl@0
|
41 |
@param size
|
sl@0
|
42 |
*/
|
sl@0
|
43 |
EXPORT_C int gethostname (char *name, size_t size)
|
sl@0
|
44 |
{
|
sl@0
|
45 |
int* perrno=__errno();
|
sl@0
|
46 |
RSocketServ ss;
|
sl@0
|
47 |
TInt err=ss.Connect(1);
|
sl@0
|
48 |
if (err==KErrNone)
|
sl@0
|
49 |
{
|
sl@0
|
50 |
RHostResolver r;
|
sl@0
|
51 |
err=r.Open(ss, AF_INET, KProtocolInetUdp);
|
sl@0
|
52 |
if (err==KErrNone)
|
sl@0
|
53 |
{
|
sl@0
|
54 |
TBuf<128> hostname;
|
sl@0
|
55 |
err=r.GetHostName(hostname);
|
sl@0
|
56 |
if (err==KErrNone)
|
sl@0
|
57 |
{
|
sl@0
|
58 |
if (size>(size_t)hostname.Length())
|
sl@0
|
59 |
{
|
sl@0
|
60 |
TPtr8 retval((TText8*)name,size);
|
sl@0
|
61 |
retval.Copy(hostname);
|
sl@0
|
62 |
retval.PtrZ();
|
sl@0
|
63 |
}
|
sl@0
|
64 |
else
|
sl@0
|
65 |
err=ENAMETOOLONG;
|
sl@0
|
66 |
}
|
sl@0
|
67 |
r.Close();
|
sl@0
|
68 |
}
|
sl@0
|
69 |
ss.Close();
|
sl@0
|
70 |
}
|
sl@0
|
71 |
return MapError(err,*perrno);
|
sl@0
|
72 |
}
|
sl@0
|
73 |
|
sl@0
|
74 |
/**
|
sl@0
|
75 |
Get the internet name of the host by address.
|
sl@0
|
76 |
@return
|
sl@0
|
77 |
@param addr Address of the host
|
sl@0
|
78 |
@param length
|
sl@0
|
79 |
@param format
|
sl@0
|
80 |
*/
|
sl@0
|
81 |
EXPORT_C struct hostent* gethostbyaddr (const char* addr, int length, int format)
|
sl@0
|
82 |
{
|
sl@0
|
83 |
return _gethostbyaddr_r(_REENT,addr,length,format);
|
sl@0
|
84 |
}
|
sl@0
|
85 |
|
sl@0
|
86 |
/**
|
sl@0
|
87 |
Get the internet name of the host by name.
|
sl@0
|
88 |
@return
|
sl@0
|
89 |
@param name Name of the host
|
sl@0
|
90 |
*/
|
sl@0
|
91 |
EXPORT_C struct hostent* gethostbyname (const char* name)
|
sl@0
|
92 |
{
|
sl@0
|
93 |
return _gethostbyname_r(_REENT,name);
|
sl@0
|
94 |
}
|
sl@0
|
95 |
|
sl@0
|
96 |
enum GetHostType {ByName = 1, ByAddr};
|
sl@0
|
97 |
|
sl@0
|
98 |
#define MAX_ADDR_OR_ALIAS_LIST 5
|
sl@0
|
99 |
|
sl@0
|
100 |
struct hostent_buf
|
sl@0
|
101 |
{
|
sl@0
|
102 |
struct hostent iHostent;
|
sl@0
|
103 |
char *iAliasesPtr[MAX_ADDR_OR_ALIAS_LIST+1];
|
sl@0
|
104 |
char *iAddrListPtr[MAX_ADDR_OR_ALIAS_LIST+1];
|
sl@0
|
105 |
THostName iHostAliases[MAX_ADDR_OR_ALIAS_LIST];
|
sl@0
|
106 |
struct sockaddr iHostAddress[MAX_ADDR_OR_ALIAS_LIST];
|
sl@0
|
107 |
};
|
sl@0
|
108 |
|
sl@0
|
109 |
struct hostent* mapNameRecord(struct _reent* rp, TFixedArray<TNameRecord, MAX_ADDR_OR_ALIAS_LIST>& aRecord, const TInt aCount, const GetHostType aHostType, const int aLength, const int aFormat)
|
sl@0
|
110 |
{
|
sl@0
|
111 |
free(rp->_netdb);
|
sl@0
|
112 |
struct hostent_buf* hbp = (struct hostent_buf*)calloc(1,sizeof(struct hostent_buf));
|
sl@0
|
113 |
rp->_netdb = hbp;
|
sl@0
|
114 |
if (hbp==0)
|
sl@0
|
115 |
{
|
sl@0
|
116 |
rp->_errno=ENOMEM;
|
sl@0
|
117 |
return 0;
|
sl@0
|
118 |
}
|
sl@0
|
119 |
|
sl@0
|
120 |
// Set-up Aliases & Address list pointer
|
sl@0
|
121 |
hbp->iHostent.h_aliases = &hbp->iAliasesPtr[0];
|
sl@0
|
122 |
hbp->iHostent.h_addr_list = &hbp->iAddrListPtr[0];
|
sl@0
|
123 |
|
sl@0
|
124 |
// Fill-up Host Name
|
sl@0
|
125 |
hbp->iHostent.h_name = (char*) &hbp->iHostAliases[0];
|
sl@0
|
126 |
TPtr8 name((TText8*)&hbp->iHostAliases[0], aRecord[0].iName.Length()+1);
|
sl@0
|
127 |
name.Copy(aRecord[0].iName);
|
sl@0
|
128 |
name.ZeroTerminate();
|
sl@0
|
129 |
|
sl@0
|
130 |
hbp->iHostent.h_addrtype = aFormat;
|
sl@0
|
131 |
hbp->iHostent.h_length = aLength;
|
sl@0
|
132 |
|
sl@0
|
133 |
// Fill-up Address
|
sl@0
|
134 |
hbp->iAddrListPtr[0] = (char*)&hbp->iHostAddress[0].sa_data[0]; // ... which is iAddr
|
sl@0
|
135 |
unsigned long len=sizeof(struct sockaddr);
|
sl@0
|
136 |
aRecord[0].iAddr.SetFamily(aFormat); // not set by GetByName(_L(""));
|
sl@0
|
137 |
STATIC_CAST(TUSockAddr*,&aRecord[0].iAddr)->Get(&hbp->iHostAddress[0],&len);
|
sl@0
|
138 |
|
sl@0
|
139 |
if (aCount > 1)
|
sl@0
|
140 |
{
|
sl@0
|
141 |
// If there are multiple host name or address
|
sl@0
|
142 |
TInt i;
|
sl@0
|
143 |
if (aHostType == ByName)
|
sl@0
|
144 |
{
|
sl@0
|
145 |
// there are multiple addresses for a given host
|
sl@0
|
146 |
hbp->iAliasesPtr[0] = NULL;
|
sl@0
|
147 |
for (i=1; i<aCount; i++)
|
sl@0
|
148 |
{
|
sl@0
|
149 |
hbp->iAddrListPtr[i] = (char*)&hbp->iHostAddress[i].sa_data[0];
|
sl@0
|
150 |
len=sizeof(struct sockaddr);
|
sl@0
|
151 |
aRecord[i].iAddr.SetFamily(aFormat); // not set by GetByName(_L(""));
|
sl@0
|
152 |
STATIC_CAST(TUSockAddr*,&aRecord[i].iAddr)->Get(&hbp->iHostAddress[i],&len);
|
sl@0
|
153 |
}
|
sl@0
|
154 |
hbp->iAddrListPtr[i] = NULL;
|
sl@0
|
155 |
}
|
sl@0
|
156 |
else
|
sl@0
|
157 |
{
|
sl@0
|
158 |
// there are multiple host/aliases name for a given address
|
sl@0
|
159 |
hbp->iAddrListPtr[1] = NULL;
|
sl@0
|
160 |
for (i=1; i<aCount; i++)
|
sl@0
|
161 |
{
|
sl@0
|
162 |
hbp->iAliasesPtr[i-1] = (char*) &hbp->iHostAliases[i];
|
sl@0
|
163 |
name.Set((TText8*)&hbp->iHostAliases[i], 0, aRecord[i].iName.Length()+1);
|
sl@0
|
164 |
name.Copy(aRecord[i].iName);
|
sl@0
|
165 |
name.ZeroTerminate();
|
sl@0
|
166 |
}
|
sl@0
|
167 |
hbp->iAliasesPtr[i-1] = NULL;
|
sl@0
|
168 |
}
|
sl@0
|
169 |
}
|
sl@0
|
170 |
else
|
sl@0
|
171 |
{
|
sl@0
|
172 |
hbp->iAliasesPtr[0] = NULL;
|
sl@0
|
173 |
hbp->iAddrListPtr[1] = NULL;
|
sl@0
|
174 |
}
|
sl@0
|
175 |
return &hbp->iHostent;
|
sl@0
|
176 |
}
|
sl@0
|
177 |
|
sl@0
|
178 |
/**
|
sl@0
|
179 |
Get the internet name of the host by address.
|
sl@0
|
180 |
@return
|
sl@0
|
181 |
@param rp pointer
|
sl@0
|
182 |
@param addr
|
sl@0
|
183 |
@param length
|
sl@0
|
184 |
@param format
|
sl@0
|
185 |
*/
|
sl@0
|
186 |
EXPORT_C struct hostent* _gethostbyaddr_r (struct _reent* rp, const char* addr, int length, int format)
|
sl@0
|
187 |
//
|
sl@0
|
188 |
// For AF_INET,
|
sl@0
|
189 |
{
|
sl@0
|
190 |
RSocketServ ss;
|
sl@0
|
191 |
TInt err=ss.Connect();
|
sl@0
|
192 |
struct hostent* retval=0;
|
sl@0
|
193 |
if (err==KErrNone)
|
sl@0
|
194 |
{
|
sl@0
|
195 |
RHostResolver r;
|
sl@0
|
196 |
err=r.Open(ss, AF_INET, KProtocolInetUdp);
|
sl@0
|
197 |
if (err==KErrNone)
|
sl@0
|
198 |
{
|
sl@0
|
199 |
struct sockaddr buf;
|
sl@0
|
200 |
buf.sa_family=(unsigned short)format;
|
sl@0
|
201 |
memcpy(buf.sa_data,addr,length);
|
sl@0
|
202 |
TUSockAddr addr(&buf,length+4);
|
sl@0
|
203 |
|
sl@0
|
204 |
TFixedArray<TNameRecord, MAX_ADDR_OR_ALIAS_LIST> record;
|
sl@0
|
205 |
TNameEntry entry;
|
sl@0
|
206 |
TInt count = 0;
|
sl@0
|
207 |
err=r.GetByAddress(addr,entry);
|
sl@0
|
208 |
if (err==KErrNone)
|
sl@0
|
209 |
{
|
sl@0
|
210 |
record[count++]=entry();
|
sl@0
|
211 |
while ((r.Next(entry) == KErrNone) && (count < MAX_ADDR_OR_ALIAS_LIST))
|
sl@0
|
212 |
{
|
sl@0
|
213 |
record[count++] = entry();
|
sl@0
|
214 |
}
|
sl@0
|
215 |
retval = mapNameRecord(rp, record, count, ByAddr, length, format);
|
sl@0
|
216 |
}
|
sl@0
|
217 |
r.Close();
|
sl@0
|
218 |
}
|
sl@0
|
219 |
ss.Close();
|
sl@0
|
220 |
}
|
sl@0
|
221 |
if (err==-3004) // NETDIAL busy
|
sl@0
|
222 |
err=TRY_AGAIN;
|
sl@0
|
223 |
|
sl@0
|
224 |
// KErrDndAddrNotFound=-5121 should be excluded (Returned when no data found for GetByAddr)
|
sl@0
|
225 |
if ((err<-3000) && (err!=KErrDndAddrNotFound)) // i.e. a NETDIAL error
|
sl@0
|
226 |
err=NO_RECOVERY;
|
sl@0
|
227 |
MapError(err,rp->_errno);
|
sl@0
|
228 |
return retval;
|
sl@0
|
229 |
}
|
sl@0
|
230 |
|
sl@0
|
231 |
/**
|
sl@0
|
232 |
Get the internet name of the host by name.
|
sl@0
|
233 |
@return
|
sl@0
|
234 |
@param rp
|
sl@0
|
235 |
@param name name of the host
|
sl@0
|
236 |
*/
|
sl@0
|
237 |
EXPORT_C struct hostent* _gethostbyname_r (struct _reent* rp, const char* name)
|
sl@0
|
238 |
{
|
sl@0
|
239 |
RSocketServ ss;
|
sl@0
|
240 |
TInt err=ss.Connect();
|
sl@0
|
241 |
struct hostent* retval=0;
|
sl@0
|
242 |
if (err==KErrNone)
|
sl@0
|
243 |
{
|
sl@0
|
244 |
RHostResolver r;
|
sl@0
|
245 |
err=r.Open(ss, AF_INET, KProtocolInetUdp);
|
sl@0
|
246 |
if (err==KErrNone)
|
sl@0
|
247 |
{
|
sl@0
|
248 |
TFixedArray<TNameRecord, MAX_ADDR_OR_ALIAS_LIST> record;
|
sl@0
|
249 |
TNameEntry entry;
|
sl@0
|
250 |
#ifdef _UNICODE
|
sl@0
|
251 |
TPtrC8 ptr(REINTERPRET_CAST(const TUint8*,name));
|
sl@0
|
252 |
TBuf<0x40> hostname;
|
sl@0
|
253 |
hostname.Copy(ptr);
|
sl@0
|
254 |
#else
|
sl@0
|
255 |
TPtrC8 hostname(REINTERPRET_CAST(const TUint8*,name));
|
sl@0
|
256 |
#endif /* _UNICODE */
|
sl@0
|
257 |
|
sl@0
|
258 |
TInt count = 0;
|
sl@0
|
259 |
err=r.GetByName(hostname,entry);
|
sl@0
|
260 |
if (err==KErrNone)
|
sl@0
|
261 |
{
|
sl@0
|
262 |
record[count++]=entry();
|
sl@0
|
263 |
while ((r.Next(entry) == KErrNone) && (count < MAX_ADDR_OR_ALIAS_LIST))
|
sl@0
|
264 |
{
|
sl@0
|
265 |
record[count++] = entry();
|
sl@0
|
266 |
}
|
sl@0
|
267 |
retval = mapNameRecord(rp, record, count, ByName, sizeof(struct in_addr), AF_INET);
|
sl@0
|
268 |
}
|
sl@0
|
269 |
r.Close();
|
sl@0
|
270 |
}
|
sl@0
|
271 |
ss.Close();
|
sl@0
|
272 |
}
|
sl@0
|
273 |
if (err==-3004) // NETDIAL busy
|
sl@0
|
274 |
err=TRY_AGAIN;
|
sl@0
|
275 |
|
sl@0
|
276 |
// KErrDndNameNotFound=-5120 should be excluded (Returned when no data found for GetByName)
|
sl@0
|
277 |
if ((err<-3000) && (err!=KErrDndNameNotFound)) // i.e. a NETDIAL error
|
sl@0
|
278 |
err=NO_RECOVERY;
|
sl@0
|
279 |
MapError(err,rp->_errno);
|
sl@0
|
280 |
return retval;
|
sl@0
|
281 |
}
|
sl@0
|
282 |
|
sl@0
|
283 |
} // extern "C"
|