MAC Address Printing

This is the code that receives the network information. The problem is when it prints the MAC address, which it once prints and sometime with fff like 00: 21: 84: a2: 12: 88 and also 00: ffffff21: 84: a2: 12: ffffff88 varies from machine to machine

here is the code

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <time.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <net/ethernet.h> #include <net/if.h> #include <arpa/inet.h> #include <sys/types.h> # include <netinet/if_ether.h> #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: <command> <devicename>\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))) < 0){ printf("> 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) < 0){ printf("> 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) < 0){ printf("> 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) < 0){ printf("> 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) < 0 ) { printf("> 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; } 

the problem is the eth_get_info function for the MAC sector, the print statement

any solutions how to fix this?

+6
source share
4 answers

It looks like a signed / unsigned issue.

Try typing in 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]); 
+10
source

Although there is already an accepted answer, there is a better solution in netinet/ether.h .

Given that Mac addresses are usually stored in u_int8_t types, as in the ether_addr structure:

You can simply do this:

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

in my case ar is something like this:

 struct { u_int8_t sa[6]; } 

You can easily copy this to another buffer with something like asprintf :

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

If you don't have a structure like me, you can just use the address of any u_int8_t instead of ar->sa .

The corresponding / etc headers should be pulled in, but it will look a lot neater than the decision made here.

+6
source

I prefer to use an explicit length modifier in the format string for values ​​smaller than int. For example, %02hhx instead of %02x for single-byte values. This allows me not to worry about those subtle issues associated with conversion and promotion:

 #include <stdio.h> 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; } 

prints

 signed: ffffffff ff unsigned: ff ff 
0
source

Here is a simple C program to find the system MAC address:

 #include<stdio.h> #include<stdlib.h> int main() { system("getmac"); return 0; } 
-2
source

Source: https://habr.com/ru/post/888573/


All Articles