2 * MAC address manupulation utility
4 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
19 #define MAC_ADDRESS_LEN 6
24 static void usage(void);
28 static int parse_mac(const char *mac_str, unsigned char *buf)
32 t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
33 &buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5]);
35 if (t != MAC_ADDRESS_LEN)
41 static void print_mac(unsigned char *buf)
43 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
44 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
47 static int maccalc_do_add(int argc, const char *argv[])
49 unsigned char mac[MAC_ADDRESS_LEN];
59 err = parse_mac(argv[0], mac);
65 t = (mac[3] << 16) | (mac[4] << 8) | mac[5];
67 mac[3] = (t >> 16) & 0xff;
68 mac[4] = (t >> 8) & 0xff;
75 static int maccalc_do_logical(int argc, const char *argv[],
76 unsigned char (*op)(unsigned char n1,
79 unsigned char mac1[MAC_ADDRESS_LEN];
80 unsigned char mac2[MAC_ADDRESS_LEN];
89 err = parse_mac(argv[0], mac1);
93 err = parse_mac(argv[1], mac2);
97 for (i = 0; i < MAC_ADDRESS_LEN; i++)
98 mac1[i] = op(mac1[i],mac2[i]);
104 static int maccalc_do_mac2bin(int argc, const char *argv[])
106 unsigned char mac[MAC_ADDRESS_LEN];
115 err = parse_mac(argv[0], mac);
119 c = write(STDOUT_FILENO, mac, sizeof(mac));
120 if (c != sizeof(mac)) {
121 fprintf(stderr, "failed to write to stdout\n");
128 static ssize_t read_safe(int fd, void *buf, size_t count)
134 r = read(fd, buf, count);
140 /* interrupted by a signal, restart */
156 static int maccalc_do_bin2mac(int argc, const char *argv[])
158 unsigned char mac[MAC_ADDRESS_LEN];
166 c = read_safe(STDIN_FILENO, mac, sizeof(mac));
167 if (c != sizeof(mac)) {
168 fprintf(stderr, "failed to read from stdin\n");
176 static unsigned char op_or(unsigned char n1, unsigned char n2)
181 static int maccalc_do_or(int argc, const char *argv[])
183 return maccalc_do_logical(argc, argv, op_or);
186 static unsigned char op_and(unsigned char n1, unsigned char n2)
191 static int maccalc_do_and(int argc, const char *argv[])
193 return maccalc_do_logical(argc, argv, op_and);
196 static unsigned char op_xor(unsigned char n1, unsigned char n2)
201 static int maccalc_do_xor(int argc, const char *argv[])
203 return maccalc_do_logical(argc, argv, op_xor);
206 static void usage(void)
209 "Usage: %s <command>\n"
211 " add <mac> <number>\n"
212 " and|or|xor <mac1> <mac2>\n"
218 int main(int argc, const char *argv[])
220 int (*op)(int argc, const char *argv[]);
223 maccalc_name = (char *) argv[0];
230 if (strcmp(argv[1], "add") == 0) {
232 } else if (strcmp(argv[1], "and") == 0) {
234 } else if (strcmp(argv[1], "or") == 0) {
236 } else if (strcmp(argv[1], "xor") == 0) {
238 } else if (strcmp(argv[1], "mac2bin") == 0) {
239 op = maccalc_do_mac2bin;
240 } else if (strcmp(argv[1], "bin2mac") == 0) {
241 op = maccalc_do_bin2mac;
243 fprintf(stderr, "unknown command '%s'\n", argv[1]);
251 ret = op(argc, argv);