I want to be able change my NIC mac address with my own utility (ifconfig does the trick but it's too big for my project), so after hours of reading ifconfig source code utility, and of course a lot of googling, I end with this:
The good new, its compiles fine, the bad new, it doesn't change the mac address, and I get this error message every time I try to change:
Code:
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/mac.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_var.h>
/* IP */
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
struct afswtch {
const char *af_name; /* as given on cmd line, e.g. "inet" */
short af_af; /* AF_* */
/*
* Status is handled one of two ways; if there is an
* address associated with the interface then the
* associated address family af_status method is invoked
* with the appropriate addressin info. Otherwise, if
* all possible info is to be displayed and af_other_status
* is defined then it is invoked after all address status
* is presented.
*/
void (*af_status)(int, const struct ifaddrs *);
void (*af_other_status)(int);
/* parse address method */
void (*af_getaddr)(const char *, int);
/* parse prefix method (IPv6) */
void (*af_getprefix)(const char *, int);
void (*af_postproc)(int s, const struct afswtch *);
u_long af_difaddr; /* set dst if address ioctl */
u_long af_aifaddr; /* set if address ioctl */
void *af_ridreq; /* */
void *af_addreq; /* */
struct afswtch *af_next;
/* XXX doesn't fit model */
void (*af_status_tunnel)(int);
void (*af_settunnel)(int s, struct addrinfo *srcres,
struct addrinfo *dstres);
};
int
main(int argc, char **argv)
{
int s, error;
struct ifreq ifr;
//char name[IFNAMSIZ];
mac_t label;
if (mac_from_text(&label, argv[1]) == -1) {
perror(argv[1]);
return;
}
ifr.ifr_addr.sa_family = AF_INET;
if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
err(1, "socket(family %u,SOCK_DGRAM", ifr.ifr_addr.sa_family);
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, argv[2], sizeof(ifr.ifr_name));
ifr.ifr_ifru.ifru_data = (void *)label;
error = ioctl(s, SIOCSIFMAC, &ifr);
mac_free(label);
if (error == -1)
perror("setifmac");
return 0;
}
Code:
# ./mactool dc0 00:11:22:33:44:55
setifmac: Device not configured