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

TCP/IP协议栈

开发平台:

Visual C++

  1. /* AX25 control commands
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "timer.h"
  8. #include "proc.h"
  9. #include "iface.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "cmdparse.h"
  13. #include "socket.h"
  14. #include "mailbox.h"
  15. #include "session.h"
  16. #include "tty.h"
  17. #include "nr4.h"
  18. #include "commands.h"
  19. static int axdest(struct iface *ifp);
  20. static int axheard(struct iface *ifp);
  21. static void axflush(struct iface *ifp);
  22. static int doaxflush(int argc,char *argv[],void *p);
  23. static int doaxirtt(int argc,char *argv[],void *p);
  24. static int doaxkick(int argc,char *argv[],void *p);
  25. static int doaxreset(int argc,char *argv[],void *p);
  26. static int doaxroute(int argc,char *argv[],void *p);
  27. static int doaxstat(int argc,char *argv[],void *p);
  28. static int doaxwindow(int argc,char *argv[],void *p);
  29. static int doblimit(int argc,char *argv[],void *p);
  30. static int dodigipeat(int argc,char *argv[],void *p);
  31. static int domaxframe(int argc,char *argv[],void *p);
  32. static int domycall(int argc,char *argv[],void *p);
  33. static int don2(int argc,char *argv[],void *p);
  34. static int dopaclen(int argc,char *argv[],void *p);
  35. static int dopthresh(int argc,char *argv[],void *p);
  36. static int dot3(int argc,char *argv[],void *p);
  37. static int doversion(int argc,char *argv[],void *p);
  38. char *Ax25states[] = {
  39. "",
  40. "Disconn",
  41. "Listening",
  42. "Conn pend",
  43. "Disc pend",
  44. "Connected",
  45. "Recovery",
  46. };
  47. /* Ascii explanations for the disconnect reasons listed in lapb.h under
  48.  * "reason" in ax25_cb
  49.  */
  50. char *Axreasons[] = {
  51. "Normal",
  52. "DM received",
  53. "Timeout"
  54. };
  55. static struct cmds Axcmds[] = {
  56. "blimit", doblimit, 0, 0, NULL,
  57. "destlist", doaxdest, 0, 0, NULL,
  58. "digipeat", dodigipeat, 0, 0, NULL,
  59. "flush", doaxflush, 0, 0, NULL,
  60. "heard", doaxheard, 0, 0, NULL,
  61. "irtt", doaxirtt, 0, 0, NULL,
  62. "kick", doaxkick, 0, 2, "ax25 kick <axcb>",
  63. "maxframe", domaxframe, 0, 0, NULL,
  64. "mycall", domycall, 0, 0, NULL,
  65. "paclen", dopaclen, 0, 0, NULL,
  66. "pthresh", dopthresh, 0, 0, NULL,
  67. "reset", doaxreset, 0, 2, "ax25 reset <axcb>",
  68. "retry", don2, 0, 0, NULL,
  69. "route", doaxroute, 0, 0, NULL,
  70. "status", doaxstat, 0, 0, NULL,
  71. "t3", dot3, 0, 0, NULL,
  72. "version", doversion, 0, 0, NULL,
  73. "window", doaxwindow, 0, 0, NULL,
  74. NULL,
  75. };
  76. static int keychar(int c);
  77. /* Multiplexer for top-level ax25 command */
  78. int
  79. doax25(argc,argv,p)
  80. int argc;
  81. char *argv[];
  82. void *p;
  83. {
  84. return subcmd(Axcmds,argc,argv,p);
  85. }
  86. int
  87. doaxheard(argc,argv,p)
  88. int argc;
  89. char *argv[];
  90. void *p;
  91. {
  92. struct iface *ifp;
  93. if(argc > 1){
  94. if((ifp = if_lookup(argv[1])) == NULL){
  95. printf("Interface %s unknownn",argv[1]);
  96. return 1;
  97. }
  98. if(ifp->output != ax_output){
  99. printf("Interface %s not AX.25n",argv[1]);
  100. return 1;
  101. }
  102. axheard(ifp);
  103. return 0;
  104. }
  105. for(ifp = Ifaces;ifp != NULL;ifp = ifp->next){
  106. if(ifp->output != ax_output)
  107. continue; /* Not an ax.25 interface */
  108. if(axheard(ifp) == EOF)
  109. break;
  110. }
  111. return 0;
  112. }
  113. static int
  114. axheard(ifp)
  115. struct iface *ifp;
  116. {
  117. struct lq *lp;
  118. char tmp[AXBUF];
  119. if(ifp->hwaddr == NULL)
  120. return 0;
  121. printf("%s:n",ifp->name);
  122. printf("Station   Last heard           Pktsn");
  123. for(lp = Lq;lp != NULL;lp = lp->next){
  124. if(lp->iface != ifp)
  125. continue;
  126. printf("%-10s%-17s%8lun",pax25(tmp,lp->addr),
  127.  tformat(secclock() - lp->time),lp->currxcnt);
  128. }
  129. return 0;
  130. }
  131. int
  132. doaxdest(argc,argv,p)
  133. int argc;
  134. char *argv[];
  135. void *p;
  136. {
  137. struct iface *ifp;
  138. if(argc > 1){
  139. if((ifp = if_lookup(argv[1])) == NULL){
  140. printf("Interface %s unknownn",argv[1]);
  141. return 1;
  142. }
  143. if(ifp->output != ax_output){
  144. printf("Interface %s not AX.25n",argv[1]);
  145. return 1;
  146. }
  147. axdest(ifp);
  148. return 0;
  149. }
  150. for(ifp = Ifaces;ifp != NULL;ifp = ifp->next){
  151. if(ifp->output != ax_output)
  152. continue; /* Not an ax.25 interface */
  153. if(axdest(ifp) == EOF)
  154. break;
  155. }
  156. return 0;
  157. }
  158. static int
  159. axdest(ifp)
  160. struct iface *ifp;
  161. {
  162. struct ld *lp;
  163. struct lq *lq;
  164. char tmp[AXBUF];
  165. if(ifp->hwaddr == NULL)
  166. return 0;
  167. printf("%s:n",ifp->name);
  168. printf("Station   Last ref         Last heard           Pktsn");
  169. for(lp = Ld;lp != NULL;lp = lp->next){
  170. if(lp->iface != ifp)
  171. continue;
  172. printf("%-10s%-17s",
  173.  pax25(tmp,lp->addr),tformat(secclock() - lp->time));
  174. if(addreq(lp->addr,ifp->hwaddr)){
  175. /* Special case; it's our address */
  176. printf("%-17s",tformat(secclock() - ifp->lastsent));
  177. } else if((lq = al_lookup(ifp,lp->addr,0)) == NULL){
  178. printf("%-17s","");
  179. } else {
  180. printf("%-17s",tformat(secclock() - lq->time));
  181. }
  182. printf("%8lun",lp->currxcnt);
  183. }
  184. return 0;
  185. }
  186. static int
  187. doaxflush(argc,argv,p)
  188. int argc;
  189. char *argv[];
  190. void *p;
  191. {
  192. struct iface *ifp;
  193. for(ifp = Ifaces;ifp != NULL;ifp = ifp->next){
  194. if(ifp->output != ax_output)
  195. continue; /* Not an ax.25 interface */
  196. axflush(ifp);
  197. }
  198. return 0;
  199. }
  200. static void
  201. axflush(ifp)
  202. struct iface *ifp;
  203. {
  204. struct lq *lp,*lp1;
  205. struct ld *ld,*ld1;
  206. ifp->rawsndcnt = 0;
  207. for(lp = Lq;lp != NULL;lp = lp1){
  208. lp1 = lp->next;
  209. free(lp);
  210. }
  211. Lq = NULL;
  212. for(ld = Ld;ld != NULL;ld = ld1){
  213. ld1 = ld->next;
  214. free(ld);
  215. }
  216. Ld = NULL;
  217. }
  218. static
  219. doaxreset(argc,argv,p)
  220. int argc;
  221. char *argv[];
  222. void *p;
  223. {
  224. struct ax25_cb *axp;
  225. axp = (struct ax25_cb *)ltop(htol(argv[1]));
  226. if(!ax25val(axp)){
  227. printf(Notval);
  228. return 1;
  229. }
  230. reset_ax25(axp);
  231. return 0;
  232. }
  233. /* Display AX.25 link level control blocks */
  234. static
  235. doaxstat(argc,argv,p)
  236. int argc;
  237. char *argv[];
  238. void *p;
  239. {
  240. register struct ax25_cb *axp;
  241. char tmp[AXBUF];
  242. if(argc < 2){
  243. printf("&AXB      Snd-Q   Rcv-Q   Remote    Staten");
  244. for(axp = Ax25_cb;axp != NULL; axp = axp->next){
  245. printf("%9p %-8d%-8d%-10s%sn",
  246.  axp,
  247.  len_q(axp->txq),len_p(axp->rxq),
  248.  pax25(tmp,axp->remote),
  249.  Ax25states[axp->state]);
  250. }
  251. return 0;
  252. }
  253. axp = (struct ax25_cb *)ltop(htol(argv[1]));
  254. if(!ax25val(axp)){
  255. printf(Notval);
  256. return 1;
  257. }
  258. st_ax25(axp);
  259. return 0;
  260. }
  261. /* Dump one control block */
  262. void
  263. st_ax25(axp)
  264. register struct ax25_cb *axp;
  265. {
  266. char tmp[AXBUF];
  267. if(axp == NULL)
  268. return;
  269. printf("     &AXB Remote   RB V(S) V(R) Unack P Retry Staten");
  270. printf("%9p %-9s%c%c",axp,pax25(tmp,axp->remote),
  271.  axp->flags.rejsent ? 'R' : ' ',
  272.  axp->flags.remotebusy ? 'B' : ' ');
  273. printf(" %4d %4d",axp->vs,axp->vr);
  274. printf(" %02u/%02u %u",axp->unack,axp->maxframe,axp->proto);
  275. printf(" %02u/%02u",axp->retries,axp->n2);
  276. printf(" %sn",Ax25states[axp->state]);
  277. printf("srtt = %lu mdev = %lu ",axp->srt,axp->mdev);
  278. printf("T1: ");
  279. if(run_timer(&axp->t1))
  280. printf("%lu",read_timer(&axp->t1));
  281. else
  282. printf("stop");
  283. printf("/%lu ms; ",dur_timer(&axp->t1));
  284. printf("T3: ");
  285. if(run_timer(&axp->t3))
  286. printf("%lu",read_timer(&axp->t3));
  287. else
  288. printf("stop");
  289. printf("/%lu msn",dur_timer(&axp->t3));
  290. }
  291. /* Display or change our AX.25 address */
  292. static
  293. domycall(argc,argv,p)
  294. int argc;
  295. char *argv[];
  296. void *p;
  297. {
  298. char tmp[AXBUF];
  299. if(argc < 2){
  300. printf("%sn",pax25(tmp,Mycall));
  301. return 0;
  302. }
  303. if(setcall(Mycall,argv[1]) == -1)
  304. return -1;
  305. return 0;
  306. }
  307. /* Control AX.25 digipeating */
  308. static
  309. dodigipeat(argc,argv,p)
  310. int argc;
  311. char *argv[];
  312. void *p;
  313. {
  314. return setbool(&Digipeat,"Digipeat",argc,argv);
  315. }
  316. /* Set limit on retransmission backoff */
  317. static
  318. doblimit(argc,argv,p)
  319. int argc;
  320. char *argv[];
  321. void *p;
  322. {
  323. return setlong(&Blimit,"blimit",argc,argv);
  324. }
  325. static
  326. doversion(argc,argv,p)
  327. int argc;
  328. char *argv[];
  329. void *p;
  330. {
  331. return setshort(&Axversion,"AX25 version",argc,argv);
  332. }
  333. static
  334. doaxirtt(argc,argv,p)
  335. int argc;
  336. char *argv[];
  337. void *p;
  338. {
  339. return setlong(&Axirtt,"Initial RTT (ms)",argc,argv);
  340. }
  341. /* Set idle timer */
  342. static
  343. dot3(argc,argv,p)
  344. int argc;
  345. char *argv[];
  346. void *p;
  347. {
  348. return setlong(&T3init,"Idle poll timer (ms)",argc,argv);
  349. }
  350. /* Set retry limit count */
  351. static
  352. don2(argc,argv,p)
  353. int argc;
  354. char *argv[];
  355. void *p;
  356. {
  357. return setshort(&N2,"Retry limit",argc,argv);
  358. }
  359. /* Force a retransmission */
  360. static
  361. doaxkick(argc,argv,p)
  362. int argc;
  363. char *argv[];
  364. void *p;
  365. {
  366. struct ax25_cb *axp;
  367. axp = (struct ax25_cb *)ltop(htol(argv[1]));
  368. if(!ax25val(axp)){
  369. printf(Notval);
  370. return 1;
  371. }
  372. kick_ax25(axp);
  373. return 0;
  374. }
  375. /* Set maximum number of frames that will be allowed in flight */
  376. static
  377. domaxframe(argc,argv,p)
  378. int argc;
  379. char *argv[];
  380. void *p;
  381. {
  382. return setshort(&Maxframe,"Window size (frames)",argc,argv);
  383. }
  384. /* Set maximum length of I-frame data field */
  385. static
  386. dopaclen(argc,argv,p)
  387. int argc;
  388. char *argv[];
  389. void *p;
  390. {
  391. return setshort(&Paclen,"Max frame length (bytes)",argc,argv);
  392. }
  393. /* Set size of I-frame above which polls will be sent after a timeout */
  394. static
  395. dopthresh(argc,argv,p)
  396. int argc;
  397. char *argv[];
  398. void *p;
  399. {
  400. return setshort(&Pthresh,"Poll threshold (bytes)",argc,argv);
  401. }
  402. /* Set high water mark on receive queue that triggers RNR */
  403. static
  404. doaxwindow(argc,argv,p)
  405. int argc;
  406. char *argv[];
  407. void *p;
  408. {
  409. return setshort(&Axwindow,"AX25 receive window (bytes)",argc,argv);
  410. }
  411. /* End of ax25 subcommands */
  412. /* Initiate interactive AX.25 connect to remote station */
  413. int
  414. doconnect(argc,argv,p)
  415. int argc;
  416. char *argv[];
  417. void *p;
  418. {
  419. struct sockaddr_ax fsocket;
  420. struct session *sp;
  421. int ndigis,i,s;
  422. uint8 digis[MAXDIGIS][AXALEN];
  423. uint8 target[AXALEN];
  424. /* If digipeaters are given, put them in the routing table */
  425. if(argc > 3){
  426. setcall(target,argv[2]);
  427. ndigis = argc - 3;
  428. if(ndigis > MAXDIGIS){
  429. printf("Too many digipeatersn");
  430. return 1;
  431. }
  432. for(i=0;i<ndigis;i++){
  433. if(setcall(digis[i],argv[i+3]) == -1){
  434. printf("Bad digipeater %sn",argv[i+3]);
  435. return 1;
  436. }
  437. }
  438. if(ax_add(target,AX_LOCAL,digis,ndigis) == NULL){
  439. printf("Route add failedn");
  440. return 1;
  441. }
  442. }
  443. /* Allocate a session descriptor */
  444. if((sp = newsession(Cmdline,AX25TNC,1)) == NULL){
  445. printf("Too many sessionsn");
  446. return 1;
  447. }
  448. sp->inproc = keychar; /* Intercept ^C */
  449. if((s = socket(AF_AX25,SOCK_STREAM,0)) == -1){
  450. printf("Can't create socketn");
  451. freesession(sp);
  452. keywait(NULL,1);
  453. return 1;
  454. }
  455. fsocket.sax_family = AF_AX25;
  456. setcall(fsocket.ax25_addr,argv[2]);
  457. strncpy(fsocket.iface,argv[1],ILEN);
  458. sp->network = fdopen(s,"r+t");
  459. setvbuf(sp->network,NULL,_IOLBF,BUFSIZ);
  460. if(SETSIG(EABORT)){
  461. keywait(NULL,1);
  462. freesession(sp);
  463. return 1;
  464. }
  465. return tel_connect(sp, (struct sockaddr *)&fsocket, sizeof(struct sockaddr_ax));
  466. }
  467. /* Display and modify AX.25 routing table */
  468. static int
  469. doaxroute(argc,argv,p)
  470. int argc;
  471. char *argv[];
  472. void *p;
  473. {
  474. char tmp[AXBUF];
  475. int i,ndigis;
  476. register struct ax_route *axr;
  477. uint8 target[AXALEN],digis[MAXDIGIS][AXALEN];
  478. if(argc < 2){
  479. printf("Target    Type   Digipeatersn");
  480. for(axr = Ax_routes;axr != NULL;axr = axr->next){
  481. printf("%-10s%-6s",pax25(tmp,axr->target),
  482.  axr->type == AX_LOCAL ? "Local":"Auto");
  483. for(i=0;i<axr->ndigis;i++){
  484. printf(" %s",pax25(tmp,axr->digis[i]));
  485. }
  486. printf("n");
  487. }
  488. return 0;
  489. }
  490. if(argc < 3){
  491. printf("Usage: ax25 route add <target> [digis...]n");
  492. printf("       ax25 route drop <target>n");
  493. return 1;
  494. }
  495. if(setcall(target,argv[2]) == -1){
  496. printf("Bad target %sn",argv[2]);
  497. return 1;
  498. }
  499. switch(argv[1][0]){
  500. case 'a': /* Add route */
  501. if(argc < 3){
  502. printf("Usage: ax25 route add <target> [digis...]n");
  503. return 1;
  504. }
  505. ndigis = argc - 3;
  506. if(ndigis > MAXDIGIS){
  507. printf("Too many digipeatersn");
  508. return 1;
  509. }
  510. for(i=0;i<ndigis;i++){
  511. if(setcall(digis[i],argv[i+3]) == -1){
  512. printf("Bad digipeater %sn",argv[i+3]);
  513. return 1;
  514. }
  515. }
  516. if(ax_add(target,AX_LOCAL,digis,ndigis) == NULL){
  517. printf("Failedn");
  518. return 1;
  519. }
  520. break;
  521. case 'd': /* Drop route */
  522. if(ax_drop(target) == -1){
  523. printf("Not in tablen");
  524. return 1;
  525. }
  526. break;
  527. default:
  528. printf("Unknown command %sn",argv[1]);
  529. return 1;
  530. }
  531. return 0;
  532. }
  533. static int
  534. keychar(c)
  535. int c;
  536. {
  537. if(c != CTLC)
  538. return 1; /* Ignore all but ^C */
  539. fprintf(Current->output,"^Cn");
  540. alert(Current->proc,EABORT);
  541. return 0;
  542. }