list.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  3. * Copyright (c) 2013-2022 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  4. *
  5. * The Tcpreplay Suite of tools is free software: you can redistribute it
  6. * and/or modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or with the authors permission any later version.
  9. *
  10. * The Tcpreplay Suite is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * A generic method to parse a list of integers which are
  20. * delimited by commas and dashes to indicate individual
  21. * numbers and ranges
  22. * Provides both a way to process the list and determine
  23. * if an integer exists in the list.
  24. */
  25. #include "config.h"
  26. #include "defines.h"
  27. #include "common.h"
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <sys/types.h>
  31. #include <regex.h>
  32. #include <errno.h>
  33. /**
  34. * Creates a new tcpr_list entry. Malloc's memory.
  35. */
  36. tcpr_list_t *
  37. new_list()
  38. {
  39. tcpr_list_t *newlist;
  40. newlist = (tcpr_list_t *)safe_malloc(sizeof(tcpr_list_t));
  41. return (newlist);
  42. }
  43. /**
  44. * Processes a string (ourstr) containing the list in human readable
  45. * format and places the data in **list and finally returns 1 for
  46. * success, 0 for fail.
  47. */
  48. int
  49. parse_list(tcpr_list_t ** listdata, char *ourstr)
  50. {
  51. tcpr_list_t *listcur, *list_ptr;
  52. char *this = NULL;
  53. char *first, *second;
  54. int rcode;
  55. regex_t preg;
  56. char regex[] = "^[0-9]+(-[0-9]+)?$";
  57. char *token = NULL;
  58. u_int i;
  59. /* compile the regex first */
  60. if ((rcode = regcomp(&preg, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
  61. char ebuf[EBUF_SIZE];
  62. regerror(rcode, &preg, ebuf, sizeof(ebuf));
  63. errx(-1, "Unable to compile regex (%s): %s", regex, ebuf);
  64. }
  65. /* first iteration */
  66. this = strtok_r(ourstr, ",", &token);
  67. first = this;
  68. second = NULL;
  69. /* regex test */
  70. if (regexec(&preg, this, 0, NULL, 0) != 0) {
  71. warnx("Unable to parse: %s", this);
  72. regfree(&preg);
  73. return 0;
  74. }
  75. *listdata = new_list();
  76. list_ptr = *listdata;
  77. listcur = list_ptr;
  78. for (i = 0; i < strlen(this); i++) {
  79. if (this[i] == '-') {
  80. this[i] = '\0';
  81. second = &this[i + 1];
  82. }
  83. }
  84. list_ptr->min = strtoull(first, NULL, 0);
  85. if (second != NULL) {
  86. list_ptr->max = strtoull(second, NULL, 0);
  87. }
  88. else {
  89. list_ptr->max = list_ptr->min;
  90. }
  91. while (1) {
  92. this = strtok_r(NULL, ",", &token);
  93. if (this == NULL)
  94. break;
  95. first = this;
  96. second = NULL;
  97. /* regex test */
  98. if (regexec(&preg, this, 0, NULL, 0) != 0) {
  99. warnx("Unable to parse: %s", this);
  100. regfree(&preg);
  101. return 0;
  102. }
  103. listcur->next = new_list();
  104. listcur = listcur->next;
  105. for (i = 0; i < strlen(this); i++) {
  106. if (this[i] == '-') {
  107. this[i] = '\0';
  108. second = &this[i + 1];
  109. }
  110. }
  111. listcur->min = strtoull(first, NULL, 0);
  112. if (second != NULL) {
  113. listcur->max = strtoull(second, NULL, 0);
  114. }
  115. else {
  116. listcur->max = listcur->min;
  117. }
  118. }
  119. regfree(&preg);
  120. return 1;
  121. }
  122. /**
  123. * Checks to see if the given integer exists in the LIST.
  124. * Return 1 if in the list, otherwise 0
  125. */
  126. tcpr_dir_t
  127. check_list(tcpr_list_t * list, COUNTER value)
  128. {
  129. tcpr_list_t *current;
  130. current = list;
  131. do {
  132. if ((current->min != 0) && (current->max != 0)) {
  133. if ((value >= current->min) && (value <= current->max))
  134. return 1;
  135. } else if (current->min == 0) {
  136. if (value <= current->max)
  137. return 1;
  138. } else if (current->max == 0) {
  139. if (value >= current->min)
  140. return 1;
  141. }
  142. if (current->next != NULL)
  143. current = current->next;
  144. else
  145. current = NULL;
  146. } while (current != NULL);
  147. return 0;
  148. }
  149. /**
  150. * Free's all the memory associated with the given LIST
  151. */
  152. void
  153. free_list(tcpr_list_t * list)
  154. {
  155. /* recursively go down the list */
  156. if (list->next != NULL)
  157. free_list(list->next);
  158. safe_free(list);
  159. }