Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/libbb/inet_common.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 5  Line 5 
5   *   *
6   * Heavily modified by Manuel Novoa III       Mar 12, 2001   * Heavily modified by Manuel Novoa III       Mar 12, 2001
7   *   *
  * Version:     $Id: inet_common.c,v 1.1 2007-09-01 22:43:51 niro Exp $  
8   *   *
9   */   */
10    
11  #include "libbb.h"  #include "libbb.h"
12  #include "inet_common.h"  #include "inet_common.h"
13    
14  int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst)  int FAST_FUNC INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst)
15  {  {
16   struct hostent *hp;   struct hostent *hp;
17    #if ENABLE_FEATURE_ETC_NETWORKS
18   struct netent *np;   struct netent *np;
19    #endif
20    
21   /* Grmpf. -FvK */   /* Grmpf. -FvK */
22   s_in->sin_family = AF_INET;   s_in->sin_family = AF_INET;
# Line 33  int INET_resolve(const char *name, struc Line 34  int INET_resolve(const char *name, struc
34   /* If we expect this to be a hostname, try hostname database first */   /* If we expect this to be a hostname, try hostname database first */
35  #ifdef DEBUG  #ifdef DEBUG
36   if (hostfirst) {   if (hostfirst) {
37   bb_error_msg("gethostbyname (%s)", name);   bb_error_msg("gethostbyname(%s)", name);
38   }   }
39  #endif  #endif
40   if (hostfirst && (hp = gethostbyname(name)) != (struct hostent *) NULL) {   if (hostfirst) {
41   memcpy((char *) &s_in->sin_addr, (char *) hp->h_addr_list[0],   hp = gethostbyname(name);
42     sizeof(struct in_addr));   if (hp != NULL) {
43   return 0;   memcpy(&s_in->sin_addr, hp->h_addr_list[0],
44     sizeof(struct in_addr));
45     return 0;
46     }
47   }   }
48    #if ENABLE_FEATURE_ETC_NETWORKS
49   /* Try the NETWORKS database to see if this is a known network. */   /* Try the NETWORKS database to see if this is a known network. */
50  #ifdef DEBUG  #ifdef DEBUG
51   bb_error_msg("getnetbyname (%s)", name);   bb_error_msg("getnetbyname(%s)", name);
52  #endif  #endif
53   if ((np = getnetbyname(name)) != (struct netent *) NULL) {   np = getnetbyname(name);
54     if (np != NULL) {
55   s_in->sin_addr.s_addr = htonl(np->n_net);   s_in->sin_addr.s_addr = htonl(np->n_net);
56   return 1;   return 1;
57   }   }
58    #endif
59   if (hostfirst) {   if (hostfirst) {
60   /* Don't try again */   /* Don't try again */
61   return -1;   return -1;
# Line 56  int INET_resolve(const char *name, struc Line 63  int INET_resolve(const char *name, struc
63  #ifdef DEBUG  #ifdef DEBUG
64   res_init();   res_init();
65   _res.options |= RES_DEBUG;   _res.options |= RES_DEBUG;
66     bb_error_msg("gethostbyname(%s)", name);
67  #endif  #endif
68     hp = gethostbyname(name);
69  #ifdef DEBUG   if (hp == NULL) {
  bb_error_msg("gethostbyname (%s)", name);  
 #endif  
  if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {  
70   return -1;   return -1;
71   }   }
72   memcpy((char *) &s_in->sin_addr, (char *) hp->h_addr_list[0],   memcpy(&s_in->sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
    sizeof(struct in_addr));  
   
73   return 0;   return 0;
74  }  }
75    
 /* cache */  
 struct addr {  
  struct sockaddr_in addr;  
  char *name;  
  int host;  
  struct addr *next;  
 };  
   
 static struct addr *INET_nn = NULL; /* addr-to-name cache           */  
76    
77  /* numeric: & 0x8000: default instead of *,  /* numeric: & 0x8000: default instead of *,
78   *          & 0x4000: host instead of net,   *          & 0x4000: host instead of net,
79   *          & 0x0fff: don't resolve   *          & 0x0fff: don't resolve
80   */   */
81  int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,  char* FAST_FUNC INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t netmask)
   int numeric, unsigned int netmask)  
