📄 libnet_resolve.c
字号:
/* * $Id: libnet_resolve.c,v 1.11 2003/10/17 15:54:35 kkuehl Exp $ * * libnet * libnet_resolve.c - various name resolution type routines * * Copyright (c) 1998 - 2003 Mike D. Schiffman <mike@infonexus.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 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 * SUCH DAMAGE. * */#if (HAVE_CONFIG_H)#include "../include/config.h"#endif#if (!(_WIN32) || (__CYGWIN__))
#include "../include/libnet.h"
#else
#include "../include/win32/libnet.h"
#endifu_int8_t *libnet_addr2name4(u_int32_t in, u_int8_t use_name){ #define HOSTNAME_SIZE 512
static u_int8_t hostname[HOSTNAME_SIZE+1], hostname2[HOSTNAME_SIZE+1]; static u_int16_t which; u_int8_t *p; struct hostent *host_ent = NULL; struct in_addr addr; /* * 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) * use host_lookup_r(). */ which++; if (use_name == LIBNET_RESOLVE) { addr.s_addr = in; 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! */ } if (!host_ent) { p = (u_int8_t *)∈ snprintf(((which % 2) ? hostname : hostname2), HOSTNAME_SIZE, "%d.%d.%d.%d",
(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); } else if (use_name == LIBNET_RESOLVE) { u_int8_t *ptr = ((which % 2) ? hostname : hostname2);
strncpy(ptr, host_ent->h_name, HOSTNAME_SIZE);
ptr[HOSTNAME_SIZE] = '\0';
} return (which % 2) ? (hostname) : (hostname2);}voidlibnet_addr2name4_r(u_int32_t in, u_int8_t use_name, u_int8_t *hostname, int hostname_len){ u_int8_t *p; struct hostent *host_ent = NULL; struct in_addr addr; if (use_name == LIBNET_RESOLVE) { addr.s_addr = in; host_ent = gethostbyaddr((int8_t *)&addr, sizeof(struct in_addr), AF_INET); } if (!host_ent) { p = (u_int8_t *)∈ snprintf(hostname, hostname_len, "%d.%d.%d.%d", (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); } else { strncpy(hostname, host_ent->h_name, hostname_len - 1); hostname[sizeof(hostname) - 1] = '\0'; }}u_int32_tlibnet_name2addr4(libnet_t *l, u_int8_t *host_name, u_int8_t use_name){ struct in_addr addr; struct hostent *host_ent; u_int32_t m; u_int val; int i; 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", __func__, strerror(errno)); /* XXX - this is actually 255.255.255.255 */ return (-1); } memcpy(&addr.s_addr, host_ent->h_addr, host_ent->h_length); } /* network byte order */ return (addr.s_addr); } else { /* * We only want dots 'n decimals. */ if (!isdigit(host_name[0])) { if (l) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): expecting dots and decimals\n", __func__); } /* XXX - this is actually 255.255.255.255 */ return (-1); } m = 0; for (i = 0; i < 4; i++) { m <<= 8; if (*host_name) { val = 0; while (*host_name && *host_name != '.') { val *= 10; val += *host_name - '0'; if (val > 255) { if (l) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): value greater than 255\n", __func__); } /* XXX - this is actually 255.255.255.255 */ return (-1); } host_name++; } m |= val; if (*host_name) { host_name++; } } } /* host byte order */ return (ntohl(m)); }}voidlibnet_addr2name6_r(struct libnet_in6_addr addr, u_int8_t use_name, u_int8_t *host_name, int host_name_len){ struct hostent *host_ent = NULL; if (use_name == LIBNET_RESOLVE) { #ifdef HAVE_SOLARIS #ifdef HAVE_SOLARIS_IPV6 host_ent = getipnodebyaddr((int8_t *)&addr, sizeof(struct in_addr), AF_INET6, NULL);#else /* XXX - Gah! Can't report error! */ host_ent = NULL;#endif#else host_ent = gethostbyaddr((int8_t *)&addr, sizeof(struct in_addr), AF_INET6);#endif } if (!host_ent) {#if !defined(__WIN32__) /* Silence Win32 warning */ inet_ntop(AF_INET6, &addr, host_name, host_name_len);#endif } else { 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;struct libnet_in6_addrlibnet_name2addr6(libnet_t *l, u_int8_t *host_name, u_int8_t use_name){#if !defined (__WIN32__) struct libnet_in6_addr addr; struct hostent *host_ent; #endif if (use_name == LIBNET_RESOLVE) {#ifdef __WIN32__ /* XXX - we don't support this yet */ if (l) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): can't resolve IPv6 addresses\n", __func__); } return (in6addr_error);#else#ifdef HAVE_SOLARIS #ifdef HAVE_SOLARIS_IPV6 if (!(host_ent = getipnodebyname((int8_t *)&addr, sizeof(struct in_addr), AF_INET6, NULL)))#else snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %s\n", __func__, strerror(errno)); return (in6addr_error);#endif#else if (!(host_ent = gethostbyname2(host_name, AF_INET6)))#endif { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %s", __func__, strerror(errno)); return (in6addr_error); } memcpy(&addr, host_ent->h_addr, host_ent->h_length); return (addr);#endif /* !__WIN32__ */ } else { #if defined(__WIN32__) /* Silence Win32 warning */ if (l) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "libnet_name2addr6(): can't resolve IPv6 addresses.\n"); } return (in6addr_error); #else if(!inet_pton(AF_INET6, host_name, &addr)) { if (l) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): invalid IPv6 address\n", __func__); } return (in6addr_error); } return (addr); #endif }}struct libnet_in6_addrlibnet_get_ipaddr6(libnet_t *l){ snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): Not yet Implemented\n", __func__); return (in6addr_error);}#if !defined(__WIN32__)u_int32_tlibnet_get_ipaddr4(libnet_t *l){ struct ifreq ifr; register struct sockaddr_in *sin; int fd; if (l == NULL) { return (-1); } /* create dummy socket to perform an ioctl upon */ fd = socket(PF_INET, SOCK_DGRAM, 0); if (fd == -1) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): socket(): %s\n", __func__, strerror(errno)); return (-1); } sin = (struct sockaddr_in *)&ifr.ifr_addr; if (l->device == NULL) { if (libnet_select_device(l) == -1) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): can't figure out a device to use\n", __func__); close(fd); return (-1); } } 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", __func__, strerror(errno)); close(fd); return (-1); } close(fd); return (sin->sin_addr.s_addr);}#else#include <Packet32.h>u_int32_tlibnet_get_ipaddr4(libnet_t *l){ ULONG ip = 0, netmask = 0; struct sockaddr_in sin; if(PacketGetNetInfo(l->device, &ip, &netmask)) { *(int32_t *)&sin.sin_addr = htonl(ip); } return(sin.sin_addr.s_addr);}#endif /* WIN32 */u_int8_t *libnet_hex_aton(int8_t *s, int *len){ u_int8_t *buf; int i; int32_t l; int8_t *pp; while (isspace(*s)) { s++; } for (i = 0, *len = 0; s[i]; i++) { if (s[i] == ':') { (*len)++; } } buf = malloc(*len + 1); if (buf == NULL) { return (NULL); } /* 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) { *len = 0; free(buf); return (NULL); } if (!(*pp == ':' || (i == *len && (isspace(*pp) || *pp == '\0')))) { *len = 0; free(buf); return (NULL); } buf[i] = (u_int8_t)l; s = pp + 1; } /* return int8_tacter after the octets ala strtol(3) */ (*len)++; return (buf);}/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -