Statistics
| Branch: | Revision:

streamers / net_helpers.c @ 2c2fad64

History | View | Annotate | Download (4.09 KB)

1
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *  Copyright (c) 2010 Csaba Kiraly
4
 *
5
 *  This is free software; see gpl-3.0.txt
6
 */
7
#include <sys/types.h>
8
#ifndef _WIN32
9
#include <ifaddrs.h>
10
#include <sys/ioctl.h>
11
#include <sys/socket.h>
12
#include <netinet/in.h>
13
#include <arpa/inet.h>
14
#include <net/if.h>     /* For struct ifreq */
15
#include <netdb.h>
16
#else
17
#include <winsock2.h>
18
#endif
19
#include <unistd.h>
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <string.h>
23

    
24
#include "net_helpers.h"
25

    
26
char *iface_addr(const char *iface)
27
{
28
#ifndef _WIN32
29
    int s, res;
30
    struct ifreq iface_request;
31
    struct sockaddr_in *sin;
32
    char buff[512];
33

    
34
    s = socket(AF_INET, SOCK_DGRAM, 0);
35
    if (s < 0) {
36
        return NULL;
37
    }
38

    
39
    memset(&iface_request, 0, sizeof(struct ifreq));
40
    sin = (struct sockaddr_in *)&iface_request.ifr_addr;
41
    strcpy(iface_request.ifr_name, iface);
42
    /* sin->sin_family = AF_INET); */
43
    res = ioctl(s, SIOCGIFADDR, &iface_request);
44
    if (res < 0) {
45
        perror("ioctl(SIOCGIFADDR)");
46
        close(s);
47

    
48
        return NULL;
49
    }
50
    close(s);
51

    
52
    inet_ntop(AF_INET, &sin->sin_addr, buff, sizeof(buff));
53

    
54
    return strdup(buff);
55
#else
56
    if(iface != NULL && inet_addr(iface) != INADDR_NONE) return strdup(iface);
57
    return default_ip_addr();
58
#endif
59
}
60

    
61

    
62

    
63

    
64
char *simple_ip_addr()
65
{
66
  char hostname[256];
67
  struct hostent *host_entry;
68
  char *ip;
69

    
70
  fprintf(stderr, "Trying to guess IP ...");
71
  if (gethostname(hostname, sizeof hostname) < 0) {
72
    fprintf(stderr, "can't get hostname\n");
73
    return NULL;
74
  }
75
  fprintf(stderr, "hostname is: %s ...", hostname);
76

    
77
  host_entry = gethostbyname(hostname);
78
  if (! host_entry) {
79
    fprintf(stderr, "can't resolve IP\n");
80
    return NULL;
81
  }
82
  ip = strdup(inet_ntoa(*(struct in_addr*)host_entry->h_addr));
83
  fprintf(stderr, "IP is: %s ...", ip);
84

    
85
  return ip;
86
}
87

    
88

    
89
const char *autodetect_ip_address() {
90
#ifdef __linux__
91

    
92
        static char addr[128] = "";
93
        char iface[IFNAMSIZ] = "";
94
        char line[128] = "x";
95
        struct ifaddrs *ifaddr, *ifa;
96
        char *ret = NULL;
97

    
98
        FILE *r = fopen("/proc/net/route", "r");
99
        if (!r) return NULL;
100

    
101
        while (1) {
102
                char dst[32];
103
                char ifc[IFNAMSIZ];
104

    
105
                fgets(line, 127, r);
106
                if (feof(r)) break;
107
                if ((sscanf(line, "%s\t%s", iface, dst) == 2) && !strcpy(dst, "00000000")) {
108
                        strcpy(iface, ifc);
109
                         break;
110
                }
111
        }
112
        if (iface[0] == 0) return NULL;
113

    
114
        if (getifaddrs(&ifaddr) < 0) {
115
                perror("getifaddrs");
116
                return NULL;
117
        }
118

    
119
        ifa = ifaddr;
120
        while (ifa) {
121
                if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET && 
122
                        ifa->ifa_name && !strcmp(ifa->ifa_name, iface))  {
123
                        void *tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
124
                        if (inet_ntop(AF_INET, tmpAddrPtr, addr, 127)) {
125
                                ret = addr;
126
                        } else {
127
                                perror("inet_ntop error");
128
                                ret = NULL;
129
                        }
130
                        break;
131
                }
132
        ifa=ifa->ifa_next;
133
        }
134

    
135
        freeifaddrs(ifaddr);
136
        return ret;
137
#else
138
        return simple_ip_addr();
139
#endif
140
}
141

    
142

    
143
const char *hostname_ip_addr()
144
{
145
#ifndef _WIN32
146
  const char *ip;
147
  char hostname[256];
148
  struct addrinfo * result;
149
  struct addrinfo * res;
150
  int error;
151

    
152
  if (gethostname(hostname, sizeof hostname) < 0) {
153
    fprintf(stderr, "can't get hostname\n");
154
    return NULL;
155
  }
156
  fprintf(stderr, "hostname is: %s ...", hostname);
157

    
158
  /* resolve the domain name into a list of addresses */
159
  error = getaddrinfo(hostname, NULL, NULL, &result);
160
  if (error != 0) {
161
    fprintf(stderr, "can't resolve IP: %s\n", gai_strerror(error));
162
    return NULL;
163
  }
164

    
165
  /* loop over all returned results and do inverse lookup */
166
  for (res = result; res != NULL; res = res->ai_next) {
167
    ip = inet_ntoa(((struct sockaddr_in*)res->ai_addr)->sin_addr);
168
    fprintf(stderr, "IP is: %s ...", ip);
169
    if ( strncmp("127.", ip, 4) == 0) {
170
      fprintf(stderr, ":( ...");
171
      ip = NULL;
172
    } else {
173
      break;
174
    }
175
  }
176
  freeaddrinfo(result);
177

    
178
  return ip;
179
#else
180
  return NULL;
181
#endif
182
}
183

    
184
char *default_ip_addr()
185
{
186
  const char *ip = NULL;
187

    
188
  fprintf(stderr, "Trying to guess IP ...");
189

    
190
  //ip = hostname_ip_addr();
191

    
192
  if (!ip) {
193
    ip = autodetect_ip_address();
194
  }
195
  if (!ip) {
196
    fprintf(stderr, "cannot detect IP!\n");
197
    return NULL;
198
  }
199
  fprintf(stderr, "IP is: %s ...\n", ip);
200

    
201
  return strdup(ip);
202
}