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; }