C 코드를 사용하여 ifconfig와 동일한 정보를 가져옵니다.
리눅스에서 C 코드를 사용하여 "ifconfig eth0"이 반환되는 것과 동일한 정보를 얻을 수 있는 방법이 있습니까?IP 주소, 링크 상태, MAC 주소 등에 관심이 있습니다.
ifconfig에서 출력한 샘플은 다음과 같습니다.
eth0 Link encap:Ethernet HWaddr 00:0F:20:CF:8B:42
inet addr:217.149.127.10 Bcast:217.149.127.63 Mask:255.255.255.192
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2472694671 errors:1 dropped:0 overruns:0 frame:0
TX packets:44641779 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1761467179 (1679.8 Mb) TX bytes:2870928587 (2737.9 Mb)
Interrupt:28
특히 출처가 없는 경우에 이와 같은 문제의 진상을 파악하는 한 가지 방법은 strace입니다.
통과하는 모든 프로그램에서 수행하는 모든 시스템 호출 목록과 인수 및 반환 값을 제공합니다.프로그램이 장시간 실행되지 않고 정보를 일부 저장했다가 그만두는 경우에는 사용자가 원하는 정보를 제공할 수 있는 것처럼 보이는 모든 시스템 호출에 대해 남자를 수행하는 것이 매우 간단할 수 있습니다.
내가 뛸때
strace ifconfig
흥미로운 통화 내용은 다음과 같습니다.
open("/proc/net/dev", O_RDONLY) = 6
이어 ioctl들이 한 무더기 나타나 @payne의 대답을 확증합니다.
ioctl(5, SIOCGIFFLAGS, {ifr_name="eth0", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
ioctl(5, SIOCGIFHWADDR, {ifr_name="eth0", ifr_hwaddr=84:2b:2b:b7:9e:6d}) = 0
ioctl(5, SIOCGIFMETRIC, {ifr_name="eth0", ifr_metric=0}) = 0
ioctl(5, SIOCGIFMTU, {ifr_name="eth0", ifr_mtu=1500}) = 0
네.ifconfig
그 자체가 C로 쓰여있습니다. :) 참조: http://cvsweb.netbsd.org/bsdweb.cgi/src/sbin/ifconfig/ifconfig.c?rev=1.169&content-type=text/x-cvsweb-markup
도man netdevice
(리눅스에서) 자세한 내용을 볼 수 있습니다.당신은 사용합니다.ioctl()
시스템 호출.
http://man7.org/linux/man-pages/man3/getifaddrs.3.html 에서 복사한 더 간단한 접근법이 있습니다.
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/if_link.h>
int main(int argc, char *argv[])
{
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
/* Walk through linked list, maintaining head pointer so we
can free list later */
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
/* Display interface name and family (including symbolic
form of the latter for the common families) */
printf("%-8s %s (%d)\n",
ifa->ifa_name,
(family == AF_PACKET) ? "AF_PACKET" :
(family == AF_INET) ? "AF_INET" :
(family == AF_INET6) ? "AF_INET6" : "???",
family);
/* For an AF_INET* interface address, display the address */
if (family == AF_INET || family == AF_INET6) {
s = getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST,
NULL, 0, NI_NUMERICHOST);
if (s != 0) {
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
printf("\t\taddress: <%s>\n", host);
} else if (family == AF_PACKET && ifa->ifa_data != NULL) {
struct rtnl_link_stats *stats = (struct rtnl_link_stats *)ifa->ifa_data;
printf("\t\ttx_packets = %10u; rx_packets = %10u\n"
"\t\ttx_bytes = %10u; rx_bytes = %10u\n",
stats->tx_packets, stats->rx_packets,
stats->tx_bytes, stats->rx_bytes);
}
}
freeifaddrs(ifaddr);
exit(EXIT_SUCCESS);
}
한 가지 간단한 방법은 open 기능을 사용하는 것입니다. http://pubs.opengroup.org/onlinepubs/009696899/functions/popen.html
다음과 같은 것을 사용합니다.
FILE *fp;
char returnData[64];
fp = popen("/sbin/ifconfig eth0", "r");
while (fgets(returnData, 64, fp) != NULL)
{
printf("%s", returnData);
}
pclose(fp);
코드에서 MAC 및 MTU를 가져오는 방법은 다음과 같습니다.
void getMACAddress(std::string _iface,unsigned char MAC[6]) {
int fd = socket(AF_INET, SOCK_DGRAM, 0);
struct ifreq ifr;
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , _iface.c_str() , IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
for(unsigned int i=0;i<6;i++)
MAC[i] = ifr.ifr_hwaddr.sa_data[i];
ioctl(fd, SIOCGIFMTU, &ifr);
close(fd);
printf("MTU: %d\n",ifr.ifr_mtu);
printf("MAC:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",MAC[0],MAC[1],MAC[2],MAC[3],MAC[4],MAC[5]);
}
void parse_ioctl(const char *ifname)
{
printf("%s\n", "scarf rosari...");
int sock;
struct ifreq ifr;
struct sockaddr_in *ipaddr;
char address[INET_ADDRSTRLEN];
size_t ifnamelen;
/* copy ifname to ifr object */
ifnamelen = strlen(ifname);
if (ifnamelen >= sizeof(ifr.ifr_name)) {
printf("error :%s\n", ifr.ifr_name);
return ;
}
memcpy(ifr.ifr_name, ifname, ifnamelen);
ifr.ifr_name[ifnamelen] = '\0';
/* open socket */
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sock < 0) {
printf("error :%s\n", "unable to open socket..");
return;
}
/* process mac */
if (ioctl(sock, SIOCGIFHWADDR, &ifr) != -1) {
printf("Mac address: %02x:%02x:%02x:%02x:%02x:%02x\n",
(unsigned char)ifr.ifr_hwaddr.sa_data[0],
(unsigned char)ifr.ifr_hwaddr.sa_data[1],
(unsigned char)ifr.ifr_hwaddr.sa_data[2],
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
}
/* process mtu */
if (ioctl(sock, SIOCGIFMTU, &ifr) != -1) {
printf("MTU: %d\n", ifr.ifr_mtu);
}
/* die if cannot get address */
if (ioctl(sock, SIOCGIFADDR, &ifr) == -1) {
close(sock);
return;
}
/* process ip */
ipaddr = (struct sockaddr_in *)&ifr.ifr_addr;
if (inet_ntop(AF_INET, &ipaddr->sin_addr, address, sizeof(address)) != NULL) {
printf("Ip address: %s\n", address);
}
/* try to get broadcast */
if (ioctl(sock, SIOCGIFBRDADDR, &ifr) != -1) {
ipaddr = (struct sockaddr_in *)&ifr.ifr_broadaddr;
if (inet_ntop(AF_INET, &ipaddr->sin_addr, address, sizeof(address)) != NULL) {
printf("Broadcast: %s\n", address);
}
}
/* try to get mask */
if (ioctl(sock, SIOCGIFNETMASK, &ifr) != -1) {
ipaddr = (struct sockaddr_in *)&ifr.ifr_netmask;
if (inet_ntop(AF_INET, &ipaddr->sin_addr, address, sizeof(address)) != NULL) {
printf("Netmask: %s\n", address);
}
}
close(sock);
}
용도:
parse_ioctl("eth0");
언급URL : https://stackoverflow.com/questions/4951257/using-c-code-to-get-same-info-as-ifconfig
'programing' 카테고리의 다른 글
jQuery를 사용하여 '어떤' ajax 요청이 완료되는지 탐지하려면 어떻게 해야 합니까? (0) | 2023.10.01 |
---|---|
jQuery를 사용하여 이미지에서 마우스 클릭의 X/Y 좌표 가져오기 (0) | 2023.10.01 |
WordPress 사용자 지정 게시물 유형이 검색 결과에 표시되지 않음 (0) | 2023.10.01 |
Get-Content - 문서에 설명된 대로 작동하지 않을 때까지 기다립니다. (0) | 2023.10.01 |
Woocmerce에서 특정 상품 속성이 있는지 확인하는 방법 (0) | 2023.10.01 |