mac.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  4. * Copyright (c) 2013-2017 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  5. *
  6. * The Tcpreplay Suite of tools is free software: you can redistribute it
  7. * and/or modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation, either version 3 of the
  9. * License, or with the authors permission any later version.
  10. *
  11. * The Tcpreplay Suite is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "config.h"
  20. #include "defines.h"
  21. #include "common.h"
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <limits.h>
  25. #include <ctype.h>
  26. #include "mac.h"
  27. /**
  28. * converts a string representation of a MAC address, based on
  29. * non-portable ether_aton()
  30. */
  31. void
  32. mac2hex(const char *mac, u_char *dst, int len)
  33. {
  34. int i;
  35. long l;
  36. char *pp;
  37. if (len < 6)
  38. return;
  39. while (isspace(*mac))
  40. mac++;
  41. /* expect 6 hex octets separated by ':' or space/NUL if last octet */
  42. for (i = 0; i < 6; i++) {
  43. l = strtol(mac, &pp, 16);
  44. if (pp == mac || l > 0xFF || l < 0)
  45. return;
  46. if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
  47. return;
  48. dst[i] = (u_char) l;
  49. mac = pp + 1;
  50. }
  51. }
  52. /**
  53. * converts a string representation of TWO MAC addresses, which
  54. * are comma deliminated into two hex values. Either *first or *second
  55. * can be NULL if there is nothing before or after the comma.
  56. * returns:
  57. * 1 = first mac
  58. * 2 = second mac
  59. * 3 = both mac's
  60. * 0 = none
  61. */
  62. int
  63. dualmac2hex(const char *dualmac, u_char *first, u_char *second, int len)
  64. {
  65. char *tok = NULL, *temp, *string;
  66. int ret = 0;
  67. string = safe_strdup(dualmac);
  68. /* if we've only got a comma, then return NULL's */
  69. if (len <= 1) {
  70. second = first = NULL;
  71. goto done;
  72. }
  73. temp = strtok_r(string, ",", &tok);
  74. if (strlen(temp)) {
  75. mac2hex(temp, first, len);
  76. ret = 1;
  77. }
  78. temp = strtok_r(NULL, ",", &tok);
  79. /* temp is null if no comma */
  80. if (temp != NULL) {
  81. if (strlen(temp)) {
  82. mac2hex(temp, second, len);
  83. ret += 2;
  84. }
  85. }
  86. done:
  87. safe_free(string);
  88. return ret;
  89. }
  90. /**
  91. * Figures out if a MAC is listed in a comma delimited
  92. * string of MAC addresses.
  93. * returns TCPR_DIR_C2S if listed
  94. * returns TCPR_DIR_S2C if not listed
  95. */
  96. tcpr_dir_t
  97. macinstring(const char *macstring, const u_char *mac)
  98. {
  99. char *tok = NULL, *tempstr, *ourstring;
  100. u_char tempmac[6];
  101. int len = 6, ret = TCPR_DIR_S2C;
  102. ourstring = safe_strdup(macstring);
  103. memset(&tempmac[0], 0, sizeof(tempmac));
  104. tempstr = strtok_r(ourstring, ",", &tok);
  105. if (strlen(tempstr)) {
  106. mac2hex(tempstr, tempmac, len);
  107. if (memcmp(mac, tempmac, len) == 0) {
  108. dbgx(3, "Packet matches: " MAC_FORMAT " sending out primary.\n", MAC_STR(tempmac));
  109. ret = TCPR_DIR_C2S;
  110. goto EXIT_MACINSTRING;
  111. }
  112. } else {
  113. goto EXIT_MACINSTRING;
  114. }
  115. while ((tempstr = strtok_r(NULL, ",", &tok)) != NULL) {
  116. mac2hex(tempstr, tempmac, len);
  117. if (memcmp(mac, tempmac, len) == 0) {
  118. ret = TCPR_DIR_C2S;
  119. dbgx(3, "Packet matches: " MAC_FORMAT " sending out primary.\n", MAC_STR(tempmac));
  120. goto EXIT_MACINSTRING;
  121. }
  122. }
  123. EXIT_MACINSTRING:
  124. safe_free(ourstring);
  125. #ifdef DEBUG
  126. if (ret == TCPR_DIR_S2C)
  127. dbg(3, "Packet doesn't match any MAC addresses sending out secondary.\n");
  128. #endif
  129. return ret;
  130. }