Jak mogę uzyskać adres IP interfejsu w systemie Linux z kodu C?Uzyskaj adres IP interfejsu w systemie Linux
Na przykład chciałbym uzyskać adres IP (jeśli istnieje) przypisany do eth0.
Jak mogę uzyskać adres IP interfejsu w systemie Linux z kodu C?Uzyskaj adres IP interfejsu w systemie Linux
Na przykład chciałbym uzyskać adres IP (jeśli istnieje) przypisany do eth0.
Spróbuj tego:
#include <stdio.h>
#include <unistd.h>
#include <string.h> /* for strncpy */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
int
main()
{
int fd;
struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
/* I want to get an IPv4 IP address */
ifr.ifr_addr.sa_family = AF_INET;
/* I want IP address attached to "eth0" */
strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);
/* display result */
printf("%s\n", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
return 0;
}
Próbka kod jest pobierana z here.
Oprócz metody ioctl() Filip zademonstrował, że można użyć getifaddrs(). Na dole strony podręcznika znajduje się przykładowy program.
getifaddrs wydaje się bardzo wyczerpujący. Inne metody będą dawały tylko pierwszy lub pierwszy adres na interfejs. – MarkR
Och, niesamowite, nigdy o tym nie wiedziałem! –
Nie mam żadnego połączenia na eth0, jeśli użyję innej metody, wynik 128.226.115.183 jest błędny. Jednak ta metoda pokazuje, że nie ma żadnego połączenia na eth0, które zapewnia niezawodne wyjście – Angs
Jeśli szukasz adresu (IPv4) specyficznego interfejsu powiedzieć wlan0 następnie wypróbować ten kod, który wykorzystuje getifaddrs():
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
exit(EXIT_FAILURE);
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
continue;
s=getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in),host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if((strcmp(ifa->ifa_name,"wlan0")==0)&&(ifa->ifa_addr->sa_family==AF_INET))
{
if (s != 0)
{
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
printf("\tInterface : <%s>\n",ifa->ifa_name);
printf("\t Address : <%s>\n", host);
}
}
freeifaddrs(ifaddr);
exit(EXIT_SUCCESS);
}
Można zastąpić wlan0 z dla eth0 ethernet i lo dla lokalnej pętli zwrotnej.
Struktura i szczegółowe wyjaśnienia struktur danych użyte można znaleźć here.
Aby dowiedzieć się więcej o połączonej liście w C, dobrym punktem wyjścia będzie ta page.
Moje 2 centów: ten sam kod działa nawet jeśli iOS:
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#import "ViewController.h"
@interface ViewController()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
showIP();
}
void showIP()
{
struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
exit(EXIT_FAILURE);
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
continue;
s=getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in),host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if(/*(strcmp(ifa->ifa_name,"wlan0")==0)&&(*/ ifa->ifa_addr->sa_family==AF_INET) //)
{
if (s != 0)
{
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
printf("\tInterface : <%s>\n",ifa->ifa_name);
printf("\t Address : <%s>\n", host);
}
}
freeifaddrs(ifaddr);
}
@end
po prostu usunięte test przed wlan0, aby zobaczyć dane. ps Możesz usunąć "rodzinę"
, dlaczego występuje usterka segmentacji? – user138126
Daje błąd segmentacji –
'#include' brakuje dla 'close()' –
Angs