MAC地址打印

这是一个代码,它获取有关网络的一些信息,问题是当它打印出正常打印的MAC地址时,有时会用00:21:84:a2:12:88和00:ffffff21:84:a2:12 :ffffff88因机器而异

这是代码

#include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  # include  #define IP_QUAD(ip) (ip)>>24,((ip)&0x00ff0000)>>16,((ip)&0x0000ff00)>>8,((ip)&0x000000ff) #define IP_ADDR_LEN 4 struct { char *dev; int sd; struct ether_addr eth; struct in_addr ip; struct in_addr bcast; unsigned int mtu; } local_info ; struct ifreq eth_init(char*,struct ifreq); struct ifreq eth_get_info(struct ifreq); struct ifreq eth_get_bcast(struct ifreq); int main(int argc,char **argv){ int sd; struct ifreq ifr; if(argc != 2){ fprintf(stderr,"usage:  \n"); exit(1); } ifr = eth_init(argv[1],ifr); ifr = eth_get_info(ifr); printf("> Exiting...\n"); return(0); } struct ifreq eth_init(char *dev,struct ifreq ifr){ //Intitating Socket if((local_info.sd = socket(PF_INET,SOCK_PACKET,(ETH_P_ALL)))  Error initating the ethernet socket..\n"); exit(-1); } //Yupeeeeeeee Descriptor open printf("> Initated Ethernet socket on Descriptor (%x)\n",local_info.sd); //Set global variables local_info.dev = dev; return ifr; } struct ifreq eth_get_info(struct ifreq ifr){ int i = ETHER_ADDR_LEN; char* ptr; memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name,local_info.dev,sizeof(ifr.ifr_name)); //Getting MAC if(ioctl(local_info.sd,SIOCGIFHWADDR,&ifr)  Error Getting the Local Mac address\n"); exit(-1); } printf("> Successfully received Local MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n", ifr.ifr_hwaddr.sa_data[0],ifr.ifr_hwaddr.sa_data[1],ifr.ifr_hwaddr.sa_data[2] ,ifr.ifr_hwaddr.sa_data[3],ifr.ifr_hwaddr.sa_data[4],ifr.ifr_hwaddr.sa_data[5]); memcpy(&(local_info.eth),&ifr.ifr_hwaddr.sa_data,ETH_ALEN); // Getting IP Address memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name,local_info.dev,sizeof(ifr.ifr_name)); if( ioctl(local_info.sd,SIOCGIFADDR,&ifr)  Error gettint the local IP address\n"); exit(-1); } printf("> Successfully received the IP Address %s\n",inet_ntoa((*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr)); memcpy(&(local_info.ip.s_addr),&(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr,IP_ADDR_LEN); // Get MTU memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name,local_info.dev,sizeof(ifr.ifr_name)); if ( ioctl(local_info.sd,SIOCGIFMTU,&ifr)  Error Getting the MTU Value\n"); exit(-1); } printf("> Recevied Successfully the MTU Value \n"); local_info.mtu = ifr.ifr_mtu; return ifr; } struct ifreq eth_get_bcast(struct ifreq ifr){ /* get broadcast addr for size */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, local_info.dev, sizeof (ifr.ifr_name)); if (ioctl(local_info.sd, SIOCGIFBRDADDR, &ifr)  Error getting the Broadcast address\n"); exit(-1); } printf("> Received the BroadCast address: %s\n",inet_ntoa((*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr)); memcpy(&(local_info.bcast.s_addr), &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr, IP_ADDR_LEN); return ifr; } 

问题是eth_get_info函数的MAC扇区,打印语句

任何解决方案如何解决?

它看起来像签名/未签名的问题。

尝试转换为unsigned char:

  printf("> Successfully received Local 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]); 

虽然这里已经有一个公认的答案,但在netinet/ether.h有一个更好的解决方案。

鉴于Mac地址通常存储在u_int8_t类型中,如ether_addr结构中所示:

你可以这样做:

 printf("Mac Address: %s", ether_ntoa((struct ether_addr*)ar->sa)); 

在我的案例ar中看起来像这样:

 struct { u_int8_t sa[6]; } 

您可以使用asprintf类的asprintf轻松将其复制到另一个缓冲区中:

 char *formatted_mac_address; asprintf(formatted_mac_address, "Mac Address: %s", ether_ntoa((struct ether_addr*)ar->sa)); 

如果你没有像我一样的结构,你也可以使用任何u_int8_t的地址代替ar->sa

应该引入适当的标题/等,但这看起来比这里接受的解决方案更整洁。

我更喜欢在格式字符串中使用显式长度修饰符,以获得短于int的值。 例如,对于单字节值, %02hhx而不是%02x 。 它让我不用担心那些微妙的转换和促销问题:

 #include  int main(void) { signed char sff = '\xff'; unsigned char uff = '\xff'; printf("signed: %02x %02hhx\n", sff, sff); printf("unsigned: %02x %02hhx\n", uff, uff); return 0; } 

版画

 signed: ffffffff ff unsigned: ff ff 

这是一个简单的C程序,用于查找系统的MAC地址:

 #include #include int main() { system("getmac"); return 0; }