c语言从服务器获取文件路径,C语言获取服务器mac地址

Linux系统

在Linux系统,可以通过系统调用函数ioctl很容易就获取到服务器的mac地址。

#include #include #include #include #include #include int main()

{

int sock, if_count, i;

struct ifconf ifc;

struct ifreq ifr[10];

unsigned char mac[6];

memset(&ifc, 0, sizeof(struct ifconf));

sock = socket(AF_INET, SOCK_DGRAM, 0);

ifc.ifc_len = 10 * sizeof(struct ifreq);

ifc.ifc_buf = (char *)ifr;

//获取所有网卡信息

ioctl(sock, SIOCGIFCONF, (char *)&ifc);

if_count = ifc.ifc_len / (sizeof(struct ifreq));

for (i = 0; i < if_count; i++) {

if (ioctl(sock, SIOCGIFHWADDR, &ifr[i]) == 0) {

memcpy(mac, ifr[i].ifr_hwaddr.sa_data, 6);

printf("eth: %s, mac: %02x:%02x:%02x:%02x:%02x:%02x\n", ifr[i].ifr_name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

}

}

return 0;

}

核心逻辑主要分两个部分,第一个部分是获取网卡,主要通过下面的函数完成:

ioctl(sock, SIOCGIFCONF, (char *)&ifc);

它的信息保存在结构体struct ifconf中,有可能不止一个。获取到的信息保存在ifc_buf中。

第二个逻辑就是根据网卡的名字去获取mac地址,主要用下面的函数完成:

ioctl(sock, SIOCGIFHWADDR, &ifr[i]);

通过上面简单的两步,就能获取到Linux服务器上所有的网卡对应的mac地址。

当前操作系统信息:

[root@vm101108 src]# uname -a

Linux vm101108 3.10.0-1160.15.2.el7.x86_64 #1 SMP Wed Feb 3 15:06:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

[root@vm101108 src]# cat /etc/os-release

NAME="CentOS Linux"

VERSION="7 (Core)"

ID="centos"

ID_LIKE="rhel fedora"

VERSION_ID="7"

PRETTY_NAME="CentOS Linux 7 (Core)"

ANSI_COLOR="0;31"

CPE_NAME="cpe:/o:centos:centos:7"

HOME_URL="https://www.centos.org/"

BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"

CENTOS_MANTISBT_PROJECT_VERSION="7"

REDHAT_SUPPORT_PRODUCT="centos"

REDHAT_SUPPORT_PRODUCT_VERSION="7"

上面的程序运行结果:

[root@vm101108 src]# ./get_mac_addr

eth: lo, mac: 00:00:00:00:00:00

eth: em1, mac: b8:2a:72:dc:42:f2

eth: p5p2, mac: 90:e2:ba:89:46:bd

eth: docker0, mac: 02:42:1c:d3:f8:e8

查看本地网卡的mac地址:

[root@vm101108 src]# ifconfig

docker0: flags=4163mtu 1500

inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255

inet6 fe80::42:1cff:fed3:f8e8 prefixlen 64 scopeid 0x20

ether 02:42:1c:d3:f8:e8 txqueuelen 0 (Ethernet)

RX packets 0 bytes 0 (0.0 B)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 5 bytes 446 (446.0 B)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

em1: flags=4163mtu 1500

inet 192.168.102.108 netmask 255.255.255.0 broadcast 192.168.102.255

inet6 fe80::9f88:a3a9:1748:56fc prefixlen 64 scopeid 0x20

ether b8:2a:72:dc:42:f2 txqueuelen 1000 (Ethernet)

RX packets 4420019 bytes 547543658 (522.1 MiB)

RX errors 0 dropped 52 overruns 0 frame 0

TX packets 6526650 bytes 6637157039 (6.1 GiB)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

device interrupt 55

lo: flags=73mtu 65536

inet 127.0.0.1 netmask 255.0.0.0

inet6 ::1 prefixlen 128 scopeid 0x10loop txqueuelen 1000 (Local Loopback)

RX packets 140886 bytes 12507428 (11.9 MiB)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 140886 bytes 12507428 (11.9 MiB)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

p5p2: flags=4163mtu 1500

inet 192.168.101.108 netmask 255.255.255.0 broadcast 192.168.101.255

inet6 fe80::427c:e13c:50b6:d747 prefixlen 64 scopeid 0x20

ether 90:e2:ba:89:46:bd txqueuelen 1000 (Ethernet)

RX packets 57573979 bytes 50997944188 (47.4 GiB)

RX errors 0 dropped 41 overruns 0 frame 0

TX packets 1111442 bytes 673920374 (642.7 MiB)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

可见,取出来的mac地址是正确的。

AIX系统

AIX系统是power架构的,没有SIOCGIFHWADDR这个接口,因此,不能像Linux那样获取mac地址。

这里提供两种方法:

第一种方法

#include #include #include #include #include #include #include #include #include /* for ifconf */

#include /* for sockaddr_in */

#include static int aix_get_mac_addr(uint8_t mac[6])

{

struct ifconf ifc;

struct ifreq *ifr;

int sock = socket(AF_INET, SOCK_DGRAM, 0);

ifc.ifc_len = sizeof(struct ifreq);

ifc.ifc_buf = (char *)ifr;

if (sock < 0)

{

free(ifr);

return -1;

}

ioctl(sock, SIOCGIFCONF, &ifc);

struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;

memcpy(mac, ((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen)), 6);

close(sock);

free(ifr);

return 0;

}

void print_mac(uint8_t mac[6]){

printf("%02x:%02x:%02x:%02x:%02x:%02x\n",

mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

}

int main(void)

{

unsigned char mac[6];

if (aix_get_mac_addr(mac) == -1){

perror("aix_getmac");

exit(2);

}

print_mac(mac);

}

这种方法的核心逻辑是通过ioctl(sock, SIOCGIFCONF, &ifc)取出网卡信息后,将其地址强转成struct sockaddr_dl类型。

当前操作系统:

-bash-4.3# uname -a

AIX localhost 1 6 00C553DC4C00

-bash-4.3# oslevel

6.1.0.0

以上代码在AIX系统下运行结果:

-bash-4.3# ./mac1

00:11:25:c5:97:cc

查看系统网卡:

-bash-4.3# netstat -in

Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll

en0 1500 link#2 0.11.25.c5.97.cc 127705533 0 1124424 3 0

en0 1500 192.168.21 192.168.21.216 127705533 0 1124424 3 0

lo0 16896 link#1 1787514 0 1709788 0 0

lo0 16896 127 127.0.0.1 1787514 0 1709788 0 0

lo0 16896 ::1%1 1787514 0 1709788 0 0

可见,取出来的mac地址是正确的。

第二种方法

#include #include #include #include #include #include #include #include #include /* for ifconf */

#include /* for sockaddr_in */

#include /*

get ethernet MAC address on AIX

*/

static int aix_get_mac_addr(uint8_t mac[6])

{

struct ifconf ifc;

struct ifreq *ifr;

int sock = socket(AF_INET, SOCK_DGRAM, 0);

ifc.ifc_len = sizeof(struct ifreq);

ifc.ifc_buf = (char *)ifr;

if (sock < 0)

{

free(ifr);

return -1;

}

ioctl(sock, SIOCGIFCONF, &ifc);

size_t ksize;

struct kinfo_ndd *ndd;

int count, i;

ksize = getkerninfo(KINFO_NDD, 0, 0, 0);

if (ksize == 0) {

errno = ENOSYS;

return -1;

}

ndd = (struct kinfo_ndd *)malloc(ksize);

if (ndd == NULL) {

errno = ENOMEM;

return -1;

}

if (getkerninfo(KINFO_NDD, ndd, &ksize, 0) == -1) {

errno = ENOSYS;

return -1;

}

count= ksize/sizeof(struct kinfo_ndd);

for (i=0;iifr_name) == 0 ||

strcmp(ndd[i].ndd_name, ifr->ifr_name == 0))) {

memcpy(mac, ndd[i].ndd_addr, 6);

free(ndd);

return 0;

}

}

free(ndd);

errno = ENOENT;

return -1;

}

void print_mac(uint8_t mac[6]){

printf("%02x:%02x:%02x:%02x:%02x:%02x\n",

mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

}

int main(void)

{

uint8_t mac[6];

int i, ret;

ret = aix_get_mac_addr(mac);

if (ret == -1) {

perror("aix_getmac");

exit(1);

}

print_mac(mac);

}

第二种方法是通过getkerninfo函数去获取相关硬件信息。

其运行结果和第一种方法得到的一样:

-bash-4.3# ./mac2

00:11:25:c5:97:cc

Windows系统

//TODO

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值