ES-2024 reverter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
7.0KB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <arpa/inet.h>
  7. #include "configdata.h"
  8. struct cfg_patch {
  9. int code;
  10. int mask;
  11. int (* patch)(void *config, struct cfg_patch *patch, int code, const char *parameter);
  12. int offset;
  13. int size;
  14. int min;
  15. int max;
  16. };
  17. static int patch_8bit(void *config, struct cfg_patch *patch, int code, const char *parameter)
  18. {
  19. int value = atoi(parameter);
  20. if (value < patch->min || value > patch->max)
  21. return -1;
  22. *((uint8_t *)(config + patch->offset)) = value;
  23. return 0;
  24. }
  25. static int patch_16bit(void *config, struct cfg_patch *patch, int code, const char *parameter)
  26. {
  27. int value = atoi(parameter);
  28. if (value < patch->min || value > patch->max)
  29. return -1;
  30. *((uint16_t *)(config + patch->offset)) = htons(value);
  31. return 0;
  32. }
  33. static int patch_string(void *config, struct cfg_patch *patch, int code, const char *parameter)
  34. {
  35. strncpy(config + patch->offset, parameter, patch->size);
  36. return 0;
  37. }
  38. static int patch_ip(void *config, struct cfg_patch *patch, int code, const char *parameter)
  39. {
  40. return (inet_pton(AF_INET, parameter, config + patch->offset) <= 0) ? -1 : 0;
  41. }
  42. static int patch_defaultgw(void *config, struct cfg_patch *patch, int code, const char *parameter)
  43. {
  44. /* defaultgw has metric of 2 */
  45. *((uint8_t *)(config + 0x110d)) = 0x02;
  46. return patch_ip(config, patch, code, parameter);
  47. }
  48. static int patch_portenable(void *config, struct cfg_patch *patch, int code, const char *parameter)
  49. {
  50. int port = code - patch->code;
  51. if (port < 1 || port > 26)
  52. return -1;
  53. int status = (strcmp(parameter, "on") == 0);
  54. *((uint8_t *)(config + 0x336b + (port -1) * 0x70)) = (status ? 0x03 : 0x01);
  55. return 0;
  56. }
  57. static int patch_portname(void *config, struct cfg_patch *patch, int code, const char *parameter)
  58. {
  59. int port = code - patch->code;
  60. if (port < 1 || port > 26)
  61. return -1;
  62. strncpy(config + 0x336c + (port -1) * 0x70, parameter, patch->size);
  63. return 0;
  64. }
  65. static int patch_snmp_community(void *config, struct cfg_patch *patch, int code, const char *parameter)
  66. {
  67. strncpy(config + 0x00A0 + patch->offset, parameter, patch->size);
  68. *((uint8_t *)(config + 0x0101)) = 0x01;
  69. strncpy(config + 0x9914 + patch->offset, parameter, patch->size);
  70. *((uint8_t *)(config + 0x9975)) = 0x01;
  71. strncpy(config + 0x9984 + patch->offset, parameter, patch->size);
  72. *((uint8_t *)(config + 0x99e5)) = 0x01;
  73. strncpy(config + 0x99f4 + patch->offset, parameter, patch->size);
  74. *((uint8_t *)(config + 0x9a55)) = 0x01;
  75. return 0;
  76. }
  77. static int patch_portvlan(void *config, struct cfg_patch *patch, int code, const char *parameter)
  78. {
  79. int port = code - patch->code;
  80. if (port < 1 || port > 26)
  81. return -1;
  82. char *tmp, *buf = strdup(parameter);
  83. int vlanid = atoi(strtok_r(buf, ":", &tmp));
  84. int check_ingress = (strcmp(strtok_r(NULL, ":", &tmp), "check") == 0);
  85. int accept_all = (strcmp(strtok_r(NULL, ":", &tmp), "all") == 0);
  86. free(buf);
  87. if (vlanid < 0 || vlanid > 255)
  88. return -1;
  89. *((uint8_t *)(config + 0x5eff + (port -1) * 0x30)) = vlanid;
  90. *((uint8_t *)(config + 0x5f00 + (port -1) * 0x30)) = accept_all ? 0x00 : 0x01;
  91. *((uint8_t *)(config + 0x5f01 + (port -1) * 0x30)) = check_ingress ? 0x01 : 0x00;
  92. return 0;
  93. }
  94. /* TODO: not working "unknown ctl bits" */
  95. static int patch_dot1qvlan(void *config, struct cfg_patch *patch, int code, const char *parameter)
  96. {
  97. return -1;
  98. int id = code - patch->code;
  99. if (id < 1 || id > 32)
  100. return -1;
  101. char *tmp, *buf = strdup(parameter);
  102. int vlanid = atoi(strtok_r(buf, ":", &tmp));
  103. char *name = strtok_r(NULL, ":", &tmp);
  104. strncpy(config + 0x63e8 + (id -1) * 0xd0, name, 12);
  105. *((uint16_t *)(config + 0x64b4 + (id -1) * 0xd0)) = htons(vlanid);
  106. *((uint8_t *)(config + 0x64b6 + (id -1) * 0xd0)) = 0x03;
  107. /* all ports forbidden & not tagging as default */
  108. *((uint32_t *)(config + 0x63f4 + (id -1) * 0xd0)) = 0x03FFFFFF;
  109. *((uint32_t *)(config + 0x6434 + (id -1) * 0xd0)) = 0x03FFFFFF;
  110. *((uint32_t *)(config + 0x6474 + (id -1) * 0xd0)) = 0;
  111. free(buf);
  112. return 0;
  113. }
  114. /* TODO: not working "unknown ctl bits" */
  115. static int patch_dot1qport(void *config, struct cfg_patch *patch, int code, const char *parameter)
  116. {
  117. return -1;
  118. int id = code - patch->code;
  119. if (id < 1 || id > 32)
  120. return -1;
  121. char *tmp, *buf = strdup(parameter);
  122. int port = atoi(strtok_r(buf, ":", &tmp));
  123. char *control = strtok_r(NULL, ":", &tmp);
  124. char *tagging = strtok_r(NULL, ":", &tmp);
  125. if (port < 1 || port > 26) {
  126. free(buf);
  127. return -1;
  128. }
  129. uint32_t *a = (uint32_t *)(config + 0x63f4 + (id -1) * 0xd0);
  130. uint32_t *b = (uint32_t *)(config + 0x6434 + (id -1) * 0xd0);
  131. uint32_t *c = (uint32_t *)(config + 0x6474 + (id -1) * 0xd0);
  132. uint32_t value = (1 << (port -1));
  133. if (strcmp(control, "normal") == 0) {
  134. *a &= ~value;
  135. *b &= ~value;
  136. } else if (strcmp(control, "fixed") == 0) {
  137. *a &= ~value;
  138. *b |= value;
  139. } else if (strcmp(control, "forbidden") == 0) {
  140. *a |= value;
  141. *b |= value;
  142. } else {
  143. free(buf);
  144. return -1;
  145. }
  146. if (strcmp(tagging, "tagging") == 0)
  147. *c |= value;
  148. else
  149. *c &= ~value;
  150. free(buf);
  151. return 0;
  152. }
  153. static struct cfg_patch patcharr[] = {{
  154. .code = CFG_PASSWORD,
  155. .patch = patch_string,
  156. .offset = 0x0014,
  157. .size = 0x1d,
  158. }, {
  159. .code = CFG_LOCATION,
  160. .patch = patch_string,
  161. .offset = 0x0034,
  162. .size = 0x1d,
  163. }, {
  164. .code = CFG_SYSNAME,
  165. .patch = patch_string,
  166. .offset = 0x0054,
  167. .size = 0x1d,
  168. }, {
  169. .code = CFG_CONTACT,
  170. .patch = patch_string,
  171. .offset = 0x0074,
  172. .size = 0x1d,
  173. }, {
  174. .code = CFG_SNMP_READ_COMMUNITY,
  175. .patch = patch_snmp_community,
  176. .offset = 0x0000,
  177. .size = 0x1f,
  178. }, {
  179. .code = CFG_SNMP_WRITE_COMMUNITY,
  180. .patch = patch_snmp_community,
  181. .offset = 0x0020,
  182. .size = 0x1f,
  183. }, {
  184. .code = CFG_DEFAULTGW,
  185. .patch = patch_defaultgw,
  186. .offset = 0x10fc,
  187. }, {
  188. .code = CFG_IPADDRESS,
  189. .patch = patch_ip,
  190. .offset = 0x2df8,
  191. }, {
  192. .code = CFG_NETMASK,
  193. .patch = patch_8bit,
  194. .offset = 0x2dfe,
  195. .min = 0, .max = 32,
  196. }, {
  197. .code = CFG_NAMESERVER,
  198. .patch = patch_ip,
  199. .offset = 0x32dc,
  200. }, {
  201. .code = CFG_MACAGEING,
  202. .patch = patch_16bit,
  203. .offset = 0x53e8,
  204. .min = 0, .max = 65536,
  205. }, {
  206. .code = CFG_CPUVLANID,
  207. .patch = patch_8bit,
  208. .offset = 0x5d69,
  209. .min = 1, .max = 255,
  210. }, {
  211. .code = CFG_PORTENABLE_MASK,
  212. .mask = 0xFFFFFFE0,
  213. .patch = patch_portenable,
  214. }, {
  215. .code = CFG_PORTNAME_MASK,
  216. .mask = 0xFFFFFFE0,
  217. .patch = patch_portname,
  218. .size = 0x9,
  219. }, {
  220. .code = CFG_PORTVLAN_MASK,
  221. .mask = 0xFFFFFFE0,
  222. .patch = patch_portvlan,
  223. }, {
  224. .code = CFG_DOT1QVLAN_MASK,
  225. .mask = 0xFFFFFFE0,
  226. .patch = patch_dot1qvlan,
  227. }, {
  228. .code = CFG_DOT1QPORT_MASK,
  229. .mask = 0xFFFFFFE0,
  230. .patch = patch_dot1qport,
  231. }};
  232. int config_patch(void *config, int code, const char *parameter)
  233. {
  234. int i;
  235. for (i = 0; i < (sizeof(patcharr) / sizeof(struct cfg_patch)); i++) {
  236. int mask = (patcharr[i].mask != 0) ? patcharr[i].mask : ~0;
  237. if ((code & mask) == patcharr[i].code) {
  238. int retval = patcharr[i].patch(config, &patcharr[i], code, parameter);
  239. if (retval != 0)
  240. printf("failed to patch code=0x%x parameter='%s'\n", code, parameter);
  241. return retval;
  242. }
  243. }
  244. printf("nothing found to patch code=0x%x parameter='%s'\n", code, parameter);
  245. return -1;
  246. }