82  {  {
83   struct hostent *ent;   /* addr-to-name cache */
84   struct netent *np;   struct addr {
85     struct addr *next;
86     struct sockaddr_in addr;
87     int host;
88     char name[1];
89     };
90     static struct addr *cache = NULL;
91    
92   struct addr *pn;   struct addr *pn;
93   unsigned long ad, host_ad;   char *name;
94     uint32_t ad, host_ad;
95   int host = 0;   int host = 0;
96    
  /* Grmpf. -FvK */  
97   if (s_in->sin_family != AF_INET) {   if (s_in->sin_family != AF_INET) {
98  #ifdef DEBUG  #ifdef DEBUG
99   bb_error_msg("rresolve: unsupport address family %d !",   bb_error_msg("rresolve: unsupported address family %d!",
100    s_in->sin_family);    s_in->sin_family);
101  #endif  #endif
102   errno = EAFNOSUPPORT;   errno = EAFNOSUPPORT;
103   return -1;   return NULL;
104   }   }
105   ad = (unsigned long) s_in->sin_addr.s_addr;   ad = s_in->sin_addr.s_addr;
106  #ifdef DEBUG  #ifdef DEBUG
107   bb_error_msg("rresolve: %08lx, mask %08x, num %08x", ad, netmask, numeric);   bb_error_msg("rresolve: %08x, mask %08x, num %08x", (unsigned)ad, netmask, numeric);
108  #endif  #endif
109   if (ad == INADDR_ANY) {   if (ad == INADDR_ANY) {
110   if ((numeric & 0x0FFF) == 0) {   if ((numeric & 0x0FFF) == 0) {
111   if (numeric & 0x8000)   if (numeric & 0x8000)
112   safe_strncpy(name, bb_str_default, len);   return xstrdup(bb_str_default);
113   else   return xstrdup("*");
  safe_strncpy(name, "*", len);  
  return 0;  
114   }   }
115   }   }
116   if (numeric & 0x0FFF) {   if (numeric & 0x0FFF)
117   safe_strncpy(name, inet_ntoa(s_in->sin_addr), len);   return xstrdup(inet_ntoa(s_in->sin_addr));
  return 0;  
  }  
118    
119   if ((ad & (~netmask)) != 0 || (numeric & 0x4000))   if ((ad & (~netmask)) != 0 || (numeric & 0x4000))
120   host = 1;   host = 1;
121   pn = INET_nn;   pn = cache;
122   while (pn != NULL) {   while (pn) {
123   if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {   if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
  safe_strncpy(name, pn->name, len);  
124  #ifdef DEBUG  #ifdef DEBUG
125   bb_error_msg("rresolve: found %s %08lx in cache",   bb_error_msg("rresolve: found %s %08x in cache",
126    (host ? "host" : "net"), ad);    (host ? "host" : "net"), (unsigned)ad);
127  #endif  #endif
128   return 0;   return xstrdup(pn->name);
129   }   }
130   pn = pn->next;   pn = pn->next;
131   }   }
132    
133   host_ad = ntohl(ad);   host_ad = ntohl(ad);
134   np = NULL;   name = NULL;
  ent = NULL;  
135   if (host) {   if (host) {
136     struct hostent *ent;
137  #ifdef DEBUG  #ifdef DEBUG
138   bb_error_msg("gethostbyaddr (%08lx)", ad);   bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad);
139  #endif  #endif
140   ent = gethostbyaddr((char *) &ad, 4, AF_INET);   ent = gethostbyaddr((char *) &ad, 4, AF_INET);
141   if (ent != NULL) {   if (ent)
142   safe_strncpy(name, ent->h_name, len);   name = xstrdup(ent->h_name);
143   }   } else if (ENABLE_FEATURE_ETC_NETWORKS) {
144   } else {   struct netent *np;
145  #ifdef DEBUG  #ifdef DEBUG
146   bb_error_msg("getnetbyaddr (%08lx)", host_ad);   bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad);
147  #endif  #endif
148   np = getnetbyaddr(host_ad, AF_INET);   np = getnetbyaddr(host_ad, AF_INET);
149   if (np != NULL) {   if (np)
150   safe_strncpy(name, np->n_name, len);   name = xstrdup(np->n_name);
  }  
151   }   }
152   if ((ent == NULL) && (np == NULL)) {   if (!name)
153   safe_strncpy(name, inet_ntoa(s_in->sin_addr), len);   name = xstrdup(inet_ntoa(s_in->sin_addr));
154   }   pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */
155   pn = xmalloc(sizeof(struct addr));   pn->next = cache;
156   pn->addr = *s_in;   pn->addr = *s_in;
  pn->next = INET_nn;  
