TrafficPlugin.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /*
  2. 3proxy Traffic correct plugin v0.1 beta
  3. Íŕďčńŕë Maslov Michael aka Flexx(rus)
  4. Ôîđěóëŕ đŕń÷¸ňŕ ňđŕôôčęŕ ďî đŕçěĺđó ďŕęĺňŕ by 3APA3A
  5. email: flexx_rus@mail.ru
  6. ICQ: 299132764
  7. http://3proxy.ru/
  8. Ęŕę đŕáîňŕĺň íĺ çíŕţ (ěíîăîĺ çŕâčńčň îň âŕřčő íŕńňđîĺę). Íčęŕęčő ăŕđŕíňčé.
  9. Ń ďëóăčíîě ěîćĺňĺ äĺëŕňü âń¸, ÷ňî çŕőî÷ĺňń˙.
  10. Äîćĺí đŕńďđîńňđîí˙ňüń˙ ňîëüęî ń čńőîäíűěč ęîäŕěč čëč âěĺńňĺ ń 3proxy.
  11. Óäŕë˙ňü äŕííűé Copyright çŕďđĺůĺíî.
  12. */
  13. #include "../../structures.h"
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. int DBGLEVEL = 0;
  21. int already_loaded = 0;
  22. typedef int (* handler)(int argc, unsigned char ** argv);
  23. struct extparam * conf;
  24. struct commands * commandhandlers;
  25. struct pluginlink * pl;
  26. typedef enum {
  27. MULTIPLAY, /* ěĺňîä ęîđđĺęöčč óěíîćĺíčĺě íŕ ęîôôčöčĺíň */
  28. IPCORRECT, /* ěĺňîä ęîđđĺęöčč ń ó÷¸ňîě đŕçěĺđŕ ďŕęĺňŕ */
  29. } TRAFCORRECT_TYPE;
  30. typedef enum {
  31. UDP,
  32. TCP
  33. } CONN_TYPE;
  34. struct trafcorrect {
  35. struct trafcorrect * next;
  36. TRAFCORRECT_TYPE type;
  37. int port;
  38. PROXYSERVICE p_service;
  39. double coeff;
  40. CONN_TYPE con_type;
  41. int psize;
  42. };
  43. struct trafcorrect * firsttrafcorrect = NULL;
  44. static void addtrafcorrect(struct trafcorrect * tc) {
  45. struct trafcorrect * starttrafcorrect;
  46. if (!firsttrafcorrect) {
  47. firsttrafcorrect = tc;
  48. return;
  49. }
  50. starttrafcorrect = firsttrafcorrect;
  51. for ( ; starttrafcorrect->next ; starttrafcorrect = starttrafcorrect->next);
  52. starttrafcorrect->next = tc;
  53. }
  54. static void killtrafcorrect() {
  55. struct trafcorrect * p = firsttrafcorrect;
  56. struct trafcorrect * d;
  57. if (!firsttrafcorrect) return;
  58. firsttrafcorrect = NULL;
  59. while (p) {
  60. d = p;
  61. p = p->next;
  62. free(d);
  63. }
  64. }
  65. struct commands trafcorrect_handler;
  66. int h_trafcorrect(int argc, unsigned char ** argv) {
  67. if (argc < 2) {
  68. if(DBGLEVEL == 1)fprintf(stdout, "See documentation of traffic correct plugin.\n");
  69. return 1;
  70. }
  71. /* đĺćčě óěíîćĺíč˙ ňđŕôôčęŕ íŕ ęîýôôčöčĺíň */
  72. if (!strcmp((char *)argv[1], "m")) {
  73. struct trafcorrect * newitem;
  74. if (argc < 5) {
  75. if(DBGLEVEL == 1){
  76. fprintf(stdout, "USE: trafcorrect m <service> <port> <coefficient>\n");
  77. fprintf(stdout, "See documentation of traffic correct plugin.\n");
  78. }
  79. return 1;
  80. }
  81. newitem = (struct trafcorrect *)malloc(sizeof(struct trafcorrect));
  82. newitem->next = NULL;
  83. newitem->type = MULTIPLAY;
  84. newitem->p_service = S_NOSERVICE;
  85. if (!strcmp((char *)argv[2], (char *)"proxy")) newitem->p_service = S_PROXY;
  86. if (!strcmp((char *)argv[2], (char *)"socks4")) newitem->p_service = S_SOCKS4;
  87. if (!strcmp((char *)argv[2], (char *)"socks45")) newitem->p_service = S_SOCKS45;
  88. if (!strcmp((char *)argv[2], (char *)"socks5")) newitem->p_service = S_SOCKS5;
  89. if (!strcmp((char *)argv[2],(char *) "tcppm")) newitem->p_service = S_TCPPM;
  90. if (!strcmp((char *)argv[2],(char *) "udppm")) newitem->p_service = S_UDPPM;
  91. if (!strcmp((char *)argv[2], (char *)"admin")) newitem->p_service = S_ADMIN;
  92. if (!strcmp((char *)argv[2], (char *)"pop3p")) newitem->p_service = S_POP3P;
  93. newitem->port = atoi((char *)argv[3]);
  94. newitem->coeff = atof((char *)argv[4]);
  95. /* ďđîâĺđęŕ íŕ ęîđđĺęňíîńňü ââîäŕ */
  96. if ((newitem->port>65535) || (newitem->coeff<=0) || (newitem->coeff>100)) {
  97. free(newitem);
  98. if(DBGLEVEL == 1)fprintf(stdout, "Port must be 0<p<65535 and coefficient must be 0<c<100.\n");
  99. return 2;
  100. }
  101. addtrafcorrect(newitem);
  102. return 0;
  103. }
  104. /* đĺćčě ó÷¸ňŕ âőîä˙ůčő č čńőîä˙ůčő ďŕęĺňîâ */
  105. if (!strcmp((char *)argv[1], "p")) {
  106. struct trafcorrect * newitem;
  107. if (argc < 5) {
  108. if(DBGLEVEL == 1){
  109. fprintf(stdout, "USE: trafcorrect p <service> <tcp/udp> <port> [packet size]\n");
  110. fprintf(stdout, "See documentation of traffic correct plugin.\n");
  111. }
  112. return 1;
  113. }
  114. newitem = (struct trafcorrect *)malloc(sizeof(struct trafcorrect));
  115. newitem->next = NULL;
  116. newitem->type = IPCORRECT;
  117. newitem->p_service = S_NOSERVICE;
  118. if (!strstr((char *)argv[2], "proxy")) newitem->p_service = S_PROXY;
  119. if (!strstr((char *)argv[2], "socks4")) newitem->p_service = S_SOCKS4;
  120. if (!strstr((char *)argv[2], "socks45")) newitem->p_service = S_SOCKS45;
  121. if (!strstr((char *)argv[2], "socks5")) newitem->p_service = S_SOCKS5;
  122. if (!strstr((char *)argv[2], "tcppm")) newitem->p_service = S_TCPPM;
  123. if (!strstr((char *)argv[2], "udppm")) newitem->p_service = S_UDPPM;
  124. if (!strstr((char *)argv[2], "admin")) newitem->p_service = S_ADMIN;
  125. if (!strstr((char *)argv[2], "pop3p")) newitem->p_service = S_POP3P;
  126. newitem->con_type = TCP;
  127. newitem->psize = 52;
  128. if ((!strcmp((char *)argv[3], "udp")) && (newitem->p_service != S_PROXY) && (newitem->p_service != S_TCPPM) && (newitem->p_service != S_POP3P)) {
  129. newitem->con_type = UDP;
  130. newitem->psize = 48;
  131. }
  132. newitem->port = atoi((char *)argv[4]);
  133. /* ďîńëĺäíčé íĺîá˙çŕňĺëüíűé ďŕđŕěĺňđ - đŕçěĺđ ďŕęĺňŕ */
  134. if (argc >= 6) {
  135. newitem->psize = atoi((char *)argv[5]);
  136. }
  137. if ((newitem->port>65535) || (newitem->psize<=0)) {
  138. free(newitem);
  139. if(DBGLEVEL == 1)fprintf(stdout, "Port must be 0<p<65535.\n");
  140. return 2;
  141. }
  142. addtrafcorrect(newitem);
  143. return 0;
  144. }
  145. if(DBGLEVEL == 1)fprintf(stdout, "See documentation of traffic correct plugin.\n");
  146. return 1;
  147. }
  148. static unsigned short myhtons(unsigned short port) {
  149. return (port << 8) | (port >> 8);
  150. }
  151. LOGFUNC origlogfunc;
  152. void mylogfunc(struct clientparam * param, const unsigned char * pz) {
  153. PROXYSERVICE g_s = S_NOSERVICE;
  154. int port;
  155. int rule = 0;
  156. struct trafcorrect * starttrafcorrect = firsttrafcorrect;
  157. #ifndef NOPSTDINT
  158. uint64_t statssrv_before, statscli_before;
  159. #else
  160. unsigned long statssrv_before, statscli_before;
  161. #endif
  162. int ok = 0;
  163. for (;starttrafcorrect != NULL; starttrafcorrect = starttrafcorrect->next) {
  164. port = starttrafcorrect->port;
  165. g_s = starttrafcorrect->p_service;
  166. if (starttrafcorrect->p_service == S_NOSERVICE) g_s = param->service;
  167. if (starttrafcorrect->port <= 0) port = myhtons(*SAPORT(&param->sinsr));
  168. #ifndef NOPSTDINT
  169. statssrv_before = param->statssrv64;
  170. statscli_before = param->statscli64;
  171. #else
  172. statssrv_before = param->statssrv;
  173. statscli_before = param->statscli;
  174. #endif
  175. rule++;
  176. if (((g_s == param->service) && (port == myhtons(*SAPORT(&param->sinsr)))) ||
  177. ( ((starttrafcorrect->type == UDP) &&
  178. ((param->operation == UDPASSOC)||
  179. (param->operation == DNSRESOLVE)||
  180. (param->operation == BIND)||
  181. (param->operation == ICMPASSOC))
  182. )||(starttrafcorrect->type == TCP))) /* TCP support */
  183. {
  184. /* ôčëüňđ ďîäîř¸ë. ěîćíî čçěĺí˙ňü çíŕ÷ĺíčĺ ňđŕôôčęŕ
  185. äîěíîćŕĺě íŕ ÷čńëî */
  186. if (starttrafcorrect->type == MULTIPLAY) {
  187. #ifndef NOPSTDINT
  188. param->statssrv64 = (unsigned)((double)param->statssrv64 *starttrafcorrect->coeff);
  189. param->statscli64 = (unsigned)((double)param->statscli64 * starttrafcorrect->coeff);
  190. #else
  191. param->statssrv = (unsigned)((double)param->statssrv *starttrafcorrect->coeff);
  192. param->statscli = (unsigned)((double)param->statscli * starttrafcorrect->coeff);
  193. #endif
  194. }
  195. /* ń ó÷¸ňîě ďŕęĺňîâ */
  196. if (starttrafcorrect->type == IPCORRECT) {
  197. if (starttrafcorrect->con_type == TCP) {
  198. #ifndef NOPSTDINT
  199. param->statssrv64+=(param->nreads + 3*param->nconnects)*starttrafcorrect->psize;
  200. param->statscli64+=(param->nwrites + 3*param->nconnects)*starttrafcorrect->psize;
  201. #else
  202. param->statssrv+=(param->nreads + 3*param->nconnects)*starttrafcorrect->psize;
  203. param->statscli+=(param->nwrites + 3*param->nconnects)*starttrafcorrect->psize;
  204. #endif
  205. } else {
  206. #ifndef NOPSTDINT
  207. param->statssrv64+=param->nreads*starttrafcorrect->psize;
  208. param->statscli64+=param->nwrites*starttrafcorrect->psize;
  209. #else
  210. param->statssrv+=param->nreads*starttrafcorrect->psize;
  211. param->statscli+=param->nwrites*starttrafcorrect->psize;
  212. #endif
  213. }
  214. }
  215. if (DBGLEVEL == 1) {
  216. #ifndef NOPSTDINT
  217. fprintf(stdout, "Port=%hd; Before: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; After: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(*SAPORT(&param->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
  218. #else
  219. fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After: srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(param->sins.sin_port), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
  220. #endif
  221. }
  222. ok = 1;
  223. break;
  224. }
  225. }
  226. if ((!ok) && (DBGLEVEL == 1)) {
  227. fprintf(stdout, "No rules specifed: service=%d, port=%d, operation=%d", param->service, *SAPORT(&param->sinsr),param->operation);
  228. }
  229. origlogfunc(param, pz);
  230. }
  231. #ifdef _WIN32
  232. BOOL WINAPI DllMain( HINSTANCE hModule,
  233. DWORD ul_reason_for_call,
  234. LPVOID lpReserved
  235. )
  236. {
  237. if (ul_reason_for_call == DLL_PROCESS_DETACH) killtrafcorrect();
  238. return TRUE;
  239. }
  240. #endif
  241. #ifdef WATCOM
  242. #pragma aux start "*" parm caller [ ] value struct float struct routine [eax] modify [eax ecx edx]
  243. #undef PLUGINCALL
  244. #define PLUGINCALL
  245. #endif
  246. PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char** argv) {
  247. struct commands * starthandler;
  248. conf = pluginlink->conf;
  249. commandhandlers = pluginlink->commandhandlers;
  250. pl = pluginlink;
  251. if (argc>1) {
  252. /*for (int i = 0; i< argc; i++) fprintf(stdout,"%s ", argv[i]); */
  253. if (!strcmp((char *)argv[1], "debug")) {
  254. DBGLEVEL = 1;
  255. fprintf(stdout, "Traffic correct plugin: debug mode enabled.\n");
  256. }
  257. }
  258. if (already_loaded) {
  259. killtrafcorrect();
  260. return 0;
  261. }
  262. already_loaded = 1;
  263. /* äîáŕâë˙ĺě ęîěŕíäó "trafcorrect" */
  264. starthandler = commandhandlers;
  265. for ( ; starthandler->next; starthandler = starthandler->next);
  266. trafcorrect_handler.next = NULL;
  267. trafcorrect_handler.minargs = 1;
  268. trafcorrect_handler.maxargs = 10;
  269. trafcorrect_handler.command = "trafcorrect";
  270. trafcorrect_handler.handler = h_trafcorrect;
  271. starthandler->next = &trafcorrect_handler;
  272. /* ďîäěĺí˙ĺě conf->logfunc, ń öĺëüţ ęîíňđîëčđîâŕňü ňđŕôôčę */
  273. origlogfunc = conf->logfunc;
  274. conf->logfunc = mylogfunc;
  275. return 0;
  276. }
  277. #ifdef __cplusplus
  278. }
  279. #endif