]>
git.saurik.com Git - apt.git/blob - methods/rfc2553emu.cc
1b0628f98457487b422941a43d4091f6b9cf74b7
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: rfc2553emu.cc,v 1.2 1999/05/26 04:08:39 jgg Exp $
4 /* ######################################################################
6 RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo,
7 freeaddrinfo and getnameinfo
9 Originally written by Jason Gunthorpe <jgg@debian.org> and placed into
10 the Public Domain, do with it what you will.
12 ##################################################################### */
14 #include "rfc2553emu.h"
16 #include <arpa/inet.h>
20 #ifndef HAVE_GETADDRINFO
21 // getaddrinfo - Resolve a hostname /*{{{*/
22 // ---------------------------------------------------------------------
24 int getaddrinfo(const char *nodename
, const char *servname
,
25 const struct addrinfo
*hints
,
26 struct addrinfo
**res
)
28 struct addrinfo
**Result
;
35 Addr
= gethostbyname(nodename
);
38 if (h_errno
== TRY_AGAIN
)
40 if (h_errno
== NO_RECOVERY
)
46 if (Addr
->h_addr_list
[0] == 0)
49 // Try to convert the service as a number
50 Port
= htons(strtol(servname
,(char **)&End
,0));
53 if (hints
!= 0 && hints
->ai_socktype
!= 0)
54 Proto
= hints
->ai_socktype
;
56 // Not a number, must be a name.
57 if (End
!= servname
+ strlen(End
))
59 struct servent
*Srv
= 0;
61 // Do a lookup in the service database
62 if (hints
== 0 || hints
->ai_socktype
== SOCK_STREAM
)
63 Srv
= getservbyname(servname
,"tcp");
64 if (hints
!= 0 && hints
->ai_socktype
== SOCK_DGRAM
)
65 Srv
= getservbyname(servname
,"udp");
69 // Get the right protocol
71 if (strcmp(Srv
->s_proto
,"tcp") == 0)
75 if (strcmp(Srv
->s_proto
,"udp") == 0)
81 if (hints
!= 0 && hints
->ai_socktype
!= Proto
&&
82 hints
->ai_socktype
!= 0)
86 // Start constructing the linked list
88 for (CurAddr
= Addr
->h_addr_list
; *CurAddr
!= 0; CurAddr
++)
90 // New result structure
91 *Result
= (struct addrinfo
*)calloc(sizeof(**Result
),1);
100 (*Result
)->ai_family
= AF_INET
;
101 (*Result
)->ai_socktype
= Proto
;
103 // If we have the IPPROTO defines we can set the protocol field
105 if (Proto
== SOCK_STREAM
)
106 (*Result
)->ai_protocol
= IPPROTO_TCP
;
107 if (Proto
== SOCK_DGRAM
)
108 (*Result
)->ai_protocol
= IPPROTO_UDP
;
111 // Allocate space for the address
112 (*Result
)->ai_addrlen
= sizeof(struct sockaddr_in
);
113 (*Result
)->ai_addr
= (struct sockaddr
*)calloc(sizeof(sockaddr_in
),1);
114 if ((*Result
)->ai_addr
== 0)
121 ((struct sockaddr_in
*)(*Result
)->ai_addr
)->sin_family
= AF_INET
;
122 ((struct sockaddr_in
*)(*Result
)->ai_addr
)->sin_port
= Port
;
123 ((struct sockaddr_in
*)(*Result
)->ai_addr
)->sin_addr
= *(in_addr
*)(*CurAddr
);
125 Result
= &(*Result
)->ai_next
;
131 // freeaddrinfo - Free the result of getaddrinfo /*{{{*/
132 // ---------------------------------------------------------------------
134 void freeaddrinfo(struct addrinfo
*ai
)
136 struct addrinfo
*Tmp
;
146 #endif // HAVE_GETADDRINFO
148 #ifndef HAVE_GETNAMEINFO
149 // getnameinfo - Convert a sockaddr to a string /*{{{*/
150 // ---------------------------------------------------------------------
152 int getnameinfo(const struct sockaddr
*sa
, socklen_t salen
,
153 char *host
, size_t hostlen
,
154 char *serv
, size_t servlen
,
157 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
159 // This routine only support internet addresses
160 if (sa
->sa_family
!= AF_INET
)
161 return EAI_ADDRFAMILY
;
165 // Try to resolve the hostname
166 if ((flags
& NI_NUMERICHOST
) != NI_NUMERICHOST
)
168 struct hostent
*Ent
= gethostbyaddr((char *)&sin
->sin_addr
,sizeof(sin
->sin_addr
),
171 strncpy(host
,Ent
->h_name
,hostlen
);
174 if ((flags
& NI_NAMEREQD
) == NI_NAMEREQD
)
176 if (h_errno
== TRY_AGAIN
)
178 if (h_errno
== NO_RECOVERY
)
183 flags
|= NI_NUMERICHOST
;
187 // Resolve as a plain numberic
188 if ((flags
& NI_NUMERICHOST
) == NI_NUMERICHOST
)
190 strncpy(host
,inet_ntoa(sin
->sin_addr
),hostlen
);
196 // Try to resolve the hostname
197 if ((flags
& NI_NUMERICSERV
) != NI_NUMERICSERV
)
200 if ((flags
& NI_DATAGRAM
) == NI_DATAGRAM
)
201 Ent
= getservbyport(sin
->sin_port
,"udp");
203 Ent
= getservbyport(sin
->sin_port
,"tcp");
206 strncpy(serv
,Ent
->s_name
,servlen
);
209 if ((flags
& NI_NAMEREQD
) == NI_NAMEREQD
)
212 flags
|= NI_NUMERICSERV
;
216 // Resolve as a plain numberic
217 if ((flags
& NI_NUMERICSERV
) == NI_NUMERICSERV
)
219 snprintf(serv
,servlen
,"%u",sin
->sin_port
);
226 #endif // HAVE_GETNAMEINFO