157   pn->host = host;   pn->host = host;
158   pn->name = xstrdup(name);   strcpy(pn->name, name);
159   INET_nn = pn;   cache = pn;
160     return name;
  return 0;  
161  }  }
162    
163  #ifdef CONFIG_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
164    
165  int INET6_resolve(const char *name, struct sockaddr_in6 *sin6)  int FAST_FUNC INET6_resolve(const char *name, struct sockaddr_in6 *sin6)
166  {  {
167   struct addrinfo req, *ai;   struct addrinfo req, *ai;
168   int s;   int s;
# Line 183  int INET6_resolve(const char *name, stru Line 175  int INET6_resolve(const char *name, stru
175   return -1;   return -1;
176   }   }
177   memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));   memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));
   
178   freeaddrinfo(ai);   freeaddrinfo(ai);
   
179   return 0;   return 0;
180  }  }
181    
# Line 196  int INET6_resolve(const char *name, stru Line 186  int INET6_resolve(const char *name, stru
186  #endif  #endif
187    
188    
189  int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6,  char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric)
    int numeric)  
190  {  {
191     char name[128];
192   int s;   int s;
193    
  /* Grmpf. -FvK */  
194   if (sin6->sin6_family != AF_INET6) {   if (sin6->sin6_family != AF_INET6) {
195  #ifdef DEBUG  #ifdef DEBUG
196   bb_error_msg("rresolve: unsupport address family %d!",   bb_error_msg("rresolve: unsupport address family %d!",
197    sin6->sin6_family);    sin6->sin6_family);
198  #endif  #endif
199   errno = EAFNOSUPPORT;   errno = EAFNOSUPPORT;
200   return -1;   return NULL;
201   }   }
202   if (numeric & 0x7FFF) {   if (numeric & 0x7FFF) {
203   inet_ntop(AF_INET6, &sin6->sin6_addr, name, len);   inet_ntop(AF_INET6, &sin6->sin6_addr, name, sizeof(name));
204   return 0;   return xstrdup(name);
205   }   }
206   if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {   if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
207   if (numeric & 0x8000) {   if (numeric & 0x8000)
208   strcpy(name, bb_str_default);   return xstrdup(bb_str_default);
209   } else {   return xstrdup("*");
  name[0] = '*';  
  name[1] = '\0';  
  }  
  return 0;  
210   }   }
211    
212   s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), name, len, NULL, 0, 0);   s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6),
213     name, sizeof(name), NULL, 0, 0);
214   if (s) {   if (s) {
215   bb_error_msg("getnameinfo failed");   bb_error_msg("getnameinfo failed");
216   return -1;   return NULL;
217   }   }
218   return 0;   return xstrdup(name);
219  }  }
220    
221  #endif /* CONFIG_FEATURE_IPV6 */  #endif /* CONFIG_FEATURE_IPV6 */

Legend:
Removed from v.532  
changed lines
  Added in v.816