smisc.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:10k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Miscellaneous Internet servers: discard, echo and remote
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "socket.h"
  8. #include "proc.h"
  9. #include "remote.h"
  10. #include "smtp.h"
  11. #include "tcp.h"
  12. #include "commands.h"
  13. #include "hardware.h"
  14. #include "mailbox.h"
  15. #include "asy.h"
  16. #include "n8250.h"
  17. #include "devparam.h"
  18. #include "telnet.h"
  19. char *Rempass = ""; /* Remote access password */
  20. static int chkrpass(struct mbuf *bp);
  21. static void discserv(int s,void *unused,void *p);
  22. static void echoserv(int s,void *unused,void *p);
  23. static void termserv(int s,void *unused,void *p);
  24. static void termrx(int s,void *p1,void *p2);
  25. static void tunregister(struct iface *,int);
  26. static void tregister(struct iface *);
  27. static int Rem = -1;
  28. static int Bsr = -1;
  29. struct tserv {
  30. struct tserv *next;
  31. struct proc *proc;
  32. struct iface *ifp;
  33. };
  34. struct tserv *Tserv;
  35. /* Start up TCP discard server */
  36. int
  37. dis1(argc,argv,p)
  38. int argc;
  39. char *argv[];
  40. void *p;
  41. {
  42. uint16 port;
  43. if(argc < 2)
  44. port = IPPORT_DISCARD;
  45. else
  46. port = atoi(argv[1]);
  47. return start_tcp(port,"Discard Server",discserv,576);
  48. }
  49. static void
  50. discserv(s,unused,p)
  51. int s;
  52. void *unused;
  53. void *p;
  54. {
  55. struct mbuf *bp;
  56. sockowner(s,Curproc);
  57. logmsg(s,"open discard");
  58. if(availmem() == 0){
  59. while(recv_mbuf(s,&bp,0,NULL,NULL) > 0)
  60. free_p(&bp);
  61. }
  62. logmsg(s,"close discard");
  63. close_s(s);
  64. }
  65. /* Stop discard server */
  66. int
  67. dis0(argc,argv,p)
  68. int argc;
  69. char *argv[];
  70. void *p;
  71. {
  72. uint16 port;
  73. if(argc < 2)
  74. port = IPPORT_DISCARD;
  75. else
  76. port = atoi(argv[1]);
  77. return stop_tcp(port);
  78. }
  79. /* Start up TCP echo server */
  80. int
  81. echo1(argc,argv,p)
  82. int argc;
  83. char *argv[];
  84. void *p;
  85. {
  86. uint16 port;
  87. if(argc < 2)
  88. port = IPPORT_ECHO;
  89. else
  90. port = atoi(argv[1]);
  91. return start_tcp(port,"Echo Server",echoserv,512);
  92. }
  93. static void
  94. echoserv(s,unused,p)
  95. int s;
  96. void *unused;
  97. void *p;
  98. {
  99. struct mbuf *bp;
  100. sockowner(s,Curproc);
  101. logmsg(s,"open echo");
  102. if(availmem() == 0){
  103. while(recv_mbuf(s,&bp,0,NULL,NULL) > 0)
  104. send_mbuf(s,&bp,0,NULL,0);
  105. }
  106. logmsg(s,"close echo");
  107. close_s(s);
  108. }
  109. /* stop echo server */
  110. int
  111. echo0(argc,argv,p)
  112. int argc;
  113. char *argv[];
  114. void *p;
  115. {
  116. uint16 port;
  117. if(argc < 2)
  118. port = IPPORT_ECHO;
  119. else
  120. port = atoi(argv[1]);
  121. return stop_tcp(port);
  122. }
  123. /* Start remote exit/reboot server */
  124. int
  125. rem1(argc,argv,p)
  126. int argc;
  127. char *argv[];
  128. void *p;
  129. {
  130. struct sockaddr_in lsocket,fsock;
  131. int i;
  132. int command;
  133. struct mbuf *bp;
  134. int32 addr;
  135. int (*kp)(int32);
  136. if(Rem != -1){
  137. return 0;
  138. }
  139. ksignal(Curproc,0);
  140. chname(Curproc,"Remote listener");
  141. lsocket.sin_family = AF_INET;
  142. lsocket.sin_addr.s_addr = INADDR_ANY;
  143. if(argc < 2)
  144. lsocket.sin_port = IPPORT_REMOTE;
  145. else
  146. lsocket.sin_port = atoi(argv[1]);
  147. Rem = socket(AF_INET,SOCK_DGRAM,0);
  148. bind(Rem,(struct sockaddr *)&lsocket,sizeof(lsocket));
  149. for(;;){
  150. i = sizeof(fsock);
  151. if(recv_mbuf(Rem,&bp,0,(struct sockaddr *)&fsock,&i) == -1)
  152. break;
  153. command = PULLCHAR(&bp);
  154. switch(command){
  155. #ifdef MSDOS /* Only present on PCs running MSDOS */
  156. case SYS_RESET:
  157. i = chkrpass(bp);
  158. logmsg(Rem,"%s - Remote reset %s",
  159.  psocket((struct sockaddr *)&fsock),
  160.  i == 0 ? "PASSWORD FAIL" : "" );
  161. if(i != 0){
  162. iostop();
  163. sysreset(); /* No return */
  164. }
  165. break;
  166. #endif
  167. case SYS_EXIT:
  168. i = chkrpass(bp);
  169. logmsg(Rem,"%s - Remote exit %s",
  170.  psocket((struct sockaddr *)&fsock),
  171.  i == 0 ? "PASSWORD FAIL" : "" );
  172. if(i != 0){
  173. iostop();
  174. exit(0);
  175. }
  176. break;
  177. case KICK_ME:
  178. if(len_p(bp) >= sizeof(int32))
  179. addr = pull32(&bp);
  180. else
  181. addr = fsock.sin_addr.s_addr;
  182. for(i=0;(kp = Kicklist[i]) != NULL;i++)
  183. (*kp)(addr);
  184. break;
  185. }
  186. free_p(&bp);
  187. }
  188. close_s(Rem);
  189. Rem = -1;
  190. return 0;
  191. }
  192. /* Check remote password */
  193. static int
  194. chkrpass(bp)
  195. struct mbuf *bp;
  196. {
  197. char *lbuf;
  198. uint16 len;
  199. int rval = 0;
  200. len = len_p(bp);
  201. if(strlen(Rempass) != len)
  202. return rval;
  203. lbuf = mallocw(len);
  204. pullup(&bp,lbuf,len);
  205. if(strncmp(Rempass,lbuf,len) == 0)
  206. rval = 1;
  207. free(lbuf);
  208. return rval;
  209. }
  210. int
  211. rem0(argc,argv,p)
  212. int argc;
  213. char *argv[];
  214. void *p;
  215. {
  216. close_s(Rem);
  217. return 0;
  218. }
  219. /* Start up TCP term server */
  220. int
  221. term1(argc,argv,p)
  222. int argc;
  223. char *argv[];
  224. void *p;
  225. {
  226. uint16 port;
  227. if(argc < 2)
  228. port = IPPORT_TERM;
  229. else
  230. port = atoi(argv[1]);
  231. return start_tcp(port,"Term Server",termserv,576);
  232. }
  233. static void
  234. termserv(s,unused,p)
  235. int s;
  236. void *unused;
  237. void *p;
  238. {
  239. FILE *network = NULL;
  240. FILE *asy;
  241. char *buf = NULL;
  242. struct iface *ifp;
  243. struct route *rp;
  244. struct sockaddr_in fsocket;
  245. struct proc *rxproc = NULL;
  246. int i;
  247. sockowner(s,Curproc);
  248. logmsg(s,"open term");
  249. network = fdopen(s,"r+");
  250. if(network == NULL || (buf = malloc(BUFSIZ)) == NULL)
  251. goto quit;
  252. if(SETSIG(EABORT)){
  253. fprintf(network,"Abortrn");
  254. goto quit;
  255. }
  256. /* Prompt for and check remote password */
  257. fprintf(network,"Password: ");
  258. fgets(buf,BUFSIZ,network);
  259. rip(buf);
  260. if(strcmp(buf,Rempass) != 0){
  261. fprintf(network,"Login incorrectn");
  262. goto quit;
  263. }
  264. /* Prompt for desired interface. Verify that it exists, that
  265.  * we're not using it for our TCP connection, that it's an
  266.  * asynch port, and that there isn't already another tip, term
  267.  * or dialer session active on it.
  268.  */
  269. for(;;){
  270. fprintf(network,"Interface: ");
  271. fgets(buf,BUFSIZ,network);
  272. rip(buf);
  273. if((ifp = if_lookup(buf)) == NULL){
  274. fprintf(network,"Interface %s does not existn",buf);
  275. continue;
  276. }
  277. if(getpeername(s,(struct sockaddr *)&fsocket,&i) != -1
  278.  && !ismyaddr(fsocket.sin_addr.s_addr)
  279.  && (rp = rt_lookup(fsocket.sin_addr.s_addr)) != NULL
  280.  && rp->iface == ifp){
  281. fprintf(network,"You're using interface %s!n",ifp->name);
  282. continue;
  283. }
  284. if((asy = asyopen(buf,"r+b")) != NULL)
  285. break;
  286. fprintf(network,"Can't open interface %sn",buf);
  287. fprintf(network,"Try to bounce current user? ");
  288. fgets(buf,BUFSIZ,network);
  289. if(buf[0] == 'y' || buf[0] == 'Y'){
  290. tunregister(ifp,1);
  291. kwait(NULL);
  292. }
  293. }
  294. setvbuf(asy,NULL,_IONBF,0);
  295. tregister(ifp);
  296. fprintf(network,"Wink DTR? ");
  297. fgets(buf,BUFSIZ,network);
  298. if(buf[0] == 'y' || buf[0] == 'Y'){
  299. asy_ioctl(ifp,PARAM_DTR,1,0); /* drop DTR */
  300. ppause(1000L);
  301. asy_ioctl(ifp,PARAM_DTR,1,1); /* raise DTR */
  302. }
  303. fmode(network,STREAM_BINARY); /* Switch to raw mode */
  304. setvbuf(network,NULL,_IONBF,0);
  305. fprintf(network,"Turn off local echo? ");
  306. fgets(buf,BUFSIZ,network);
  307. if(buf[0] == 'y' || buf[0] == 'Y'){
  308. fprintf(network,"%c%c%c",IAC,WILL,TN_ECHO);
  309. /* Eat the response */
  310. for(i=0;i<3;i++)
  311. (void)fgetc(network);
  312. }
  313. #ifdef notdef
  314. FREE(buf);
  315. #endif
  316. /* Now fork into receive and transmit processes */
  317. rxproc = newproc("term rx",1500,termrx,s,network,asy,0);
  318. /* We continue to handle the TCP->asy direction */
  319. fblock(network,PART_READ);
  320. while((i = fread(buf,1,BUFSIZ,network)) > 0)
  321. fwrite(buf,1,i,asy);
  322. quit: fclose(network);
  323. fclose(asy);
  324. killproc(rxproc);
  325. logmsg(s,"close term");
  326. free(buf);
  327. close_s(s);
  328. tunregister(ifp,0);
  329. }
  330. void
  331. termrx(s,p1,p2)
  332. int s;
  333. void *p1,*p2;
  334. {
  335. int i;
  336. FILE *network = (FILE *)p1;
  337. FILE *asy = (FILE *)p2;
  338. char buf[BUFSIZ];
  339. fblock(asy,PART_READ);
  340. while((i = fread(buf,1,BUFSIZ,asy)) > 0){
  341. fwrite(buf,1,i,network);
  342. kwait(NULL);
  343. }
  344. }
  345. void
  346. tregister(ifp)
  347. struct iface *ifp;
  348. {
  349. struct tserv *tserv;
  350. tserv = (struct tserv *)calloc(1,sizeof(struct tserv));
  351. tserv->ifp = ifp;
  352. tserv->proc = Curproc;
  353. tserv->next = Tserv;
  354. Tserv = tserv;
  355. }
  356. void
  357. tunregister(ifp,kill)
  358. struct iface *ifp;
  359. int kill;
  360. {
  361. struct tserv *tserv;
  362. struct tserv *prev = NULL;
  363. for(tserv = Tserv;tserv != NULL;prev = tserv,tserv = tserv->next){
  364. if(tserv->ifp == ifp)
  365. break;
  366. }
  367. if(tserv == NULL)
  368. return;
  369. if(kill)
  370. alert(tserv->proc,EABORT);
  371. if(prev == NULL)
  372. Tserv = tserv->next;
  373. else
  374. prev->next = tserv->next;
  375. free(tserv);
  376. }
  377. /* Stop term server */
  378. int
  379. term0(argc,argv,p)
  380. int argc;
  381. char *argv[];
  382. void *p;
  383. {
  384. uint16 port;
  385. if(argc < 2)
  386. port = IPPORT_TERM;
  387. else
  388. port = atoi(argv[1]);
  389. return stop_tcp(port);
  390. }
  391. /* Start BSR server */
  392. int
  393. bsr1(argc,argv,p)
  394. int argc;
  395. char *argv[];
  396. void *p;
  397. {
  398. struct sockaddr_in lsocket,fsock;
  399. int i,c;
  400. struct mbuf *bp;
  401. char *cp;
  402. uint8 *dp;
  403. FILE *asy;
  404. if(Bsr != -1)
  405. return 1;
  406. ksignal(Curproc,0);
  407. chname(Curproc,"BSR listener");
  408. if((asy = asyopen(argv[1],"r+b")) == NULL){
  409. printf("Can't open interface %sn",argv[1]);
  410. return 1;
  411. }
  412. /* Set up the UDP socket where we'll take commands */
  413. lsocket.sin_family = AF_INET;
  414. lsocket.sin_addr.s_addr = INADDR_ANY;
  415. if(argc < 3)
  416. lsocket.sin_port = IPPORT_BSR;
  417. else
  418. lsocket.sin_port = atoi(argv[2]);
  419. Bsr = socket(AF_INET,SOCK_DGRAM,0);
  420. bind(Bsr,(struct sockaddr *)&lsocket,sizeof(lsocket));
  421. /* Process commands */
  422. for(;;){
  423. i = sizeof(fsock);
  424. if(recv_mbuf(Bsr,&bp,0,(struct sockaddr *)&fsock,&i) == -1)
  425. break;
  426. /* Check password */
  427. for(cp = Rempass;;cp++){
  428. c = PULLCHAR(&bp);
  429. if(c == -1 || *cp != c)
  430. goto endcmd;
  431. if(*cp == '')
  432. break;
  433. }
  434. /* Send remainder of packet to BSR */
  435. while((c = PULLCHAR(&bp)) != -1){
  436. fputc(c,asy);
  437. }
  438. free_p(&bp); /* Shouldn't be necessary */
  439. /* Now generate response */
  440. bp = ambufw(512); /* Larger than max response */
  441. dp = bp->data;
  442. kalarm(500L); /* Allow BSR time to respond */
  443. while((c = fgetc(asy)) != -1){
  444. kalarm(100L); /* Reset timer */
  445. *dp++ = c;
  446. bp->cnt++;
  447. }
  448. kalarm(0L);
  449. /* Send response */
  450. send_mbuf(Bsr,&bp,0,(struct sockaddr *)&fsock,sizeof(fsock));
  451. endcmd:
  452. free_p(&bp);
  453. }
  454. fclose(asy);
  455. close_s(Bsr);
  456. Bsr = -1;
  457. return 0;
  458. }
  459. int
  460. bsr0(argc,argv,p)
  461. int argc;
  462. char *argv[];
  463. void *p;
  464. {
  465. close_s(Bsr);
  466. return 0;
  467. }