From a18cea411585603519d95d1d2108a0b20ffa0039 Mon Sep 17 00:00:00 2001 From: clutton Date: Wed, 26 Feb 2014 03:46:57 +0200 Subject: [PATCH 01/15] move to POSIX if_nametoindex for checking interface existence --- src/netinfo.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/netinfo.c b/src/netinfo.c index 3525123..fdd985b 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -49,7 +49,7 @@ mc_net_info_new (const char *device) strncpy (new->dev.ifr_name, device, sizeof(new->dev.ifr_name)); new->dev.ifr_name[sizeof(new->dev.ifr_name)-1] = '\0'; - if (ioctl(new->sock, SIOCGIFHWADDR, &new->dev) < 0) { + if (!if_nametoindex(device)) { perror ("[ERROR] Set device name"); free(new); return NULL; @@ -73,10 +73,15 @@ mc_net_info_get_mac (const net_info_t *net) int i; mac_t *new = (mac_t *) malloc (sizeof(mac_t)); - for (i=0; i<6; i++) { - new->byte[i] = net->dev.ifr_hwaddr.sa_data[i] & 0xFF; + if (ioctl(net->sock, SIOCGIFHWADDR, &net->dev) < 0) { + perror ("[ERROR] Get mac address"); + free(mac_t); + return NULL; } + for (i=0; i<6; i++) + new->byte[i] = net->dev.ifr_hwaddr.sa_data[i] & 0xFF; + return new; } From f628eee3a93b74a750f0cd72132a3dd3465ae2d6 Mon Sep 17 00:00:00 2001 From: clutton Date: Wed, 26 Feb 2014 03:50:43 +0200 Subject: [PATCH 02/15] clear if format --- src/netinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netinfo.c b/src/netinfo.c index fdd985b..fab688c 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -49,7 +49,7 @@ mc_net_info_new (const char *device) strncpy (new->dev.ifr_name, device, sizeof(new->dev.ifr_name)); new->dev.ifr_name[sizeof(new->dev.ifr_name)-1] = '\0'; - if (!if_nametoindex(device)) { + if (if_nametoindex(device) == 0) { perror ("[ERROR] Set device name"); free(new); return NULL; From 68b9d604230a63f13588472d552ec9f47e2cd563 Mon Sep 17 00:00:00 2001 From: clutton Date: Wed, 26 Feb 2014 03:56:57 +0200 Subject: [PATCH 03/15] using EXIT_SUCCESS and EXIT_FAILURE constants from stdlib.h --- src/main.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/main.c b/src/main.c index 711ffe7..6f2d92f 100644 --- a/src/main.c +++ b/src/main.c @@ -40,9 +40,6 @@ #include "maclist.h" #include "netinfo.h" -#define EXIT_OK 0 -#define EXIT_ERROR 1 - static void print_help (void) { @@ -158,7 +155,7 @@ main (int argc, char *argv[]) "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", VERSION); - exit (EXIT_OK); + exit (EXIT_SUCCESS); break; case 'l': print_list = 1; @@ -192,26 +189,26 @@ main (int argc, char *argv[]) case '?': default: print_help(); - exit (EXIT_OK); + exit (EXIT_SUCCESS); break; } } /* Read the MAC lists */ if (mc_maclist_init() < 0) { - exit (EXIT_ERROR); + exit (EXIT_FAILURE); } /* Print list? */ if (print_list) { mc_maclist_print(search_word); - exit (EXIT_OK); + exit (EXIT_SUCCESS); } /* Get device name argument */ if (optind >= argc) { print_usage(); - exit (EXIT_OK); + exit (EXIT_SUCCESS); } device_name = argv[optind]; @@ -220,7 +217,7 @@ main (int argc, char *argv[]) /* Read the MAC */ if ((net = mc_net_info_new(device_name)) == NULL) { - exit (EXIT_ERROR); + exit (EXIT_FAILURE); } mac = mc_net_info_get_mac(net); mac_permanent = mc_net_info_get_permanent_mac(net); @@ -238,10 +235,10 @@ main (int argc, char *argv[]) mac_faked = mc_mac_dup (mac); if (show) { - exit (EXIT_OK); + exit (EXIT_SUCCESS); } else if (set_mac) { if (mc_mac_read_string (mac_faked, set_mac) < 0) { - exit (EXIT_ERROR); + exit (EXIT_FAILURE); } } else if (random) { mc_mac_random (mac_faked, 6, set_bia); @@ -257,7 +254,7 @@ main (int argc, char *argv[]) } else if (permanent) { mac_faked = mc_mac_dup (mac_permanent); } else { - exit (EXIT_OK); /* default to show */ + exit (EXIT_SUCCESS); /* default to show */ } /* Set the new MAC */ @@ -283,5 +280,5 @@ main (int argc, char *argv[]) mc_net_info_free (net); mc_maclist_free(); - return (ret == 0) ? EXIT_OK : EXIT_ERROR; + return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } From a794526e9815c119bb08d786a580675940a91d9a Mon Sep 17 00:00:00 2001 From: clutton Date: Thu, 27 Feb 2014 04:01:20 +0200 Subject: [PATCH 04/15] using AC_CANONICAL_HOST for splitting OS specific code --- configure.ac | 13 +++++++++++++ src/netinfo.c | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index e100490..9dfa4b3 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,19 @@ AC_SUBST(VERSION) AC_PROG_INSTALL AC_PROG_CC +AC_CANONICAL_HOST + +AS_CASE([$host], + [*-*-linux*], + [AC_CHECK_HEADER([linux/ethtool.h], , + AC_DEFINE([HAVE_LINUX_ETHTOOL], [1], + [Linux ethernet headers found]))], + [*-*-freebsd*], + [AC_CHECK_HEADERS([ifaddrs.h net/if.h net/if_dl.h net/if_types.h], , + AC_DEFINE([HAVE_BSD_ETHTOOL], [1], + [BSD ethernet headers found]))], + [AC_MSG_ERROR([architecture not supported])] +) AC_OUTPUT([ Makefile diff --git a/src/netinfo.c b/src/netinfo.c index fab688c..72e7580 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -23,14 +23,26 @@ * USA */ +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include #include #include #include -#include -#include +#ifdef HAVE_LINUX_ETHTOOL +# include +# include +#elif HAVE_BSD_ETHTOOL +# include +# include +# include +# include +# include +#endif #include "netinfo.h" From bc7c6ff3cfef261bf648d38368dfcd83d3ae64dc Mon Sep 17 00:00:00 2001 From: clutton Date: Thu, 27 Feb 2014 06:15:14 +0200 Subject: [PATCH 05/15] working _get && _set features --- configure.ac | 22 ++++++++++-------- src/main.c | 8 +++++++ src/netinfo.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 82 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 9dfa4b3..9ae9d43 100644 --- a/configure.ac +++ b/configure.ac @@ -11,17 +11,21 @@ AC_PROG_INSTALL AC_PROG_CC AC_CANONICAL_HOST -AS_CASE([$host], - [*-*-linux*], - [AC_CHECK_HEADER([linux/ethtool.h], , +case "$host" in +*-*-linux*) + AC_CHECK_HEADER([linux/ethtool.h], , AC_DEFINE([HAVE_LINUX_ETHTOOL], [1], - [Linux ethernet headers found]))], - [*-*-freebsd*], - [AC_CHECK_HEADERS([ifaddrs.h net/if.h net/if_dl.h net/if_types.h], , + [Linux ethernet headers found])) + ;; +*-*-freebsd*) + AC_CHECK_HEADERS([ifaddrs.h net/if.h net/if_dl.h net/if_types.h], , AC_DEFINE([HAVE_BSD_ETHTOOL], [1], - [BSD ethernet headers found]))], - [AC_MSG_ERROR([architecture not supported])] -) + [BSD ethernet headers found])) + ;; +*) + AC_MSG_ERROR([architecture not supported]) + ;; +esac AC_OUTPUT([ Makefile diff --git a/src/main.c b/src/main.c index 6f2d92f..b3c3fe1 100644 --- a/src/main.c +++ b/src/main.c @@ -220,7 +220,9 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } mac = mc_net_info_get_mac(net); +#ifdef HAVE_LINUX_ETHTOOL mac_permanent = mc_net_info_get_permanent_mac(net); +#endif /* --bia can only be used with --random */ if (set_bia && !random) { @@ -229,7 +231,9 @@ main (int argc, char *argv[]) /* Print the current MAC info */ print_mac ("Current MAC: ", mac); +#ifdef HAVE_LINUX_ETHTOOL print_mac ("Permanent MAC: ", mac_permanent); +#endif /* Change the MAC */ mac_faked = mc_mac_dup (mac); @@ -251,8 +255,10 @@ main (int argc, char *argv[]) } else if (another_any) { mc_maclist_set_random_vendor(mac_faked, mac_is_anykind); mc_mac_random (mac_faked, 3, 1); +#ifdef HAVE_LINUX_ETHTOOL } else if (permanent) { mac_faked = mc_mac_dup (mac_permanent); +#endif } else { exit (EXIT_SUCCESS); /* default to show */ } @@ -276,7 +282,9 @@ main (int argc, char *argv[]) /* Memory free */ mc_mac_free (mac); mc_mac_free (mac_faked); +#ifdef HAVE_LINUX_ETHTOOL mc_mac_free (mac_permanent); +#endif mc_net_info_free (net); mc_maclist_free(); diff --git a/src/netinfo.c b/src/netinfo.c index 72e7580..c122145 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -42,6 +42,7 @@ # include # include # include +# include #endif #include "netinfo.h" @@ -79,6 +80,7 @@ mc_net_info_free (net_info_t *net) } +#ifdef HAVE_LINUX_ETHTOOL mac_t * mc_net_info_get_mac (const net_info_t *net) { @@ -96,16 +98,52 @@ mc_net_info_get_mac (const net_info_t *net) return new; } +#elif HAVE_BSD_ETHTOOL +mac_t * +mc_net_info_get_mac (const net_info_t *net) +{ + int i; + mac_t *mac = (mac_t *) malloc (sizeof(mac_t)); + u_char *lladr; + + struct ifaddrs *ifap, *ifa; + struct sockaddr_dl *sdl; + + if (getifaddrs(&ifap) == 0) { + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + + sdl = (struct sockaddr_dl *) ifa->ifa_addr; + if (strcmp(sdl->sdl_data, net->dev.ifr_name) != 0) + continue; + if (sdl == NULL && sdl->sdl_alen <= 0 && + sdl->sdl_alen != ETHER_ADDR_LEN) + continue; + + if (sdl->sdl_type == IFT_ETHER) { + lladr = (u_char *) LLADDR(sdl); + for (i=0; i<6; i++) + mac->byte[i] = lladr[i] & 0xFF; + break; + } + } + freeifaddrs(ifap); + } else + perror("getifaddrs"); + + return mac; +} +#endif + +#ifdef HAVE_LINUX_ETHTOOL int mc_net_info_set_mac (net_info_t *net, const mac_t *mac) { int i; - for (i=0; i<6; i++) { + for (i=0; i<6; i++) net->dev.ifr_hwaddr.sa_data[i] = mac->byte[i]; - } if (ioctl(net->sock, SIOCSIFHWADDR, &net->dev) < 0) { perror ("[ERROR] Could not change MAC: interface up or insufficient permissions"); @@ -114,7 +152,27 @@ mc_net_info_set_mac (net_info_t *net, const mac_t *mac) return 0; } +#elif defined(HAVE_BSD_ETHTOOL) +int +mc_net_info_set_mac (net_info_t *net, const mac_t *mac) +{ + int i; + net->dev.ifr_addr.sa_family = AF_LINK; + net->dev.ifr_addr.sa_len = ETHER_ADDR_LEN; + for (i=0; i<6; i++) + net->dev.ifr_addr.sa_data[i] = mac->byte[i]; + + if (ioctl(net->sock, SIOCSIFLLADDR, &net->dev) == -1) { + perror ("[ERROR] Could not change MAC: interface up or insufficient permissions"); + return -1; + } + + return 0; +} +#endif + +#ifdef HAVE_LINUX_ETHTOOL mac_t * mc_net_info_get_permanent_mac (const net_info_t *net) { @@ -143,3 +201,4 @@ mc_net_info_get_permanent_mac (const net_info_t *net) free(epa); return newmac; } +#endif From 6d3820873b2b9b6f008b03646fc58dc3771927a7 Mon Sep 17 00:00:00 2001 From: clutton Date: Sun, 2 Mar 2014 08:36:45 +0200 Subject: [PATCH 06/15] debugging... --- src/netinfo.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/netinfo.c b/src/netinfo.c index c122145..4285b31 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -37,12 +37,12 @@ # include # include #elif HAVE_BSD_ETHTOOL -# include # include # include # include # include # include +# include #endif #include "netinfo.h" @@ -117,16 +117,13 @@ mc_net_info_get_mac (const net_info_t *net) if (strcmp(sdl->sdl_data, net->dev.ifr_name) != 0) continue; - if (sdl == NULL && sdl->sdl_alen <= 0 && - sdl->sdl_alen != ETHER_ADDR_LEN) + if (!sdl && sdl->sdl_family != AF_LINK) continue; - if (sdl->sdl_type == IFT_ETHER) { - lladr = (u_char *) LLADDR(sdl); - for (i=0; i<6; i++) - mac->byte[i] = lladr[i] & 0xFF; - break; - } + lladr = (uint8_t *) LLADDR(sdl); + for (i=0; i<6; i++) + mac->byte[i] = lladr[i] & 0xFF; + break; } freeifaddrs(ifap); } else From 6b80a9b62ebbeee77f65bdfa6ebf294c98e62689 Mon Sep 17 00:00:00 2001 From: clutton Date: Sun, 2 Mar 2014 08:56:49 +0200 Subject: [PATCH 07/15] temporary commenting mc_net_info_get_permanent_mac for BSD host --- src/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main.c b/src/main.c index b3c3fe1..4af682e 100644 --- a/src/main.c +++ b/src/main.c @@ -51,7 +51,9 @@ print_help (void) " -e, --ending Don't change the vendor bytes\n" " -a, --another Set random vendor MAC of the same kind\n" " -A Set random vendor MAC of any kind\n" +#ifdef HAVE_LINUX_ETHTOOL " -p, --permanent Reset to original, permanent hardware MAC\n" +#endif " -r, --random Set fully random MAC\n" " -l, --list[=keyword] Print known vendors\n" " -b, --bia Pretend to be a burned-in-address\n" @@ -113,7 +115,9 @@ main (int argc, char *argv[]) char ending = 0; char another_any = 0; char another_same = 0; +#ifdef HAVE_LINUX_ETHTOOL char permanent = 0; +#endif char print_list = 0; char show = 0; char set_bia = 0; @@ -128,7 +132,9 @@ main (int argc, char *argv[]) {"ending", no_argument, NULL, 'e'}, {"endding", no_argument, NULL, 'e'}, /* kept for backwards compatibility */ {"another", no_argument, NULL, 'a'}, +#ifdef HAVE_LINUX_ETHTOOL {"permanent", no_argument, NULL, 'p'}, +#endif {"show", no_argument, NULL, 's'}, {"another_any", no_argument, NULL, 'A'}, {"bia", no_argument, NULL, 'b'}, @@ -139,7 +145,9 @@ main (int argc, char *argv[]) net_info_t *net; mac_t *mac; +#ifdef HAVE_LINUX_ETHTOOL mac_t *mac_permanent; +#endif mac_t *mac_faked; char *device_name; int val; @@ -179,9 +187,11 @@ main (int argc, char *argv[]) case 'A': another_any = 1; break; +#ifdef HAVE_LINUX_ETHTOOL case 'p': permanent = 1; break; +#endif case 'm': set_mac = optarg; break; From f14786eed28154010ecee7b58f7e9dc3f461b8f3 Mon Sep 17 00:00:00 2001 From: clutton Date: Sun, 2 Mar 2014 09:03:55 +0200 Subject: [PATCH 08/15] type mismatch cleanup --- src/netinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netinfo.c b/src/netinfo.c index 4285b31..54f5201 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -104,7 +104,7 @@ mc_net_info_get_mac (const net_info_t *net) { int i; mac_t *mac = (mac_t *) malloc (sizeof(mac_t)); - u_char *lladr; + uint8_t *lladr; struct ifaddrs *ifap, *ifa; struct sockaddr_dl *sdl; From a7a85789073715cff36eac29f83af03edd17854c Mon Sep 17 00:00:00 2001 From: clutton Date: Mon, 3 Mar 2014 09:51:39 +0200 Subject: [PATCH 09/15] fix iface name handler --- src/netinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netinfo.c b/src/netinfo.c index 54f5201..3429797 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -114,7 +114,7 @@ mc_net_info_get_mac (const net_info_t *net) sdl = (struct sockaddr_dl *) ifa->ifa_addr; - if (strcmp(sdl->sdl_data, net->dev.ifr_name) != 0) + if (strcmp(ifa->ifa_name, net->dev.ifr_name) != 0) continue; if (!sdl && sdl->sdl_family != AF_LINK) From c1f5c30f44230f4eaa3db4c0eded54d1e32c1879 Mon Sep 17 00:00:00 2001 From: clutton Date: Thu, 6 Mar 2014 16:16:30 +0200 Subject: [PATCH 10/15] bobo types --- src/netinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/netinfo.c b/src/netinfo.c index 3429797..7102c28 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -104,7 +104,7 @@ mc_net_info_get_mac (const net_info_t *net) { int i; mac_t *mac = (mac_t *) malloc (sizeof(mac_t)); - uint8_t *lladr; + u_char *lladr; struct ifaddrs *ifap, *ifa; struct sockaddr_dl *sdl; @@ -120,7 +120,7 @@ mc_net_info_get_mac (const net_info_t *net) if (!sdl && sdl->sdl_family != AF_LINK) continue; - lladr = (uint8_t *) LLADDR(sdl); + lladr = (u_char *) LLADDR(sdl); for (i=0; i<6; i++) mac->byte[i] = lladr[i] & 0xFF; break; From 4239dce1d224ddd09c8cb74bbd31d91d59837876 Mon Sep 17 00:00:00 2001 From: clutton Date: Sat, 8 Mar 2014 07:12:26 +0200 Subject: [PATCH 11/15] proper os split --- configure.ac | 17 --------------- src/main.c | 18 ++++++++-------- src/netinfo.c | 57 +++++++++------------------------------------------ src/netinfo.h | 11 ++++++++++ 4 files changed, 30 insertions(+), 73 deletions(-) diff --git a/configure.ac b/configure.ac index 9ae9d43..e100490 100644 --- a/configure.ac +++ b/configure.ac @@ -9,23 +9,6 @@ AC_SUBST(VERSION) AC_PROG_INSTALL AC_PROG_CC -AC_CANONICAL_HOST - -case "$host" in -*-*-linux*) - AC_CHECK_HEADER([linux/ethtool.h], , - AC_DEFINE([HAVE_LINUX_ETHTOOL], [1], - [Linux ethernet headers found])) - ;; -*-*-freebsd*) - AC_CHECK_HEADERS([ifaddrs.h net/if.h net/if_dl.h net/if_types.h], , - AC_DEFINE([HAVE_BSD_ETHTOOL], [1], - [BSD ethernet headers found])) - ;; -*) - AC_MSG_ERROR([architecture not supported]) - ;; -esac AC_OUTPUT([ Makefile diff --git a/src/main.c b/src/main.c index 4af682e..44ff96e 100644 --- a/src/main.c +++ b/src/main.c @@ -51,7 +51,7 @@ print_help (void) " -e, --ending Don't change the vendor bytes\n" " -a, --another Set random vendor MAC of the same kind\n" " -A Set random vendor MAC of any kind\n" -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ " -p, --permanent Reset to original, permanent hardware MAC\n" #endif " -r, --random Set fully random MAC\n" @@ -115,7 +115,7 @@ main (int argc, char *argv[]) char ending = 0; char another_any = 0; char another_same = 0; -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ char permanent = 0; #endif char print_list = 0; @@ -132,7 +132,7 @@ main (int argc, char *argv[]) {"ending", no_argument, NULL, 'e'}, {"endding", no_argument, NULL, 'e'}, /* kept for backwards compatibility */ {"another", no_argument, NULL, 'a'}, -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ {"permanent", no_argument, NULL, 'p'}, #endif {"show", no_argument, NULL, 's'}, @@ -145,7 +145,7 @@ main (int argc, char *argv[]) net_info_t *net; mac_t *mac; -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ mac_t *mac_permanent; #endif mac_t *mac_faked; @@ -187,7 +187,7 @@ main (int argc, char *argv[]) case 'A': another_any = 1; break; -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ case 'p': permanent = 1; break; @@ -230,7 +230,7 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } mac = mc_net_info_get_mac(net); -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ mac_permanent = mc_net_info_get_permanent_mac(net); #endif @@ -241,7 +241,7 @@ main (int argc, char *argv[]) /* Print the current MAC info */ print_mac ("Current MAC: ", mac); -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ print_mac ("Permanent MAC: ", mac_permanent); #endif @@ -265,7 +265,7 @@ main (int argc, char *argv[]) } else if (another_any) { mc_maclist_set_random_vendor(mac_faked, mac_is_anykind); mc_mac_random (mac_faked, 3, 1); -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ } else if (permanent) { mac_faked = mc_mac_dup (mac_permanent); #endif @@ -292,7 +292,7 @@ main (int argc, char *argv[]) /* Memory free */ mc_mac_free (mac); mc_mac_free (mac_faked); -#ifdef HAVE_LINUX_ETHTOOL +#ifdef __linux__ mc_mac_free (mac_permanent); #endif mc_net_info_free (net); diff --git a/src/netinfo.c b/src/netinfo.c index 7102c28..fdfc9b9 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -23,20 +23,16 @@ * USA */ -#ifdef HAVE_CONFIG_H -# include -#endif - #include #include #include #include #include -#ifdef HAVE_LINUX_ETHTOOL +#if defined(__linux__) # include # include -#elif HAVE_BSD_ETHTOOL +#elif defined(__FreeBSD__) # include # include # include @@ -79,26 +75,6 @@ mc_net_info_free (net_info_t *net) free(net); } - -#ifdef HAVE_LINUX_ETHTOOL -mac_t * -mc_net_info_get_mac (const net_info_t *net) -{ - int i; - mac_t *new = (mac_t *) malloc (sizeof(mac_t)); - - if (ioctl(net->sock, SIOCGIFHWADDR, &net->dev) < 0) { - perror ("[ERROR] Get mac address"); - free(mac_t); - return NULL; - } - - for (i=0; i<6; i++) - new->byte[i] = net->dev.ifr_hwaddr.sa_data[i] & 0xFF; - - return new; -} -#elif HAVE_BSD_ETHTOOL mac_t * mc_net_info_get_mac (const net_info_t *net) { @@ -131,45 +107,32 @@ mc_net_info_get_mac (const net_info_t *net) return mac; } -#endif -#ifdef HAVE_LINUX_ETHTOOL -int -mc_net_info_set_mac (net_info_t *net, const mac_t *mac) -{ - int i; - - for (i=0; i<6; i++) - net->dev.ifr_hwaddr.sa_data[i] = mac->byte[i]; - - if (ioctl(net->sock, SIOCSIFHWADDR, &net->dev) < 0) { - perror ("[ERROR] Could not change MAC: interface up or insufficient permissions"); - return -1; - } - - return 0; -} -#elif defined(HAVE_BSD_ETHTOOL) int mc_net_info_set_mac (net_info_t *net, const mac_t *mac) { int i; +#if defined(__FreeBSD__) net->dev.ifr_addr.sa_family = AF_LINK; net->dev.ifr_addr.sa_len = ETHER_ADDR_LEN; +#endif for (i=0; i<6; i++) +#if defined(__linux__) + net->dev.ifr_hwaddr.sa_data[i] = mac->byte[i]; +#elif defined(__FreeBSD__) net->dev.ifr_addr.sa_data[i] = mac->byte[i]; +#endif - if (ioctl(net->sock, SIOCSIFLLADDR, &net->dev) == -1) { + if (ioctl(net->sock, SIOCSIFHWADDR, &net->dev) == -1) { perror ("[ERROR] Could not change MAC: interface up or insufficient permissions"); return -1; } return 0; } -#endif -#ifdef HAVE_LINUX_ETHTOOL +#if defined(__linux__) mac_t * mc_net_info_get_permanent_mac (const net_info_t *net) { diff --git a/src/netinfo.h b/src/netinfo.h index f79b0a9..21d09fd 100644 --- a/src/netinfo.h +++ b/src/netinfo.h @@ -30,6 +30,17 @@ #include #include "mac.h" +#ifdef __linux__ +#define sockaddr_dl sockaddr_ll +#define sdl_family sll_family +#define AF_LINK AF_PACKET +#define LLADDR(s) s->sll_addr; +#endif + +#ifdef __FreeBSD__ +#define SIOCSIFHWADDR SIOCSIFLLADDR +#endif + typedef struct { int sock; struct ifreq dev; From 95bea69dbaec0ba4d4572961d9d0309ecc2af31f Mon Sep 17 00:00:00 2001 From: clutton Date: Sat, 8 Mar 2014 08:55:44 +0200 Subject: [PATCH 12/15] >0 instead of -1 in return status --- src/netinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netinfo.c b/src/netinfo.c index fdfc9b9..5df5c11 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -124,7 +124,7 @@ mc_net_info_set_mac (net_info_t *net, const mac_t *mac) net->dev.ifr_addr.sa_data[i] = mac->byte[i]; #endif - if (ioctl(net->sock, SIOCSIFHWADDR, &net->dev) == -1) { + if (ioctl(net->sock, SIOCSIFHWADDR, &net->dev) > 0) { perror ("[ERROR] Could not change MAC: interface up or insufficient permissions"); return -1; } From 525009b53595228fab2dcb194bcede33d01eac80 Mon Sep 17 00:00:00 2001 From: clutton Date: Sat, 8 Mar 2014 08:56:16 +0200 Subject: [PATCH 13/15] >0 instead of -1 in return status --- src/netinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netinfo.c b/src/netinfo.c index 5df5c11..a9580c4 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -124,7 +124,7 @@ mc_net_info_set_mac (net_info_t *net, const mac_t *mac) net->dev.ifr_addr.sa_data[i] = mac->byte[i]; #endif - if (ioctl(net->sock, SIOCSIFHWADDR, &net->dev) > 0) { + if (ioctl(net->sock, SIOCSIFHWADDR, &net->dev) < 0) { perror ("[ERROR] Could not change MAC: interface up or insufficient permissions"); return -1; } From 3d3c1b977f777fe673b3fca183d357b87d9f9076 Mon Sep 17 00:00:00 2001 From: clutton Date: Wed, 19 Mar 2014 20:19:43 +0200 Subject: [PATCH 14/15] Moving OS specific behaviour to header/capability specific one --- configure.ac | 40 ++++++++++++++++++++++++++++++++++++++++ src/main.c | 18 +++++++++--------- src/netinfo.c | 39 +++++++++++++++++++++------------------ src/netinfo.h | 11 ----------- 4 files changed, 70 insertions(+), 38 deletions(-) diff --git a/configure.ac b/configure.ac index e100490..11e550b 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,46 @@ AC_SUBST(VERSION) AC_PROG_INSTALL AC_PROG_CC +AC_CANONICAL_HOST + +case "$host" in +*-*-linux*) + AC_DEFINE([LLADDR(s)], [s->sll_addr], [the link level address]) +;; +*-*-freebsd*) + AC_DEFINE([sockaddr_ll], [sockaddr_dl], [the socket link structures]) + AC_DEFINE([sll_family], [sdl_family], [the socket family member]) + AC_DEFINE([AF_PACKET], [AF_LINK], [the domain name]) + AC_DEFINE([ifr_hwaddr], [ifr_addr], [the address member]) + AC_DEFINE([SIOCSIFHWADDR], [SIOCSIFLLADDR], [the ioctl call]) +;; +esac + +AC_MSG_CHECKING([if sockaddr has the sa_len member]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ #include ]], + [[ struct sockaddr sock; return (sock.sa_len); ]])], + [AC_DEFINE([HAVE_SOCKADDR_SA_LEN], [1], + [socket address structures have length fields]) +]) + +AC_CHECK_HEADER([ifaddrs.h], ,[AC_MSG_ERROR( + [*** ifaddrs.h missing - please install first or check config.log ***])]) + +AC_CHECK_HEADERS([linux/if_packet.h net/if_dl.h]) + +if test "x$ac_cv_header_linux_if_packet_h" = "xyes" ; then + AC_DEFINE([HAVE_IF_PACKET], [1], + [The Linux if_packet.h header found]) +elif test "x$ac_cv_header_net_if_dl_h" = "xyes" ; then + AC_DEFINE([HAVE_IF_DL], [1], + [The BSD if_dl.h header found]) +else + AC_MSG_ERROR([*** sockaddr_* missing - please install first or check config.log ***]) +fi + +AC_CHECK_HEADER(linux/ethtool.h, AC_DEFINE([HAVE_ETHTOOL], [1], [Linux ethernet headers found]), ) AC_OUTPUT([ Makefile diff --git a/src/main.c b/src/main.c index 44ff96e..4f5ad93 100644 --- a/src/main.c +++ b/src/main.c @@ -51,7 +51,7 @@ print_help (void) " -e, --ending Don't change the vendor bytes\n" " -a, --another Set random vendor MAC of the same kind\n" " -A Set random vendor MAC of any kind\n" -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) " -p, --permanent Reset to original, permanent hardware MAC\n" #endif " -r, --random Set fully random MAC\n" @@ -115,7 +115,7 @@ main (int argc, char *argv[]) char ending = 0; char another_any = 0; char another_same = 0; -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) char permanent = 0; #endif char print_list = 0; @@ -132,7 +132,7 @@ main (int argc, char *argv[]) {"ending", no_argument, NULL, 'e'}, {"endding", no_argument, NULL, 'e'}, /* kept for backwards compatibility */ {"another", no_argument, NULL, 'a'}, -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) {"permanent", no_argument, NULL, 'p'}, #endif {"show", no_argument, NULL, 's'}, @@ -145,7 +145,7 @@ main (int argc, char *argv[]) net_info_t *net; mac_t *mac; -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) mac_t *mac_permanent; #endif mac_t *mac_faked; @@ -187,7 +187,7 @@ main (int argc, char *argv[]) case 'A': another_any = 1; break; -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) case 'p': permanent = 1; break; @@ -230,7 +230,7 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } mac = mc_net_info_get_mac(net); -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) mac_permanent = mc_net_info_get_permanent_mac(net); #endif @@ -241,7 +241,7 @@ main (int argc, char *argv[]) /* Print the current MAC info */ print_mac ("Current MAC: ", mac); -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) print_mac ("Permanent MAC: ", mac_permanent); #endif @@ -265,7 +265,7 @@ main (int argc, char *argv[]) } else if (another_any) { mc_maclist_set_random_vendor(mac_faked, mac_is_anykind); mc_mac_random (mac_faked, 3, 1); -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) } else if (permanent) { mac_faked = mc_mac_dup (mac_permanent); #endif @@ -292,7 +292,7 @@ main (int argc, char *argv[]) /* Memory free */ mc_mac_free (mac); mc_mac_free (mac_faked); -#ifdef __linux__ +#if defined(HAVE_ETHTOOL) mc_mac_free (mac_permanent); #endif mc_net_info_free (net); diff --git a/src/netinfo.c b/src/netinfo.c index a9580c4..a48106c 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -23,22 +23,29 @@ * USA */ +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include #include #include #include -#if defined(__linux__) +#include +#include +#include + +#if defined(HAVE_IF_PACKET) +# include +#elif defined(HAVE_IF_DL) +# include +#endif + +#if defined(HAVE_ETHTOOL) # include # include -#elif defined(__FreeBSD__) -# include -# include -# include -# include -# include -# include #endif #include "netinfo.h" @@ -83,17 +90,17 @@ mc_net_info_get_mac (const net_info_t *net) u_char *lladr; struct ifaddrs *ifap, *ifa; - struct sockaddr_dl *sdl; + struct sockaddr_ll *sdl; if (getifaddrs(&ifap) == 0) { for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - sdl = (struct sockaddr_dl *) ifa->ifa_addr; + sdl = (struct sockaddr_ll *) ifa->ifa_addr; if (strcmp(ifa->ifa_name, net->dev.ifr_name) != 0) continue; - if (!sdl && sdl->sdl_family != AF_LINK) + if (!sdl && sdl->sll_family != AF_PACKET) continue; lladr = (u_char *) LLADDR(sdl); @@ -112,17 +119,13 @@ int mc_net_info_set_mac (net_info_t *net, const mac_t *mac) { int i; -#if defined(__FreeBSD__) - net->dev.ifr_addr.sa_family = AF_LINK; +#if defined(HAVE_SOCKADDR_SA_LEN) + net->dev.ifr_addr.sa_family = AF_PACKET; net->dev.ifr_addr.sa_len = ETHER_ADDR_LEN; #endif for (i=0; i<6; i++) -#if defined(__linux__) net->dev.ifr_hwaddr.sa_data[i] = mac->byte[i]; -#elif defined(__FreeBSD__) - net->dev.ifr_addr.sa_data[i] = mac->byte[i]; -#endif if (ioctl(net->sock, SIOCSIFHWADDR, &net->dev) < 0) { perror ("[ERROR] Could not change MAC: interface up or insufficient permissions"); @@ -132,7 +135,7 @@ mc_net_info_set_mac (net_info_t *net, const mac_t *mac) return 0; } -#if defined(__linux__) +#if defined(HAVE_ETHTOOL) mac_t * mc_net_info_get_permanent_mac (const net_info_t *net) { diff --git a/src/netinfo.h b/src/netinfo.h index 21d09fd..f79b0a9 100644 --- a/src/netinfo.h +++ b/src/netinfo.h @@ -30,17 +30,6 @@ #include #include "mac.h" -#ifdef __linux__ -#define sockaddr_dl sockaddr_ll -#define sdl_family sll_family -#define AF_LINK AF_PACKET -#define LLADDR(s) s->sll_addr; -#endif - -#ifdef __FreeBSD__ -#define SIOCSIFHWADDR SIOCSIFLLADDR -#endif - typedef struct { int sock; struct ifreq dev; From 819e70d13371b470348c1c0db4554b87dbb302c2 Mon Sep 17 00:00:00 2001 From: clutton Date: Wed, 19 Mar 2014 21:26:34 +0200 Subject: [PATCH 15/15] Setting a ifreq structure with a SIOCGIFHWADDR before calling a SIOCSIFHWADDR for the linux/ethtool.h version --- src/netinfo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/netinfo.c b/src/netinfo.c index a48106c..25d8182 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -119,7 +119,12 @@ int mc_net_info_set_mac (net_info_t *net, const mac_t *mac) { int i; -#if defined(HAVE_SOCKADDR_SA_LEN) +#if defined(HAVE_ETHTOOL) + if (ioctl(net->sock, SIOCGIFHWADDR, &net->dev) < 0) { + perror ("[ERROR] Set ifreq structure"); + return -1; + } +#elif defined(HAVE_SOCKADDR_SA_LEN) net->dev.ifr_addr.sa_family = AF_PACKET; net->dev.ifr_addr.sa_len = ETHER_ADDR_LEN; #endif