inz

snmpproxy.c (raw)

  1. /*
  2.  * Copyright (c) 2015 Santtu Lakkala
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20.  * DEALINGS IN THE SOFTWARE.
  21.  */
  22. #include <netinet/in.h>
  23. #include <sys/socket.h>
  24. #include <sys/select.h>
  25. #include <arpa/inet.h>
  26. #include <stdlib.h>
  27. #include <signal.h>
  28. #include <unistd.h>
  29.  
  30. #include <stdio.h>
  31.  
  32. int running = 1;
  33.  
  34. void sighand(int signo)
  35. {
  36. (void)signo;
  37. running = 0;
  38. }
  39.  
  40. int main(int argc, char **argv)
  41. {
  42. char buffer[8192];
  43. struct sockaddr_in serv = { 0 };
  44. struct sockaddr_in clnt = { 0 };
  45. struct sockaddr_in prxy = { 0 };
  46.  
  47. int srv;
  48. int prx;
  49. int maxfd;
  50. int i;
  51.  
  52. serv.sin_family = AF_INET;
  53. serv.sin_addr.s_addr = htonl(INADDR_ANY);
  54. serv.sin_port = htons(161);
  55.  
  56. prxy.sin_family = AF_INET;
  57. inet_aton("192.168.1.1", &prxy.sin_addr);
  58. prxy.sin_port = htons(161);
  59.  
  60. signal(SIGINT, sighand);
  61.  
  62. for (i = 1; i < argc; i++) {
  63. if (*argv[i] == '-') {
  64. const char *o = &argv[i][1];
  65. while (*o) {
  66. if (i + 1 >= argc)
  67. return 1;
  68.  
  69. switch (*o++) {
  70. case 'l':
  71. if (!inet_aton(argv[++i], &serv.sin_addr))
  72. return 1;
  73. break;
  74. case 'p':
  75. serv.sin_port = htons(atoi(argv[++i]));
  76. break;
  77. case 'd':
  78. if (!inet_aton(argv[++i], &prxy.sin_addr))
  79. return 1;
  80. break;
  81. case 'P':
  82. prxy.sin_port = htons(atoi(argv[++i]));
  83. break;
  84. default:
  85. return 1;
  86. break;
  87. }
  88. }
  89. } else {
  90. return 1;
  91. }
  92. }
  93.  
  94. if ((maxfd = srv = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  95. perror("Failed to create socket for listening: ");
  96. return 1;
  97. }
  98. if ((prx = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  99. perror("Failed to create socket for proxying: ");
  100. return 1;
  101. }
  102. if (prx > maxfd)
  103. maxfd = prx;
  104.  
  105. if (bind(srv, (const struct sockaddr *)&serv, sizeof(serv)) < 0) {
  106. perror("Failed to bind: ");
  107. return 1;
  108. }
  109.  
  110. while (running) {
  111. int n;
  112. fd_set rfds;
  113. FD_ZERO(&rfds);
  114. FD_SET(prx, &rfds);
  115. FD_SET(srv, &rfds);
  116.  
  117. n = select(maxfd + 1, &rfds, NULL, NULL, NULL);
  118.  
  119. if (n > 0 && FD_ISSET(srv, &rfds)) {
  120. socklen_t len = sizeof(clnt);
  121. ssize_t r = recvfrom(srv, buffer, sizeof(buffer), 0,
  122. (struct sockaddr *)&clnt, &len);
  123. if (r == 0)
  124. break;
  125. if (r > 0) {
  126. sendto(prx, buffer, r, 0,
  127. (const struct sockaddr *)&prxy, sizeof(prxy));
  128. int len = (unsigned char)buffer[6];
  129. printf("%.*s\n", len, buffer + 7);
  130. }
  131. n--;
  132. }
  133.  
  134. if (n > 0 && FD_ISSET(prx, &rfds)) {
  135. ssize_t r = recv(prx, buffer, sizeof(buffer), 0);
  136. if (r == 0)
  137. break;
  138. if (r > 0)
  139. sendto(srv, buffer, r, 0, (const struct sockaddr *)&clnt, sizeof(clnt));
  140. }
  141. }
  142.  
  143. close(srv);
  144. close(prx);
  145.  
  146. return 0;
  147. }
  148.