1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/*
This file is part of LFT.
The LFT software provided in this Distribution is
Copyright 2002 MainNerve, Inc.
The full text of our legal notices is contained in the file called
COPYING, included with this Distribution.
ifname.c : ljd
$Id: lft_ifname.c,v 1.5 2003/04/23 18:28:44 nils Exp $
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#if !defined(linux) && !defined(__CYGWIN__)
#include <sys/sockio.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include "lft_ifname.h"
#include "acconfig.h"
static int sock = -1;
u_long
lft_getifaddr (const char *ifname)
{
struct ifreq ifr;
/* Only do this once of course */
if (sock < 0) {
if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
perror ("socket");
return -1;
}
}
STRNCPY(ifr.ifr_name, (char*)ifname, IFNAMSIZ);
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
perror("ioctl");
return -1;
}
return ((struct sockaddr_in *)(&(ifr.ifr_addr)))->sin_addr.s_addr;
}
char *
lft_getifname (struct in_addr addr)
{
struct ifconf ifc;
char buffer[2048];
int i, skip;
/* Only do this once of course */
if (sock < 0) {
if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
perror ("socket");
return NULL;
}
}
ifc.ifc_len = sizeof(buffer);
ifc.ifc_buf = buffer;
if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
perror("ioctl");
return NULL;
}
for (i = 0; i < ifc.ifc_len; i += skip) {
struct ifreq ifr;
struct in_addr thisaddr;
memcpy(&ifr, ifc.ifc_buf + i, sizeof(struct ifreq));
skip = sizeof(struct ifreq);
#ifdef HAVE_SOCKADDR_SA_LEN
if (ifr.ifr_addr.sa_len > sizeof(struct sockaddr)) {
skip = ifr.ifr_addr.sa_len + IFNAMSIZ;
}
#endif
if (ifr.ifr_addr.sa_family != AF_INET) continue;
thisaddr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
if (thisaddr.s_addr == addr.s_addr)
return strdup(ifr.ifr_name);
}
/* not found */
return NULL;
}
#ifdef LFT_IFADDR_TESTING
extern int
main (int argc, char *argv[])
{
struct in_addr in;
char *addr;
if (argc > 1)
addr = strdup (argv[1]);
else
addr = strdup ("eth0");
in.s_addr = lft_getifaddr (addr);
if (in.s_addr == -1) {
fprintf (stderr, "%s: Error reading ifname\n", addr);
fflush (stderr);
free(addr);
exit (-1);
}
fprintf (stdout, "%s: %s\n", addr,
inet_ntoa (in));
fflush (stdout);
free (addr);
exit (0);
}
#endif /*LFT_IFNAME_TESTING*/
|