OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / lib / Libnet / src / libnet_resolve.c
1 /*
2  *  $Id: libnet_resolve.c,v 1.1.1.1 2000/05/25 00:28:49 route Exp $
3  *
4  *  libnet
5  *  libnet_resolve.c - various name resolution type routines
6  *
7  *  Copyright (c) 1998 - 2001 Mike D. Schiffman <mike@infonexus.com>
8  *  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  */
32
33 #if (HAVE_CONFIG_H)
34 #include "../include/config.h"
35 #endif
36 #include "../include/libnet.h"
37
38 u_char *
39 libnet_host_lookup(u_long in, u_short use_name)
40 {
41     static u_char hostname[512], hostname2[512];
42     static u_short which;
43     u_char *p;
44
45     struct hostent *host_ent = NULL;
46     struct in_addr addr;
47
48     /*
49      *  Swap to the other buffer.  We swap static buffers to avoid having to
50      *  pass in a char *.  This makes the code that calls this function more
51      *  intuitive, but makes this function ugly.  This function is seriously
52      *  non-reentrant.  For threaded applications (or for signal handler code)
53      *  use host_lookup_r().
54      */
55     which++;
56     
57     if (use_name == LIBNET_RESOLVE)
58     {
59         addr.s_addr = in;
60         host_ent = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
61     }
62     if (!host_ent)
63     {
64
65         p = (u_char *)&in;
66         sprintf(((which % 2) ? hostname : hostname2),  "%d.%d.%d.%d",
67                 (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
68     }
69     else if (use_name == LIBNET_RESOLVE)
70     {
71         strncpy(((which % 2) ? hostname : hostname2), host_ent->h_name, 
72                                                         sizeof(hostname));
73     }
74     return (which % 2) ? (hostname) : (hostname2);
75 }
76
77
78 void
79 libnet_host_lookup_r(u_long in, u_short use_name, u_char *hostname)
80 {
81     u_char *p;
82     struct hostent *host_ent = NULL;
83     struct in_addr addr;
84
85     if (use_name == LIBNET_RESOLVE)
86     {    
87         addr.s_addr = in;
88         host_ent = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
89     }
90     if (!host_ent)
91     {
92
93         p = (u_char *)&in;
94         sprintf(hostname, "%d.%d.%d.%d",
95                 (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
96     }
97     else
98     {
99         /* XXX - sizeof(hostname) == 4 bytes you moron.  FIX THAT. - r */
100         strncpy(hostname, host_ent->h_name, sizeof(hostname));
101     }
102 }
103
104
105 u_long
106 libnet_name_resolve(u_char *host_name, u_short use_name)
107 {
108     struct in_addr addr;
109     struct hostent *host_ent; 
110     u_long l;
111     u_int val;
112     int i;
113    
114     if (use_name == LIBNET_RESOLVE)
115     {
116         if ((addr.s_addr = inet_addr(host_name)) == -1)
117         {
118             if (!(host_ent = gethostbyname(host_name)))
119             {
120                 return (-1);
121             }
122             memcpy((char *)&addr.s_addr, host_ent->h_addr, host_ent->h_length);
123         }
124         return (addr.s_addr);
125     }
126     else
127     {
128         /*
129          *  We only want dots 'n decimals.
130          */
131         if (!isdigit(host_name[0]))
132         {
133             return (-1L);
134         }
135
136         l = 0;
137         for (i = 0; i < 4; i++)
138         {
139             l <<= 8;
140             if (*host_name)
141             {
142                 val = 0;
143                 while (*host_name && *host_name != '.')
144                 {   
145                     val *= 10;
146                     val += *host_name - '0';
147                     if (val > 255)
148                     {
149                         return (-1L);
150                     }
151                     host_name++;
152                 }
153                 l |= val;
154                 if (*host_name)
155                 {
156                     host_name++;
157                 }
158             }
159         }
160         return (htonl(l));
161     }
162 }
163
164
165 u_long
166 libnet_get_ipaddr(struct libnet_link_int *l, const char *device, char *ebuf)
167 {
168     struct ifreq ifr;
169     register struct sockaddr_in *sin;
170     int fd;
171
172     /*
173      *  Create dummy socket to perform an ioctl upon.
174      */
175     fd = socket(PF_INET, SOCK_DGRAM, 0);
176     if (fd < 0)
177     {
178         sprintf(ebuf, "socket: %s", strerror(errno));
179         return (0);
180     }
181
182     memset(&ifr, 0, sizeof(ifr));
183     sin = (struct sockaddr_in *)&ifr.ifr_addr;
184     strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
185
186     ifr.ifr_addr.sa_family = AF_INET;
187
188     if (ioctl(fd, SIOCGIFADDR, (char*) &ifr) < 0)
189     {
190         close(fd);
191         return(0);
192     }
193     close(fd);
194     return (ntohl(sin->sin_addr.s_addr));
195 }
196
197
198 /*
199  *  get_hwaddr routine moved to arch specifc files (sockpacket.c, bpf.c, etc)
200  */
201
202 /* EOF */