* $Id: libnet_resolve.c,v 1.21 2005/11/29 21:49:08 carlosc Exp $
* libnet_resolve.c - various name resolution type routines
* Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#include "../include/config.h"
#if (!(_WIN32) || (__CYGWIN__))
#include "../include/libnet.h"
#include "../include/win32/libnet.h"
libnet_addr2name4(u_int32_t in
, u_int8_t use_name
)
#define HOSTNAME_SIZE 512
static char hostname
[HOSTNAME_SIZE
+1], hostname2
[HOSTNAME_SIZE
+1];
struct hostent
*host_ent
= NULL
;
* Swap to the other buffer. We swap static buffers to avoid having to
* pass in a int8_t *. This makes the code that calls this function more
* intuitive, but makes this function ugly. This function is seriously
* non-reentrant. For threaded applications (or for signal handler code)
if (use_name
== LIBNET_RESOLVE
)
host_ent
= gethostbyaddr((int8_t *)&addr
, sizeof(struct in_addr
), AF_INET
);
/* if this fails, we silently ignore the error and move to plan b! */
snprintf(((which
% 2) ? hostname
: hostname2
), HOSTNAME_SIZE
,
(p
[0] & 255), (p
[1] & 255), (p
[2] & 255), (p
[3] & 255));
else if (use_name
== LIBNET_RESOLVE
)
char *ptr
= ((which
% 2) ? hostname
: hostname2
);
strncpy(ptr
, host_ent
->h_name
, HOSTNAME_SIZE
);
ptr
[HOSTNAME_SIZE
] = '\0';
return (which
% 2) ? (hostname
) : (hostname2
);
libnet_addr2name4_r(u_int32_t in
, u_int8_t use_name
, char *hostname
,
struct hostent
*host_ent
= NULL
;
if (use_name
== LIBNET_RESOLVE
)
host_ent
= gethostbyaddr((int8_t *)&addr
, sizeof(struct in_addr
),
snprintf(hostname
, hostname_len
, "%d.%d.%d.%d",
(p
[0] & 255), (p
[1] & 255), (p
[2] & 255), (p
[3] & 255));
strncpy(hostname
, host_ent
->h_name
, hostname_len
- 1);
hostname
[sizeof(hostname
) - 1] = '\0';
libnet_name2addr4(libnet_t
*l
, char *host_name
, u_int8_t use_name
)
struct hostent
*host_ent
;
if (use_name
== LIBNET_RESOLVE
)
if ((addr
.s_addr
= inet_addr(host_name
)) == -1)
if (!(host_ent
= gethostbyname(host_name
)))
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): %s\n", __func__
, strerror(errno
));
/* XXX - this is actually 255.255.255.255 */
memcpy(&addr
.s_addr
, host_ent
->h_addr
, host_ent
->h_length
);
* We only want dots 'n decimals.
if (!isdigit(host_name
[0]))
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): expecting dots and decimals\n", __func__
);
/* XXX - this is actually 255.255.255.255 */
while (*host_name
&& *host_name
!= '.')
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): value greater than 255\n", __func__
);
/* XXX - this is actually 255.255.255.255 */
libnet_addr2name6_r(struct libnet_in6_addr addr
, u_int8_t use_name
,
char *host_name
, int host_name_len
)
struct hostent
*host_ent
= NULL
;
if (use_name
== LIBNET_RESOLVE
)
host_ent
= getipnodebyaddr((int8_t *)&addr
, sizeof(struct in_addr
),
/* XXX - Gah! Can't report error! */
host_ent
= gethostbyaddr((int8_t *)&addr
, sizeof(struct in_addr
),
#if !defined(__WIN32__) /* Silence Win32 warning */
inet_ntop(AF_INET6
, &addr
, host_name
, host_name_len
);
strncpy(host_name
, host_ent
->h_name
, host_name_len
-1);
host_name
[sizeof(host_name
) - 1] = '\0';
const struct libnet_in6_addr in6addr_error
= IN6ADDR_ERROR_INIT
;
libnet_name2addr6(libnet_t
*l
, char *host_name
, u_int8_t use_name
)
struct libnet_in6_addr addr
;
struct hostent
*host_ent
;
if (use_name
== LIBNET_RESOLVE
)
/* XXX - we don't support this yet */
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): can't resolve IPv6 addresses\n", __func__
);
if (!(host_ent
= getipnodebyname((int8_t *)&addr
,
sizeof(struct in_addr
), AF_INET6
, NULL
)))
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): %s\n", __func__
, strerror(errno
));
if (!(host_ent
= gethostbyname2(host_name
, AF_INET6
)))
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): %s", __func__
, strerror(errno
));
memcpy(&addr
, host_ent
->h_addr
, host_ent
->h_length
);
#if defined(__WIN32__) /* Silence Win32 warning */
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): can't resolve IPv6 addresses.\n", __func__
);
if(!inet_pton(AF_INET6
, host_name
, &addr
))
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): invalid IPv6 address\n", __func__
);
libnet_get_ipaddr6(libnet_t
*l
)
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): not yet Implemented\n", __func__
);
libnet_get_ipaddr4(libnet_t
*l
)
register struct sockaddr_in
*sin
;
/* create dummy socket to perform an ioctl upon */
fd
= socket(PF_INET
, SOCK_DGRAM
, 0);
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): socket(): %s\n", __func__
, strerror(errno
));
sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
if (libnet_select_device(l
) == -1)
/* error msg set in libnet_select_device() */
strncpy(ifr
.ifr_name
, l
->device
, sizeof(ifr
.ifr_name
) -1);
ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
ifr
.ifr_addr
.sa_family
= AF_INET
;
if (ioctl(fd
, SIOCGIFADDR
, (int8_t*) &ifr
) < 0)
snprintf(l
->err_buf
, LIBNET_ERRBUF_SIZE
,
"%s(): ioctl(): %s\n", __func__
, strerror(errno
));
return (sin
->sin_addr
.s_addr
);
libnet_get_ipaddr4(libnet_t
*l
)
struct npf_if_addr ipbuff
;
memset(&sin
,0,sizeof(sin
));
memset(&ipbuff
,0,sizeof(ipbuff
));
if (PacketGetNetInfoEx(l
->device
, &ipbuff
, &npflen
))
sin
= *(struct sockaddr_in
*)&ipbuff
.IPAddress
;
return (sin
.sin_addr
.s_addr
);
libnet_hex_aton(int8_t *s
, int *len
)
for (i
= 0, *len
= 0; s
[i
]; i
++)
/* expect len hex octets separated by ':' */
for (i
= 0; i
< *len
+ 1; i
++)
l
= strtol(s
, (char **)&pp
, 16);
if (pp
== s
|| l
> 0xff || l
< 0)
if (!(*pp
== ':' || (i
== *len
&& (isspace(*pp
) || *pp
== '\0'))))
/* return int8_tacter after the octets ala strtol(3) */