vtysh.c 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485
  1. /* Virtual terminal interface shell.
  2. * Copyright (C) 2000 Kunihiro Ishiguro
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  18. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. * 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include <sys/un.h>
  23. #include <setjmp.h>
  24. #include <sys/wait.h>
  25. #include <sys/resource.h>
  26. #include <sys/stat.h>
  27. #include <readline/readline.h>
  28. #include <readline/history.h>
  29. #include "command.h"
  30. #include "memory.h"
  31. #include "vtysh/vtysh.h"
  32. #include "log.h"
  33. #include "bgpd/bgp_vty.h"
  34. /* Struct VTY. */
  35. struct vty *vty;
  36. /* VTY shell pager name. */
  37. char *vtysh_pager_name = NULL;
  38. /* VTY shell client structure. */
  39. struct vtysh_client
  40. {
  41. int fd;
  42. const char *name;
  43. int flag;
  44. const char *path;
  45. } vtysh_client[] =
  46. {
  47. { .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path = ZEBRA_VTYSH_PATH},
  48. { .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH},
  49. { .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH},
  50. { .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH},
  51. { .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},
  52. { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},
  53. { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},
  54. { .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH},
  55. { .fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .path = PIM_VTYSH_PATH},
  56. >>>>>>> [pim] pim commands added to vtysh
  57. };
  58. /* We need direct access to ripd to implement vtysh_exit_ripd_only. */
  59. static struct vtysh_client *ripd_client = NULL;
  60. /* Using integrated config from Quagga.conf. Default is no. */
  61. int vtysh_writeconfig_integrated = 0;
  62. extern char config_default[];
  63. static void
  64. vclient_close (struct vtysh_client *vclient)
  65. {
  66. if (vclient->fd >= 0)
  67. {
  68. fprintf(stderr,
  69. "Warning: closing connection to %s because of an I/O error!\n",
  70. vclient->name);
  71. close (vclient->fd);
  72. vclient->fd = -1;
  73. }
  74. }
  75. /* Following filled with debug code to trace a problematic condition
  76. * under load - it SHOULD handle it. */
  77. #define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
  78. static int
  79. vtysh_client_config (struct vtysh_client *vclient, char *line)
  80. {
  81. int ret;
  82. char *buf;
  83. size_t bufsz;
  84. char *pbuf;
  85. size_t left;
  86. char *eoln;
  87. int nbytes;
  88. int i;
  89. int readln;
  90. if (vclient->fd < 0)
  91. return CMD_SUCCESS;
  92. ret = write (vclient->fd, line, strlen (line) + 1);
  93. if (ret <= 0)
  94. {
  95. vclient_close (vclient);
  96. return CMD_SUCCESS;
  97. }
  98. /* Allow enough room for buffer to read more than a few pages from socket. */
  99. bufsz = 5 * getpagesize() + 1;
  100. buf = XMALLOC(MTYPE_TMP, bufsz);
  101. memset(buf, 0, bufsz);
  102. pbuf = buf;
  103. while (1)
  104. {
  105. if (pbuf >= ((buf + bufsz) -1))
  106. {
  107. fprintf (stderr, ERR_WHERE_STRING \
  108. "warning - pbuf beyond buffer end.\n");
  109. return CMD_WARNING;
  110. }
  111. readln = (buf + bufsz) - pbuf - 1;
  112. nbytes = read (vclient->fd, pbuf, readln);
  113. if (nbytes <= 0)
  114. {
  115. if (errno == EINTR)
  116. continue;
  117. fprintf(stderr, ERR_WHERE_STRING "(%u)", errno);
  118. perror("");
  119. if (errno == EAGAIN || errno == EIO)
  120. continue;
  121. vclient_close (vclient);
  122. XFREE(MTYPE_TMP, buf);
  123. return CMD_SUCCESS;
  124. }
  125. pbuf[nbytes] = '\0';
  126. if (nbytes >= 4)
  127. {
  128. i = nbytes - 4;
  129. if (pbuf[i] == '\0' && pbuf[i + 1] == '\0' && pbuf[i + 2] == '\0')
  130. {
  131. ret = pbuf[i + 3];
  132. break;
  133. }
  134. }
  135. pbuf += nbytes;
  136. /* See if a line exists in buffer, if so parse and consume it, and
  137. * reset read position. */
  138. if ((eoln = strrchr(buf, '\n')) == NULL)
  139. continue;
  140. if (eoln >= ((buf + bufsz) - 1))
  141. {
  142. fprintf (stderr, ERR_WHERE_STRING \
  143. "warning - eoln beyond buffer end.\n");
  144. }
  145. vtysh_config_parse(buf);
  146. eoln++;
  147. left = (size_t)(buf + bufsz - eoln);
  148. memmove(buf, eoln, left);
  149. buf[bufsz-1] = '\0';
  150. pbuf = buf + strlen(buf);
  151. }
  152. /* Parse anything left in the buffer. */
  153. vtysh_config_parse (buf);
  154. XFREE(MTYPE_TMP, buf);
  155. return ret;
  156. }
  157. static int
  158. vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)
  159. {
  160. int ret;
  161. char buf[1001];
  162. int nbytes;
  163. int i;
  164. int numnulls = 0;
  165. if (vclient->fd < 0)
  166. return CMD_SUCCESS;
  167. ret = write (vclient->fd, line, strlen (line) + 1);
  168. if (ret <= 0)
  169. {
  170. vclient_close (vclient);
  171. return CMD_SUCCESS;
  172. }
  173. while (1)
  174. {
  175. nbytes = read (vclient->fd, buf, sizeof(buf)-1);
  176. if (nbytes <= 0 && errno != EINTR)
  177. {
  178. vclient_close (vclient);
  179. return CMD_SUCCESS;
  180. }
  181. if (nbytes > 0)
  182. {
  183. if ((numnulls == 3) && (nbytes == 1))
  184. return buf[0];
  185. buf[nbytes] = '\0';
  186. fputs (buf, fp);
  187. fflush (fp);
  188. /* check for trailling \0\0\0<ret code>,
  189. * even if split across reads
  190. * (see lib/vty.c::vtysh_read)
  191. */
  192. if (nbytes >= 4)
  193. {
  194. i = nbytes-4;
  195. numnulls = 0;
  196. }
  197. else
  198. i = 0;
  199. while (i < nbytes && numnulls < 3)
  200. {
  201. if (buf[i++] == '\0')
  202. numnulls++;
  203. else
  204. numnulls = 0;
  205. }
  206. /* got 3 or more trailing NULs? */
  207. if ((numnulls >= 3) && (i < nbytes))
  208. return (buf[nbytes-1]);
  209. }
  210. }
  211. }
  212. void
  213. vtysh_exit_ripd_only (void)
  214. {
  215. if (ripd_client)
  216. vtysh_client_execute (ripd_client, "exit", stdout);
  217. }
  218. void
  219. vtysh_pager_init (void)
  220. {
  221. char *pager_defined;
  222. pager_defined = getenv ("VTYSH_PAGER");
  223. if (pager_defined)
  224. vtysh_pager_name = strdup (pager_defined);
  225. else
  226. vtysh_pager_name = strdup ("more");
  227. }
  228. /* Command execution over the vty interface. */
  229. static int
  230. vtysh_execute_func (const char *line, int pager)
  231. {
  232. int ret, cmd_stat;
  233. u_int i;
  234. vector vline;
  235. struct cmd_element *cmd;
  236. FILE *fp = NULL;
  237. int closepager = 0;
  238. int tried = 0;
  239. int saved_ret, saved_node;
  240. /* Split readline string up into the vector. */
  241. vline = cmd_make_strvec (line);
  242. if (vline == NULL)
  243. return CMD_SUCCESS;
  244. saved_ret = ret = cmd_execute_command (vline, vty, &cmd, 1);
  245. saved_node = vty->node;
  246. /* If command doesn't succeeded in current node, try to walk up in node tree.
  247. * Changing vty->node is enough to try it just out without actual walkup in
  248. * the vtysh. */
  249. while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON && ret != CMD_WARNING
  250. && vty->node > CONFIG_NODE)
  251. {
  252. vty->node = node_parent(vty->node);
  253. ret = cmd_execute_command (vline, vty, &cmd, 1);
  254. tried++;
  255. }
  256. vty->node = saved_node;
  257. /* If command succeeded in any other node than current (tried > 0) we have
  258. * to move into node in the vtysh where it succeeded. */
  259. if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON || ret == CMD_WARNING)
  260. {
  261. if ((saved_node == BGP_VPNV4_NODE || saved_node == BGP_IPV4_NODE
  262. || saved_node == BGP_IPV6_NODE || saved_node == BGP_IPV4M_NODE
  263. || saved_node == BGP_IPV6M_NODE)
  264. && (tried == 1))
  265. {
  266. vtysh_execute("exit-address-family");
  267. }
  268. else if ((saved_node == KEYCHAIN_KEY_NODE) && (tried == 1))
  269. {
  270. vtysh_execute("exit");
  271. }
  272. else if (tried)
  273. {
  274. vtysh_execute ("end");
  275. vtysh_execute ("configure terminal");
  276. }
  277. }
  278. /* If command didn't succeed in any node, continue with return value from
  279. * first try. */
  280. else if (tried)
  281. {
  282. ret = saved_ret;
  283. }
  284. cmd_free_strvec (vline);
  285. cmd_stat = ret;
  286. switch (ret)
  287. {
  288. case CMD_WARNING:
  289. if (vty->type == VTY_FILE)
  290. fprintf (stdout,"Warning...\n");
  291. break;
  292. case CMD_ERR_AMBIGUOUS:
  293. fprintf (stdout,"%% Ambiguous command.\n");
  294. break;
  295. case CMD_ERR_NO_MATCH:
  296. fprintf (stdout,"%% Unknown command.\n");
  297. break;
  298. case CMD_ERR_INCOMPLETE:
  299. fprintf (stdout,"%% Command incomplete.\n");
  300. break;
  301. case CMD_SUCCESS_DAEMON:
  302. {
  303. /* FIXME: Don't open pager for exit commands. popen() causes problems
  304. * if exited from vtysh at all. This hack shouldn't cause any problem
  305. * but is really ugly. */
  306. if (pager && vtysh_pager_name && (strncmp(line, "exit", 4) != 0))
  307. {
  308. fp = popen (vtysh_pager_name, "w");
  309. if (fp == NULL)
  310. {
  311. perror ("popen failed for pager");
  312. fp = stdout;
  313. }
  314. else
  315. closepager=1;
  316. }
  317. else
  318. fp = stdout;
  319. if (! strcmp(cmd->string,"configure terminal"))
  320. {
  321. for (i = 0; i < array_size(vtysh_client); i++)
  322. {
  323. cmd_stat = vtysh_client_execute(&vtysh_client[i], line, fp);
  324. if (cmd_stat == CMD_WARNING)
  325. break;
  326. }
  327. if (cmd_stat)
  328. {
  329. line = "end";
  330. vline = cmd_make_strvec (line);
  331. if (vline == NULL)
  332. {
  333. if (pager && vtysh_pager_name && fp && closepager)
  334. {
  335. if (pclose (fp) == -1)
  336. {
  337. perror ("pclose failed for pager");
  338. }
  339. fp = NULL;
  340. }
  341. return CMD_SUCCESS;
  342. }
  343. ret = cmd_execute_command (vline, vty, &cmd, 1);
  344. cmd_free_strvec (vline);
  345. if (ret != CMD_SUCCESS_DAEMON)
  346. break;
  347. }
  348. else
  349. if (cmd->func)
  350. {
  351. (*cmd->func) (cmd, vty, 0, NULL);
  352. break;
  353. }
  354. }
  355. cmd_stat = CMD_SUCCESS;
  356. for (i = 0; i < array_size(vtysh_client); i++)
  357. {
  358. if (cmd->daemon & vtysh_client[i].flag)
  359. {
  360. cmd_stat = vtysh_client_execute(&vtysh_client[i], line, fp);
  361. if (cmd_stat != CMD_SUCCESS)
  362. break;
  363. }
  364. }
  365. if (cmd_stat != CMD_SUCCESS)
  366. break;
  367. if (cmd->func)
  368. (*cmd->func) (cmd, vty, 0, NULL);
  369. }
  370. }
  371. if (pager && vtysh_pager_name && fp && closepager)
  372. {
  373. if (pclose (fp) == -1)
  374. {
  375. perror ("pclose failed for pager");
  376. }
  377. fp = NULL;
  378. }
  379. return cmd_stat;
  380. }
  381. int
  382. vtysh_execute_no_pager (const char *line)
  383. {
  384. return vtysh_execute_func (line, 0);
  385. }
  386. int
  387. vtysh_execute (const char *line)
  388. {
  389. return vtysh_execute_func (line, 1);
  390. }
  391. /* Configration make from file. */
  392. int
  393. vtysh_config_from_file (struct vty *vty, FILE *fp)
  394. {
  395. int ret;
  396. vector vline;
  397. struct cmd_element *cmd;
  398. while (fgets (vty->buf, VTY_BUFSIZ, fp))
  399. {
  400. if (vty->buf[0] == '!' || vty->buf[1] == '#')
  401. continue;
  402. vline = cmd_make_strvec (vty->buf);
  403. /* In case of comment line. */
  404. if (vline == NULL)
  405. continue;
  406. /* Execute configuration command : this is strict match. */
  407. ret = cmd_execute_command_strict (vline, vty, &cmd);
  408. /* Try again with setting node to CONFIG_NODE. */
  409. if (ret != CMD_SUCCESS
  410. && ret != CMD_SUCCESS_DAEMON
  411. && ret != CMD_WARNING)
  412. {
  413. if (vty->node == KEYCHAIN_KEY_NODE)
  414. {
  415. vty->node = KEYCHAIN_NODE;
  416. vtysh_exit_ripd_only ();
  417. ret = cmd_execute_command_strict (vline, vty, &cmd);
  418. if (ret != CMD_SUCCESS
  419. && ret != CMD_SUCCESS_DAEMON
  420. && ret != CMD_WARNING)
  421. {
  422. vtysh_exit_ripd_only ();
  423. vty->node = CONFIG_NODE;
  424. ret = cmd_execute_command_strict (vline, vty, &cmd);
  425. }
  426. }
  427. else
  428. {
  429. vtysh_execute ("end");
  430. vtysh_execute ("configure terminal");
  431. vty->node = CONFIG_NODE;
  432. ret = cmd_execute_command_strict (vline, vty, &cmd);
  433. }
  434. }
  435. cmd_free_strvec (vline);
  436. switch (ret)
  437. {
  438. case CMD_WARNING:
  439. if (vty->type == VTY_FILE)
  440. fprintf (stdout,"Warning...\n");
  441. break;
  442. case CMD_ERR_AMBIGUOUS:
  443. fprintf (stdout,"%% Ambiguous command.\n");
  444. break;
  445. case CMD_ERR_NO_MATCH:
  446. fprintf (stdout,"%% Unknown command: %s", vty->buf);
  447. break;
  448. case CMD_ERR_INCOMPLETE:
  449. fprintf (stdout,"%% Command incomplete.\n");
  450. break;
  451. case CMD_SUCCESS_DAEMON:
  452. {
  453. u_int i;
  454. int cmd_stat = CMD_SUCCESS;
  455. for (i = 0; i < array_size(vtysh_client); i++)
  456. {
  457. if (cmd->daemon & vtysh_client[i].flag)
  458. {
  459. cmd_stat = vtysh_client_execute (&vtysh_client[i],
  460. vty->buf, stdout);
  461. if (cmd_stat != CMD_SUCCESS)
  462. break;
  463. }
  464. }
  465. if (cmd_stat != CMD_SUCCESS)
  466. break;
  467. if (cmd->func)
  468. (*cmd->func) (cmd, vty, 0, NULL);
  469. }
  470. }
  471. }
  472. return CMD_SUCCESS;
  473. }
  474. /* We don't care about the point of the cursor when '?' is typed. */
  475. int
  476. vtysh_rl_describe (void)
  477. {
  478. int ret;
  479. unsigned int i;
  480. vector vline;
  481. vector describe;
  482. int width;
  483. struct cmd_token *token;
  484. vline = cmd_make_strvec (rl_line_buffer);
  485. /* In case of '> ?'. */
  486. if (vline == NULL)
  487. {
  488. vline = vector_init (1);
  489. vector_set (vline, '\0');
  490. }
  491. else
  492. if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
  493. vector_set (vline, '\0');
  494. describe = cmd_describe_command (vline, vty, &ret);
  495. fprintf (stdout,"\n");
  496. /* Ambiguous and no match error. */
  497. switch (ret)
  498. {
  499. case CMD_ERR_AMBIGUOUS:
  500. cmd_free_strvec (vline);
  501. fprintf (stdout,"%% Ambiguous command.\n");
  502. rl_on_new_line ();
  503. return 0;
  504. break;
  505. case CMD_ERR_NO_MATCH:
  506. cmd_free_strvec (vline);
  507. fprintf (stdout,"%% There is no matched command.\n");
  508. rl_on_new_line ();
  509. return 0;
  510. break;
  511. }
  512. /* Get width of command string. */
  513. width = 0;
  514. for (i = 0; i < vector_active (describe); i++)
  515. if ((token = vector_slot (describe, i)) != NULL)
  516. {
  517. int len;
  518. if (token->cmd[0] == '\0')
  519. continue;
  520. len = strlen (token->cmd);
  521. if (token->cmd[0] == '.')
  522. len--;
  523. if (width < len)
  524. width = len;
  525. }
  526. for (i = 0; i < vector_active (describe); i++)
  527. if ((token = vector_slot (describe, i)) != NULL)
  528. {
  529. if (token->cmd[0] == '\0')
  530. continue;
  531. if (! token->desc)
  532. fprintf (stdout," %-s\n",
  533. token->cmd[0] == '.' ? token->cmd + 1 : token->cmd);
  534. else
  535. fprintf (stdout," %-*s %s\n",
  536. width,
  537. token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
  538. token->desc);
  539. }
  540. cmd_free_strvec (vline);
  541. vector_free (describe);
  542. rl_on_new_line();
  543. return 0;
  544. }
  545. /* Result of cmd_complete_command() call will be stored here
  546. * and used in new_completion() in order to put the space in
  547. * correct places only. */
  548. int complete_status;
  549. static char *
  550. command_generator (const char *text, int state)
  551. {
  552. vector vline;
  553. static char **matched = NULL;
  554. static int index = 0;
  555. /* First call. */
  556. if (! state)
  557. {
  558. index = 0;
  559. if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
  560. return NULL;
  561. vline = cmd_make_strvec (rl_line_buffer);
  562. if (vline == NULL)
  563. return NULL;
  564. if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
  565. vector_set (vline, '\0');
  566. matched = cmd_complete_command (vline, vty, &complete_status);
  567. }
  568. if (matched && matched[index])
  569. return matched[index++];
  570. return NULL;
  571. }
  572. static char **
  573. new_completion (char *text, int start, int end)
  574. {
  575. char **matches;
  576. matches = rl_completion_matches (text, command_generator);
  577. if (matches)
  578. {
  579. rl_point = rl_end;
  580. if (complete_status != CMD_COMPLETE_FULL_MATCH)
  581. /* only append a space on full match */
  582. rl_completion_append_character = '\0';
  583. }
  584. return matches;
  585. }
  586. #if 0
  587. /* This function is not actually being used. */
  588. static char **
  589. vtysh_completion (char *text, int start, int end)
  590. {
  591. int ret;
  592. vector vline;
  593. char **matched = NULL;
  594. if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
  595. return NULL;
  596. vline = cmd_make_strvec (rl_line_buffer);
  597. if (vline == NULL)
  598. return NULL;
  599. /* In case of 'help \t'. */
  600. if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
  601. vector_set (vline, '\0');
  602. matched = cmd_complete_command (vline, vty, &ret);
  603. cmd_free_strvec (vline);
  604. return (char **) matched;
  605. }
  606. #endif
  607. /* Vty node structures. */
  608. static struct cmd_node bgp_node =
  609. {
  610. BGP_NODE,
  611. "%s(config-router)# ",
  612. };
  613. static struct cmd_node rip_node =
  614. {
  615. RIP_NODE,
  616. "%s(config-router)# ",
  617. };
  618. static struct cmd_node isis_node =
  619. {
  620. ISIS_NODE,
  621. "%s(config-router)# ",
  622. };
  623. static struct cmd_node interface_node =
  624. {
  625. INTERFACE_NODE,
  626. "%s(config-if)# ",
  627. };
  628. static struct cmd_node rmap_node =
  629. {
  630. RMAP_NODE,
  631. "%s(config-route-map)# "
  632. };
  633. static struct cmd_node zebra_node =
  634. {
  635. ZEBRA_NODE,
  636. "%s(config-router)# "
  637. };
  638. static struct cmd_node bgp_vpnv4_node =
  639. {
  640. BGP_VPNV4_NODE,
  641. "%s(config-router-af)# "
  642. };
  643. static struct cmd_node bgp_ipv4_node =
  644. {
  645. BGP_IPV4_NODE,
  646. "%s(config-router-af)# "
  647. };
  648. static struct cmd_node bgp_ipv4m_node =
  649. {
  650. BGP_IPV4M_NODE,
  651. "%s(config-router-af)# "
  652. };
  653. static struct cmd_node bgp_ipv6_node =
  654. {
  655. BGP_IPV6_NODE,
  656. "%s(config-router-af)# "
  657. };
  658. static struct cmd_node bgp_ipv6m_node =
  659. {
  660. BGP_IPV6M_NODE,
  661. "%s(config-router-af)# "
  662. };
  663. static struct cmd_node ospf_node =
  664. {
  665. OSPF_NODE,
  666. "%s(config-router)# "
  667. };
  668. static struct cmd_node ripng_node =
  669. {
  670. RIPNG_NODE,
  671. "%s(config-router)# "
  672. };
  673. static struct cmd_node ospf6_node =
  674. {
  675. OSPF6_NODE,
  676. "%s(config-ospf6)# "
  677. };
  678. static struct cmd_node babel_node =
  679. {
  680. BABEL_NODE,
  681. "%s(config-babel)# "
  682. };
  683. static struct cmd_node keychain_node =
  684. {
  685. KEYCHAIN_NODE,
  686. "%s(config-keychain)# "
  687. };
  688. static struct cmd_node keychain_key_node =
  689. {
  690. KEYCHAIN_KEY_NODE,
  691. "%s(config-keychain-key)# "
  692. };
  693. /* Defined in lib/vty.c */
  694. extern struct cmd_node vty_node;
  695. /* When '^Z' is received from vty, move down to the enable mode. */
  696. int
  697. vtysh_end (void)
  698. {
  699. switch (vty->node)
  700. {
  701. case VIEW_NODE:
  702. case ENABLE_NODE:
  703. /* Nothing to do. */
  704. break;
  705. default:
  706. vty->node = ENABLE_NODE;
  707. break;
  708. }
  709. return CMD_SUCCESS;
  710. }
  711. DEFUNSH (VTYSH_ALL,
  712. vtysh_end_all,
  713. vtysh_end_all_cmd,
  714. "end",
  715. "End current mode and change to enable mode\n")
  716. {
  717. return vtysh_end ();
  718. }
  719. DEFUNSH (VTYSH_BGPD,
  720. router_bgp,
  721. router_bgp_cmd,
  722. "router bgp " CMD_AS_RANGE,
  723. ROUTER_STR
  724. BGP_STR
  725. AS_STR)
  726. {
  727. vty->node = BGP_NODE;
  728. return CMD_SUCCESS;
  729. }
  730. ALIAS_SH (VTYSH_BGPD,
  731. router_bgp,
  732. router_bgp_view_cmd,
  733. "router bgp " CMD_AS_RANGE " view WORD",
  734. ROUTER_STR
  735. BGP_STR
  736. AS_STR
  737. "BGP view\n"
  738. "view name\n")
  739. DEFUNSH (VTYSH_BGPD,
  740. address_family_vpnv4,
  741. address_family_vpnv4_cmd,
  742. "address-family vpnv4",
  743. "Enter Address Family command mode\n"
  744. "Address family\n")
  745. {
  746. vty->node = BGP_VPNV4_NODE;
  747. return CMD_SUCCESS;
  748. }
  749. DEFUNSH (VTYSH_BGPD,
  750. address_family_vpnv4_unicast,
  751. address_family_vpnv4_unicast_cmd,
  752. "address-family vpnv4 unicast",
  753. "Enter Address Family command mode\n"
  754. "Address family\n"
  755. "Address Family Modifier\n")
  756. {
  757. vty->node = BGP_VPNV4_NODE;
  758. return CMD_SUCCESS;
  759. }
  760. DEFUNSH (VTYSH_BGPD,
  761. address_family_ipv4_unicast,
  762. address_family_ipv4_unicast_cmd,
  763. "address-family ipv4 unicast",
  764. "Enter Address Family command mode\n"
  765. "Address family\n"
  766. "Address Family Modifier\n")
  767. {
  768. vty->node = BGP_IPV4_NODE;
  769. return CMD_SUCCESS;
  770. }
  771. DEFUNSH (VTYSH_BGPD,
  772. address_family_ipv4_multicast,
  773. address_family_ipv4_multicast_cmd,
  774. "address-family ipv4 multicast",
  775. "Enter Address Family command mode\n"
  776. "Address family\n"
  777. "Address Family Modifier\n")
  778. {
  779. vty->node = BGP_IPV4M_NODE;
  780. return CMD_SUCCESS;
  781. }
  782. DEFUNSH (VTYSH_BGPD,
  783. address_family_ipv6,
  784. address_family_ipv6_cmd,
  785. "address-family ipv6",
  786. "Enter Address Family command mode\n"
  787. "Address family\n")
  788. {
  789. vty->node = BGP_IPV6_NODE;
  790. return CMD_SUCCESS;
  791. }
  792. DEFUNSH (VTYSH_BGPD,
  793. address_family_ipv6_unicast,
  794. address_family_ipv6_unicast_cmd,
  795. "address-family ipv6 unicast",
  796. "Enter Address Family command mode\n"
  797. "Address family\n"
  798. "Address Family Modifier\n")
  799. {
  800. vty->node = BGP_IPV6_NODE;
  801. return CMD_SUCCESS;
  802. }
  803. DEFUNSH (VTYSH_BGPD,
  804. address_family_ipv6_multicast,
  805. address_family_ipv6_multicast_cmd,
  806. "address-family ipv6 multicast",
  807. "Enter Address Family command mode\n"
  808. "Address family\n"
  809. "Address Family Modifier\n")
  810. {
  811. vty->node = BGP_IPV6M_NODE;
  812. return CMD_SUCCESS;
  813. }
  814. DEFUNSH (VTYSH_RIPD,
  815. key_chain,
  816. key_chain_cmd,
  817. "key chain WORD",
  818. "Authentication key management\n"
  819. "Key-chain management\n"
  820. "Key-chain name\n")
  821. {
  822. vty->node = KEYCHAIN_NODE;
  823. return CMD_SUCCESS;
  824. }
  825. DEFUNSH (VTYSH_RIPD,
  826. key,
  827. key_cmd,
  828. "key <0-2147483647>",
  829. "Configure a key\n"
  830. "Key identifier number\n")
  831. {
  832. vty->node = KEYCHAIN_KEY_NODE;
  833. return CMD_SUCCESS;
  834. }
  835. DEFUNSH (VTYSH_RIPD,
  836. router_rip,
  837. router_rip_cmd,
  838. "router rip",
  839. ROUTER_STR
  840. "RIP")
  841. {
  842. vty->node = RIP_NODE;
  843. return CMD_SUCCESS;
  844. }
  845. DEFUNSH (VTYSH_RIPNGD,
  846. router_ripng,
  847. router_ripng_cmd,
  848. "router ripng",
  849. ROUTER_STR
  850. "RIPng")
  851. {
  852. vty->node = RIPNG_NODE;
  853. return CMD_SUCCESS;
  854. }
  855. DEFUNSH (VTYSH_OSPFD,
  856. router_ospf,
  857. router_ospf_cmd,
  858. "router ospf",
  859. "Enable a routing process\n"
  860. "Start OSPF configuration\n")
  861. {
  862. vty->node = OSPF_NODE;
  863. return CMD_SUCCESS;
  864. }
  865. DEFUNSH (VTYSH_OSPF6D,
  866. router_ospf6,
  867. router_ospf6_cmd,
  868. "router ospf6",
  869. OSPF6_ROUTER_STR
  870. OSPF6_STR)
  871. {
  872. vty->node = OSPF6_NODE;
  873. return CMD_SUCCESS;
  874. }
  875. DEFUNSH (VTYSH_BABELD,
  876. router_babel,
  877. router_babel_cmd,
  878. "router babel",
  879. ROUTER_STR
  880. "Babel")
  881. {
  882. vty->node = BABEL_NODE;
  883. return CMD_SUCCESS;
  884. }
  885. DEFUNSH (VTYSH_ISISD,
  886. router_isis,
  887. router_isis_cmd,
  888. "router isis WORD",
  889. ROUTER_STR
  890. "ISO IS-IS\n"
  891. "ISO Routing area tag")
  892. {
  893. vty->node = ISIS_NODE;
  894. return CMD_SUCCESS;
  895. }
  896. DEFUNSH (VTYSH_RMAP,
  897. route_map,
  898. route_map_cmd,
  899. "route-map WORD (deny|permit) <1-65535>",
  900. "Create route-map or enter route-map command mode\n"
  901. "Route map tag\n"
  902. "Route map denies set operations\n"
  903. "Route map permits set operations\n"
  904. "Sequence to insert to/delete from existing route-map entry\n")
  905. {
  906. vty->node = RMAP_NODE;
  907. return CMD_SUCCESS;
  908. }
  909. DEFUNSH (VTYSH_ALL,
  910. vtysh_line_vty,
  911. vtysh_line_vty_cmd,
  912. "line vty",
  913. "Configure a terminal line\n"
  914. "Virtual terminal\n")
  915. {
  916. vty->node = VTY_NODE;
  917. return CMD_SUCCESS;
  918. }
  919. DEFUNSH (VTYSH_ALL,
  920. vtysh_enable,
  921. vtysh_enable_cmd,
  922. "enable",
  923. "Turn on privileged mode command\n")
  924. {
  925. vty->node = ENABLE_NODE;
  926. return CMD_SUCCESS;
  927. }
  928. DEFUNSH (VTYSH_ALL,
  929. vtysh_disable,
  930. vtysh_disable_cmd,
  931. "disable",
  932. "Turn off privileged mode command\n")
  933. {
  934. if (vty->node == ENABLE_NODE)
  935. vty->node = VIEW_NODE;
  936. return CMD_SUCCESS;
  937. }
  938. DEFUNSH (VTYSH_ALL,
  939. vtysh_config_terminal,
  940. vtysh_config_terminal_cmd,
  941. "configure terminal",
  942. "Configuration from vty interface\n"
  943. "Configuration terminal\n")
  944. {
  945. vty->node = CONFIG_NODE;
  946. return CMD_SUCCESS;
  947. }
  948. static int
  949. vtysh_exit (struct vty *vty)
  950. {
  951. switch (vty->node)
  952. {
  953. case VIEW_NODE:
  954. case ENABLE_NODE:
  955. exit (0);
  956. break;
  957. case CONFIG_NODE:
  958. vty->node = ENABLE_NODE;
  959. break;
  960. case INTERFACE_NODE:
  961. case ZEBRA_NODE:
  962. case BGP_NODE:
  963. case RIP_NODE:
  964. case RIPNG_NODE:
  965. case OSPF_NODE:
  966. case OSPF6_NODE:
  967. case BABEL_NODE:
  968. case ISIS_NODE:
  969. case MASC_NODE:
  970. case RMAP_NODE:
  971. case VTY_NODE:
  972. case KEYCHAIN_NODE:
  973. vtysh_execute("end");
  974. vtysh_execute("configure terminal");
  975. vty->node = CONFIG_NODE;
  976. break;
  977. case BGP_VPNV4_NODE:
  978. case BGP_IPV4_NODE:
  979. case BGP_IPV4M_NODE:
  980. case BGP_IPV6_NODE:
  981. case BGP_IPV6M_NODE:
  982. vty->node = BGP_NODE;
  983. break;
  984. case KEYCHAIN_KEY_NODE:
  985. vty->node = KEYCHAIN_NODE;
  986. break;
  987. default:
  988. break;
  989. }
  990. return CMD_SUCCESS;
  991. }
  992. DEFUNSH (VTYSH_ALL,
  993. vtysh_exit_all,
  994. vtysh_exit_all_cmd,
  995. "exit",
  996. "Exit current mode and down to previous mode\n")
  997. {
  998. return vtysh_exit (vty);
  999. }
  1000. ALIAS (vtysh_exit_all,
  1001. vtysh_quit_all_cmd,
  1002. "quit",
  1003. "Exit current mode and down to previous mode\n")
  1004. DEFUNSH (VTYSH_BGPD,
  1005. exit_address_family,
  1006. exit_address_family_cmd,
  1007. "exit-address-family",
  1008. "Exit from Address Family configuration mode\n")
  1009. {
  1010. if (vty->node == BGP_IPV4_NODE
  1011. || vty->node == BGP_IPV4M_NODE
  1012. || vty->node == BGP_VPNV4_NODE
  1013. || vty->node == BGP_IPV6_NODE
  1014. || vty->node == BGP_IPV6M_NODE)
  1015. vty->node = BGP_NODE;
  1016. return CMD_SUCCESS;
  1017. }
  1018. DEFUNSH (VTYSH_ZEBRA,
  1019. vtysh_exit_zebra,
  1020. vtysh_exit_zebra_cmd,
  1021. "exit",
  1022. "Exit current mode and down to previous mode\n")
  1023. {
  1024. return vtysh_exit (vty);
  1025. }
  1026. ALIAS (vtysh_exit_zebra,
  1027. vtysh_quit_zebra_cmd,
  1028. "quit",
  1029. "Exit current mode and down to previous mode\n")
  1030. DEFUNSH (VTYSH_RIPD,
  1031. vtysh_exit_ripd,
  1032. vtysh_exit_ripd_cmd,
  1033. "exit",
  1034. "Exit current mode and down to previous mode\n")
  1035. {
  1036. return vtysh_exit (vty);
  1037. }
  1038. ALIAS (vtysh_exit_ripd,
  1039. vtysh_quit_ripd_cmd,
  1040. "quit",
  1041. "Exit current mode and down to previous mode\n")
  1042. DEFUNSH (VTYSH_RIPNGD,
  1043. vtysh_exit_ripngd,
  1044. vtysh_exit_ripngd_cmd,
  1045. "exit",
  1046. "Exit current mode and down to previous mode\n")
  1047. {
  1048. return vtysh_exit (vty);
  1049. }
  1050. ALIAS (vtysh_exit_ripngd,
  1051. vtysh_quit_ripngd_cmd,
  1052. "quit",
  1053. "Exit current mode and down to previous mode\n")
  1054. DEFUNSH (VTYSH_RMAP,
  1055. vtysh_exit_rmap,
  1056. vtysh_exit_rmap_cmd,
  1057. "exit",
  1058. "Exit current mode and down to previous mode\n")
  1059. {
  1060. return vtysh_exit (vty);
  1061. }
  1062. ALIAS (vtysh_exit_rmap,
  1063. vtysh_quit_rmap_cmd,
  1064. "quit",
  1065. "Exit current mode and down to previous mode\n")
  1066. DEFUNSH (VTYSH_BGPD,
  1067. vtysh_exit_bgpd,
  1068. vtysh_exit_bgpd_cmd,
  1069. "exit",
  1070. "Exit current mode and down to previous mode\n")
  1071. {
  1072. return vtysh_exit (vty);
  1073. }
  1074. ALIAS (vtysh_exit_bgpd,
  1075. vtysh_quit_bgpd_cmd,
  1076. "quit",
  1077. "Exit current mode and down to previous mode\n")
  1078. DEFUNSH (VTYSH_OSPFD,
  1079. vtysh_exit_ospfd,
  1080. vtysh_exit_ospfd_cmd,
  1081. "exit",
  1082. "Exit current mode and down to previous mode\n")
  1083. {
  1084. return vtysh_exit (vty);
  1085. }
  1086. ALIAS (vtysh_exit_ospfd,
  1087. vtysh_quit_ospfd_cmd,
  1088. "quit",
  1089. "Exit current mode and down to previous mode\n")
  1090. DEFUNSH (VTYSH_OSPF6D,
  1091. vtysh_exit_ospf6d,
  1092. vtysh_exit_ospf6d_cmd,
  1093. "exit",
  1094. "Exit current mode and down to previous mode\n")
  1095. {
  1096. return vtysh_exit (vty);
  1097. }
  1098. ALIAS (vtysh_exit_ospf6d,
  1099. vtysh_quit_ospf6d_cmd,
  1100. "quit",
  1101. "Exit current mode and down to previous mode\n")
  1102. DEFUNSH (VTYSH_ISISD,
  1103. vtysh_exit_isisd,
  1104. vtysh_exit_isisd_cmd,
  1105. "exit",
  1106. "Exit current mode and down to previous mode\n")
  1107. {
  1108. return vtysh_exit (vty);
  1109. }
  1110. ALIAS (vtysh_exit_isisd,
  1111. vtysh_quit_isisd_cmd,
  1112. "quit",
  1113. "Exit current mode and down to previous mode\n")
  1114. DEFUNSH (VTYSH_ALL,
  1115. vtysh_exit_line_vty,
  1116. vtysh_exit_line_vty_cmd,
  1117. "exit",
  1118. "Exit current mode and down to previous mode\n")
  1119. {
  1120. return vtysh_exit (vty);
  1121. }
  1122. ALIAS (vtysh_exit_line_vty,
  1123. vtysh_quit_line_vty_cmd,
  1124. "quit",
  1125. "Exit current mode and down to previous mode\n")
  1126. DEFUNSH (VTYSH_INTERFACE,
  1127. vtysh_interface,
  1128. vtysh_interface_cmd,
  1129. "interface IFNAME",
  1130. "Select an interface to configure\n"
  1131. "Interface's name\n")
  1132. {
  1133. vty->node = INTERFACE_NODE;
  1134. return CMD_SUCCESS;
  1135. }
  1136. /* TODO Implement "no interface command in isisd. */
  1137. DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
  1138. vtysh_no_interface_cmd,
  1139. "no interface IFNAME",
  1140. NO_STR
  1141. "Delete a pseudo interface's configuration\n"
  1142. "Interface's name\n")
  1143. /* TODO Implement interface description commands in ripngd, ospf6d
  1144. * and isisd. */
  1145. DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
  1146. interface_desc_cmd,
  1147. "description .LINE",
  1148. "Interface specific description\n"
  1149. "Characters describing this interface\n")
  1150. DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
  1151. no_interface_desc_cmd,
  1152. "no description",
  1153. NO_STR
  1154. "Interface specific description\n")
  1155. DEFUNSH (VTYSH_INTERFACE,
  1156. vtysh_exit_interface,
  1157. vtysh_exit_interface_cmd,
  1158. "exit",
  1159. "Exit current mode and down to previous mode\n")
  1160. {
  1161. return vtysh_exit (vty);
  1162. }
  1163. ALIAS (vtysh_exit_interface,
  1164. vtysh_quit_interface_cmd,
  1165. "quit",
  1166. "Exit current mode and down to previous mode\n")
  1167. /* Memory */
  1168. DEFUN (vtysh_show_memory,
  1169. vtysh_show_memory_cmd,
  1170. "show memory",
  1171. SHOW_STR
  1172. "Memory statistics\n")
  1173. {
  1174. unsigned int i;
  1175. int ret = CMD_SUCCESS;
  1176. char line[] = "show memory\n";
  1177. for (i = 0; i < array_size(vtysh_client); i++)
  1178. if ( vtysh_client[i].fd >= 0 )
  1179. {
  1180. fprintf (stdout, "Memory statistics for %s:\n",
  1181. vtysh_client[i].name);
  1182. ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
  1183. fprintf (stdout,"\n");
  1184. }
  1185. return ret;
  1186. }
  1187. /* Logging commands. */
  1188. DEFUN (vtysh_show_logging,
  1189. vtysh_show_logging_cmd,
  1190. "show logging",
  1191. SHOW_STR
  1192. "Show current logging configuration\n")
  1193. {
  1194. unsigned int i;
  1195. int ret = CMD_SUCCESS;
  1196. char line[] = "show logging\n";
  1197. for (i = 0; i < array_size(vtysh_client); i++)
  1198. if ( vtysh_client[i].fd >= 0 )
  1199. {
  1200. fprintf (stdout,"Logging configuration for %s:\n",
  1201. vtysh_client[i].name);
  1202. ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
  1203. fprintf (stdout,"\n");
  1204. }
  1205. return ret;
  1206. }
  1207. DEFUNSH (VTYSH_ALL,
  1208. vtysh_log_stdout,
  1209. vtysh_log_stdout_cmd,
  1210. "log stdout",
  1211. "Logging control\n"
  1212. "Set stdout logging level\n")
  1213. {
  1214. return CMD_SUCCESS;
  1215. }
  1216. DEFUNSH (VTYSH_ALL,
  1217. vtysh_log_stdout_level,
  1218. vtysh_log_stdout_level_cmd,
  1219. "log stdout "LOG_LEVELS,
  1220. "Logging control\n"
  1221. "Set stdout logging level\n"
  1222. LOG_LEVEL_DESC)
  1223. {
  1224. return CMD_SUCCESS;
  1225. }
  1226. DEFUNSH (VTYSH_ALL,
  1227. no_vtysh_log_stdout,
  1228. no_vtysh_log_stdout_cmd,
  1229. "no log stdout [LEVEL]",
  1230. NO_STR
  1231. "Logging control\n"
  1232. "Cancel logging to stdout\n"
  1233. "Logging level\n")
  1234. {
  1235. return CMD_SUCCESS;
  1236. }
  1237. DEFUNSH (VTYSH_ALL,
  1238. vtysh_log_file,
  1239. vtysh_log_file_cmd,
  1240. "log file FILENAME",
  1241. "Logging control\n"
  1242. "Logging to file\n"
  1243. "Logging filename\n")
  1244. {
  1245. return CMD_SUCCESS;
  1246. }
  1247. DEFUNSH (VTYSH_ALL,
  1248. vtysh_log_file_level,
  1249. vtysh_log_file_level_cmd,
  1250. "log file FILENAME "LOG_LEVELS,
  1251. "Logging control\n"
  1252. "Logging to file\n"
  1253. "Logging filename\n"
  1254. LOG_LEVEL_DESC)
  1255. {
  1256. return CMD_SUCCESS;
  1257. }
  1258. DEFUNSH (VTYSH_ALL,
  1259. no_vtysh_log_file,
  1260. no_vtysh_log_file_cmd,
  1261. "no log file [FILENAME]",
  1262. NO_STR
  1263. "Logging control\n"
  1264. "Cancel logging to file\n"
  1265. "Logging file name\n")
  1266. {
  1267. return CMD_SUCCESS;
  1268. }
  1269. ALIAS_SH (VTYSH_ALL,
  1270. no_vtysh_log_file,
  1271. no_vtysh_log_file_level_cmd,
  1272. "no log file FILENAME LEVEL",
  1273. NO_STR
  1274. "Logging control\n"
  1275. "Cancel logging to file\n"
  1276. "Logging file name\n"
  1277. "Logging level\n")
  1278. DEFUNSH (VTYSH_ALL,
  1279. vtysh_log_monitor,
  1280. vtysh_log_monitor_cmd,
  1281. "log monitor",
  1282. "Logging control\n"
  1283. "Set terminal line (monitor) logging level\n")
  1284. {
  1285. return CMD_SUCCESS;
  1286. }
  1287. DEFUNSH (VTYSH_ALL,
  1288. vtysh_log_monitor_level,
  1289. vtysh_log_monitor_level_cmd,
  1290. "log monitor "LOG_LEVELS,
  1291. "Logging control\n"
  1292. "Set terminal line (monitor) logging level\n"
  1293. LOG_LEVEL_DESC)
  1294. {
  1295. return CMD_SUCCESS;
  1296. }
  1297. DEFUNSH (VTYSH_ALL,
  1298. no_vtysh_log_monitor,
  1299. no_vtysh_log_monitor_cmd,
  1300. "no log monitor [LEVEL]",
  1301. NO_STR
  1302. "Logging control\n"
  1303. "Disable terminal line (monitor) logging\n"
  1304. "Logging level\n")
  1305. {
  1306. return CMD_SUCCESS;
  1307. }
  1308. DEFUNSH (VTYSH_ALL,
  1309. vtysh_log_syslog,
  1310. vtysh_log_syslog_cmd,
  1311. "log syslog",
  1312. "Logging control\n"
  1313. "Set syslog logging level\n")
  1314. {
  1315. return CMD_SUCCESS;
  1316. }
  1317. DEFUNSH (VTYSH_ALL,
  1318. vtysh_log_syslog_level,
  1319. vtysh_log_syslog_level_cmd,
  1320. "log syslog "LOG_LEVELS,
  1321. "Logging control\n"
  1322. "Set syslog logging level\n"
  1323. LOG_LEVEL_DESC)
  1324. {
  1325. return CMD_SUCCESS;
  1326. }
  1327. DEFUNSH (VTYSH_ALL,
  1328. no_vtysh_log_syslog,
  1329. no_vtysh_log_syslog_cmd,
  1330. "no log syslog [LEVEL]",
  1331. NO_STR
  1332. "Logging control\n"
  1333. "Cancel logging to syslog\n"
  1334. "Logging level\n")
  1335. {
  1336. return CMD_SUCCESS;
  1337. }
  1338. DEFUNSH (VTYSH_ALL,
  1339. vtysh_log_facility,
  1340. vtysh_log_facility_cmd,
  1341. "log facility "LOG_FACILITIES,
  1342. "Logging control\n"
  1343. "Facility parameter for syslog messages\n"
  1344. LOG_FACILITY_DESC)
  1345. {
  1346. return CMD_SUCCESS;
  1347. }
  1348. DEFUNSH (VTYSH_ALL,
  1349. no_vtysh_log_facility,
  1350. no_vtysh_log_facility_cmd,
  1351. "no log facility [FACILITY]",
  1352. NO_STR
  1353. "Logging control\n"
  1354. "Reset syslog facility to default (daemon)\n"
  1355. "Syslog facility\n")
  1356. {
  1357. return CMD_SUCCESS;
  1358. }
  1359. DEFUNSH_DEPRECATED (VTYSH_ALL,
  1360. vtysh_log_trap,
  1361. vtysh_log_trap_cmd,
  1362. "log trap "LOG_LEVELS,
  1363. "Logging control\n"
  1364. "(Deprecated) Set logging level and default for all destinations\n"
  1365. LOG_LEVEL_DESC)
  1366. {
  1367. return CMD_SUCCESS;
  1368. }
  1369. DEFUNSH_DEPRECATED (VTYSH_ALL,
  1370. no_vtysh_log_trap,
  1371. no_vtysh_log_trap_cmd,
  1372. "no log trap [LEVEL]",
  1373. NO_STR
  1374. "Logging control\n"
  1375. "Permit all logging information\n"
  1376. "Logging level\n")
  1377. {
  1378. return CMD_SUCCESS;
  1379. }
  1380. DEFUNSH (VTYSH_ALL,
  1381. vtysh_log_record_priority,
  1382. vtysh_log_record_priority_cmd,
  1383. "log record-priority",
  1384. "Logging control\n"
  1385. "Log the priority of the message within the message\n")
  1386. {
  1387. return CMD_SUCCESS;
  1388. }
  1389. DEFUNSH (VTYSH_ALL,
  1390. no_vtysh_log_record_priority,
  1391. no_vtysh_log_record_priority_cmd,
  1392. "no log record-priority",
  1393. NO_STR
  1394. "Logging control\n"
  1395. "Do not log the priority of the message within the message\n")
  1396. {
  1397. return CMD_SUCCESS;
  1398. }
  1399. DEFUNSH (VTYSH_ALL,
  1400. vtysh_log_timestamp_precision,
  1401. vtysh_log_timestamp_precision_cmd,
  1402. "log timestamp precision <0-6>",
  1403. "Logging control\n"
  1404. "Timestamp configuration\n"
  1405. "Set the timestamp precision\n"
  1406. "Number of subsecond digits\n")
  1407. {
  1408. return CMD_SUCCESS;
  1409. }
  1410. DEFUNSH (VTYSH_ALL,
  1411. no_vtysh_log_timestamp_precision,
  1412. no_vtysh_log_timestamp_precision_cmd,
  1413. "no log timestamp precision",
  1414. NO_STR
  1415. "Logging control\n"
  1416. "Timestamp configuration\n"
  1417. "Reset the timestamp precision to the default value of 0\n")
  1418. {
  1419. return CMD_SUCCESS;
  1420. }
  1421. DEFUNSH (VTYSH_ALL,
  1422. vtysh_service_password_encrypt,
  1423. vtysh_service_password_encrypt_cmd,
  1424. "service password-encryption",
  1425. "Set up miscellaneous service\n"
  1426. "Enable encrypted passwords\n")
  1427. {
  1428. return CMD_SUCCESS;
  1429. }
  1430. DEFUNSH (VTYSH_ALL,
  1431. no_vtysh_service_password_encrypt,
  1432. no_vtysh_service_password_encrypt_cmd,
  1433. "no service password-encryption",
  1434. NO_STR
  1435. "Set up miscellaneous service\n"
  1436. "Enable encrypted passwords\n")
  1437. {
  1438. return CMD_SUCCESS;
  1439. }
  1440. DEFUNSH (VTYSH_ALL,
  1441. vtysh_config_password,
  1442. vtysh_password_cmd,
  1443. "password (8|) WORD",
  1444. "Assign the terminal connection password\n"
  1445. "Specifies a HIDDEN password will follow\n"
  1446. "dummy string \n"
  1447. "The HIDDEN line password string\n")
  1448. {
  1449. return CMD_SUCCESS;
  1450. }
  1451. DEFUNSH (VTYSH_ALL,
  1452. vtysh_password_text,
  1453. vtysh_password_text_cmd,
  1454. "password LINE",
  1455. "Assign the terminal connection password\n"
  1456. "The UNENCRYPTED (cleartext) line password\n")
  1457. {
  1458. return CMD_SUCCESS;
  1459. }
  1460. DEFUNSH (VTYSH_ALL,
  1461. vtysh_config_enable_password,
  1462. vtysh_enable_password_cmd,
  1463. "enable password (8|) WORD",
  1464. "Modify enable password parameters\n"
  1465. "Assign the privileged level password\n"
  1466. "Specifies a HIDDEN password will follow\n"
  1467. "dummy string \n"
  1468. "The HIDDEN 'enable' password string\n")
  1469. {
  1470. return CMD_SUCCESS;
  1471. }
  1472. DEFUNSH (VTYSH_ALL,
  1473. vtysh_enable_password_text,
  1474. vtysh_enable_password_text_cmd,
  1475. "enable password LINE",
  1476. "Modify enable password parameters\n"
  1477. "Assign the privileged level password\n"
  1478. "The UNENCRYPTED (cleartext) 'enable' password\n")
  1479. {
  1480. return CMD_SUCCESS;
  1481. }
  1482. DEFUNSH (VTYSH_ALL,
  1483. no_vtysh_config_enable_password,
  1484. no_vtysh_enable_password_cmd,
  1485. "no enable password",
  1486. NO_STR
  1487. "Modify enable password parameters\n"
  1488. "Assign the privileged level password\n")
  1489. {
  1490. return CMD_SUCCESS;
  1491. }
  1492. DEFUN (vtysh_write_terminal,
  1493. vtysh_write_terminal_cmd,
  1494. "write terminal",
  1495. "Write running configuration to memory, network, or terminal\n"
  1496. "Write to terminal\n")
  1497. {
  1498. u_int i;
  1499. int ret;
  1500. char line[] = "write terminal\n";
  1501. FILE *fp = NULL;
  1502. if (vtysh_pager_name)
  1503. {
  1504. fp = popen (vtysh_pager_name, "w");
  1505. if (fp == NULL)
  1506. {
  1507. perror ("popen");
  1508. exit (1);
  1509. }
  1510. }
  1511. else
  1512. fp = stdout;
  1513. vty_out (vty, "Building configuration...%s", VTY_NEWLINE);
  1514. vty_out (vty, "%sCurrent configuration:%s", VTY_NEWLINE,
  1515. VTY_NEWLINE);
  1516. vty_out (vty, "!%s", VTY_NEWLINE);
  1517. for (i = 0; i < array_size(vtysh_client); i++)
  1518. ret = vtysh_client_config (&vtysh_client[i], line);
  1519. /* Integrate vtysh specific configuration. */
  1520. vtysh_config_write ();
  1521. vtysh_config_dump (fp);
  1522. if (vtysh_pager_name && fp)
  1523. {
  1524. fflush (fp);
  1525. if (pclose (fp) == -1)
  1526. {
  1527. perror ("pclose");
  1528. exit (1);
  1529. }
  1530. fp = NULL;
  1531. }
  1532. vty_out (vty, "end%s", VTY_NEWLINE);
  1533. return CMD_SUCCESS;
  1534. }
  1535. DEFUN (vtysh_integrated_config,
  1536. vtysh_integrated_config_cmd,
  1537. "service integrated-vtysh-config",
  1538. "Set up miscellaneous service\n"
  1539. "Write configuration into integrated file\n")
  1540. {
  1541. vtysh_writeconfig_integrated = 1;
  1542. return CMD_SUCCESS;
  1543. }
  1544. DEFUN (no_vtysh_integrated_config,
  1545. no_vtysh_integrated_config_cmd,
  1546. "no service integrated-vtysh-config",
  1547. NO_STR
  1548. "Set up miscellaneous service\n"
  1549. "Write configuration into integrated file\n")
  1550. {
  1551. vtysh_writeconfig_integrated = 0;
  1552. return CMD_SUCCESS;
  1553. }
  1554. static int
  1555. write_config_integrated(void)
  1556. {
  1557. u_int i;
  1558. int ret;
  1559. char line[] = "write terminal\n";
  1560. FILE *fp;
  1561. char *integrate_sav = NULL;
  1562. integrate_sav = malloc (strlen (integrate_default) +
  1563. strlen (CONF_BACKUP_EXT) + 1);
  1564. strcpy (integrate_sav, integrate_default);
  1565. strcat (integrate_sav, CONF_BACKUP_EXT);
  1566. fprintf (stdout,"Building Configuration...\n");
  1567. /* Move current configuration file to backup config file. */
  1568. unlink (integrate_sav);
  1569. rename (integrate_default, integrate_sav);
  1570. free (integrate_sav);
  1571. fp = fopen (integrate_default, "w");
  1572. if (fp == NULL)
  1573. {
  1574. fprintf (stdout,"%% Can't open configuration file %s.\n",
  1575. integrate_default);
  1576. return CMD_SUCCESS;
  1577. }
  1578. for (i = 0; i < array_size(vtysh_client); i++)
  1579. ret = vtysh_client_config (&vtysh_client[i], line);
  1580. vtysh_config_dump (fp);
  1581. fclose (fp);
  1582. if (chmod (integrate_default, CONFIGFILE_MASK) != 0)
  1583. {
  1584. fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n",
  1585. integrate_default, safe_strerror(errno), errno);
  1586. return CMD_WARNING;
  1587. }
  1588. fprintf(stdout,"Integrated configuration saved to %s\n",integrate_default);
  1589. fprintf (stdout,"[OK]\n");
  1590. return CMD_SUCCESS;
  1591. }
  1592. DEFUN (vtysh_write_memory,
  1593. vtysh_write_memory_cmd,
  1594. "write memory",
  1595. "Write running configuration to memory, network, or terminal\n"
  1596. "Write configuration to the file (same as write file)\n")
  1597. {
  1598. int ret = CMD_SUCCESS;
  1599. char line[] = "write memory\n";
  1600. u_int i;
  1601. /* If integrated Quagga.conf explicitely set. */
  1602. if (vtysh_writeconfig_integrated)
  1603. return write_config_integrated();
  1604. fprintf (stdout,"Building Configuration...\n");
  1605. for (i = 0; i < array_size(vtysh_client); i++)
  1606. ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
  1607. fprintf (stdout,"[OK]\n");
  1608. return ret;
  1609. }
  1610. ALIAS (vtysh_write_memory,
  1611. vtysh_copy_runningconfig_startupconfig_cmd,
  1612. "copy running-config startup-config",
  1613. "Copy from one file to another\n"
  1614. "Copy from current system configuration\n"
  1615. "Copy to startup configuration\n")
  1616. ALIAS (vtysh_write_memory,
  1617. vtysh_write_file_cmd,
  1618. "write file",
  1619. "Write running configuration to memory, network, or terminal\n"
  1620. "Write configuration to the file (same as write memory)\n")
  1621. ALIAS (vtysh_write_memory,
  1622. vtysh_write_cmd,
  1623. "write",
  1624. "Write running configuration to memory, network, or terminal\n")
  1625. ALIAS (vtysh_write_terminal,
  1626. vtysh_show_running_config_cmd,
  1627. "show running-config",
  1628. SHOW_STR
  1629. "Current operating configuration\n")
  1630. DEFUN (vtysh_terminal_length,
  1631. vtysh_terminal_length_cmd,
  1632. "terminal length <0-512>",
  1633. "Set terminal line parameters\n"
  1634. "Set number of lines on a screen\n"
  1635. "Number of lines on screen (0 for no pausing)\n")
  1636. {
  1637. int lines;
  1638. char *endptr = NULL;
  1639. char default_pager[10];
  1640. lines = strtol (argv[0], &endptr, 10);
  1641. if (lines < 0 || lines > 512 || *endptr != '\0')
  1642. {
  1643. vty_out (vty, "length is malformed%s", VTY_NEWLINE);
  1644. return CMD_WARNING;
  1645. }
  1646. if (vtysh_pager_name)
  1647. {
  1648. free (vtysh_pager_name);
  1649. vtysh_pager_name = NULL;
  1650. }
  1651. if (lines != 0)
  1652. {
  1653. snprintf(default_pager, 10, "more -%i", lines);
  1654. vtysh_pager_name = strdup (default_pager);
  1655. }
  1656. return CMD_SUCCESS;
  1657. }
  1658. DEFUN (vtysh_terminal_no_length,
  1659. vtysh_terminal_no_length_cmd,
  1660. "terminal no length",
  1661. "Set terminal line parameters\n"
  1662. NO_STR
  1663. "Set number of lines on a screen\n")
  1664. {
  1665. if (vtysh_pager_name)
  1666. {
  1667. free (vtysh_pager_name);
  1668. vtysh_pager_name = NULL;
  1669. }
  1670. vtysh_pager_init();
  1671. return CMD_SUCCESS;
  1672. }
  1673. DEFUN (vtysh_show_daemons,
  1674. vtysh_show_daemons_cmd,
  1675. "show daemons",
  1676. SHOW_STR
  1677. "Show list of running daemons\n")
  1678. {
  1679. u_int i;
  1680. for (i = 0; i < array_size(vtysh_client); i++)
  1681. if ( vtysh_client[i].fd >= 0 )
  1682. vty_out(vty, " %s", vtysh_client[i].name);
  1683. vty_out(vty, "%s", VTY_NEWLINE);
  1684. return CMD_SUCCESS;
  1685. }
  1686. /* Execute command in child process. */
  1687. static int
  1688. execute_command (const char *command, int argc, const char *arg1,
  1689. const char *arg2)
  1690. {
  1691. int ret;
  1692. pid_t pid;
  1693. int status;
  1694. /* Call fork(). */
  1695. pid = fork ();
  1696. if (pid < 0)
  1697. {
  1698. /* Failure of fork(). */
  1699. fprintf (stderr, "Can't fork: %s\n", safe_strerror (errno));
  1700. exit (1);
  1701. }
  1702. else if (pid == 0)
  1703. {
  1704. /* This is child process. */
  1705. switch (argc)
  1706. {
  1707. case 0:
  1708. ret = execlp (command, command, (const char *)NULL);
  1709. break;
  1710. case 1:
  1711. ret = execlp (command, command, arg1, (const char *)NULL);
  1712. break;
  1713. case 2:
  1714. ret = execlp (command, command, arg1, arg2, (const char *)NULL);
  1715. break;
  1716. }
  1717. /* When execlp suceed, this part is not executed. */
  1718. fprintf (stderr, "Can't execute %s: %s\n", command, safe_strerror (errno));
  1719. exit (1);
  1720. }
  1721. else
  1722. {
  1723. /* This is parent. */
  1724. execute_flag = 1;
  1725. ret = wait4 (pid, &status, 0, NULL);
  1726. execute_flag = 0;
  1727. }
  1728. return 0;
  1729. }
  1730. DEFUN (vtysh_ping,
  1731. vtysh_ping_cmd,
  1732. "ping WORD",
  1733. "Send echo messages\n"
  1734. "Ping destination address or hostname\n")
  1735. {
  1736. execute_command ("ping", 1, argv[0], NULL);
  1737. return CMD_SUCCESS;
  1738. }
  1739. ALIAS (vtysh_ping,
  1740. vtysh_ping_ip_cmd,
  1741. "ping ip WORD",
  1742. "Send echo messages\n"
  1743. "IP echo\n"
  1744. "Ping destination address or hostname\n")
  1745. DEFUN (vtysh_traceroute,
  1746. vtysh_traceroute_cmd,
  1747. "traceroute WORD",
  1748. "Trace route to destination\n"
  1749. "Trace route to destination address or hostname\n")
  1750. {
  1751. execute_command ("traceroute", 1, argv[0], NULL);
  1752. return CMD_SUCCESS;
  1753. }
  1754. ALIAS (vtysh_traceroute,
  1755. vtysh_traceroute_ip_cmd,
  1756. "traceroute ip WORD",
  1757. "Trace route to destination\n"
  1758. "IP trace\n"
  1759. "Trace route to destination address or hostname\n")
  1760. #ifdef HAVE_IPV6
  1761. DEFUN (vtysh_ping6,
  1762. vtysh_ping6_cmd,
  1763. "ping ipv6 WORD",
  1764. "Send echo messages\n"
  1765. "IPv6 echo\n"
  1766. "Ping destination address or hostname\n")
  1767. {
  1768. execute_command ("ping6", 1, argv[0], NULL);
  1769. return CMD_SUCCESS;
  1770. }
  1771. DEFUN (vtysh_traceroute6,
  1772. vtysh_traceroute6_cmd,
  1773. "traceroute ipv6 WORD",
  1774. "Trace route to destination\n"
  1775. "IPv6 trace\n"
  1776. "Trace route to destination address or hostname\n")
  1777. {
  1778. execute_command ("traceroute6", 1, argv[0], NULL);
  1779. return CMD_SUCCESS;
  1780. }
  1781. #endif
  1782. DEFUN (vtysh_telnet,
  1783. vtysh_telnet_cmd,
  1784. "telnet WORD",
  1785. "Open a telnet connection\n"
  1786. "IP address or hostname of a remote system\n")
  1787. {
  1788. execute_command ("telnet", 1, argv[0], NULL);
  1789. return CMD_SUCCESS;
  1790. }
  1791. DEFUN (vtysh_telnet_port,
  1792. vtysh_telnet_port_cmd,
  1793. "telnet WORD PORT",
  1794. "Open a telnet connection\n"
  1795. "IP address or hostname of a remote system\n"
  1796. "TCP Port number\n")
  1797. {
  1798. execute_command ("telnet", 2, argv[0], argv[1]);
  1799. return CMD_SUCCESS;
  1800. }
  1801. DEFUN (vtysh_ssh,
  1802. vtysh_ssh_cmd,
  1803. "ssh WORD",
  1804. "Open an ssh connection\n"
  1805. "[user@]host\n")
  1806. {
  1807. execute_command ("ssh", 1, argv[0], NULL);
  1808. return CMD_SUCCESS;
  1809. }
  1810. DEFUN (vtysh_start_shell,
  1811. vtysh_start_shell_cmd,
  1812. "start-shell",
  1813. "Start UNIX shell\n")
  1814. {
  1815. execute_command ("sh", 0, NULL, NULL);
  1816. return CMD_SUCCESS;
  1817. }
  1818. DEFUN (vtysh_start_bash,
  1819. vtysh_start_bash_cmd,
  1820. "start-shell bash",
  1821. "Start UNIX shell\n"
  1822. "Start bash\n")
  1823. {
  1824. execute_command ("bash", 0, NULL, NULL);
  1825. return CMD_SUCCESS;
  1826. }
  1827. DEFUN (vtysh_start_zsh,
  1828. vtysh_start_zsh_cmd,
  1829. "start-shell zsh",
  1830. "Start UNIX shell\n"
  1831. "Start Z shell\n")
  1832. {
  1833. execute_command ("zsh", 0, NULL, NULL);
  1834. return CMD_SUCCESS;
  1835. }
  1836. static void
  1837. vtysh_install_default (enum node_type node)
  1838. {
  1839. install_element (node, &config_list_cmd);
  1840. }
  1841. /* Making connection to protocol daemon. */
  1842. static int
  1843. vtysh_connect (struct vtysh_client *vclient)
  1844. {
  1845. int ret;
  1846. int sock, len;
  1847. struct sockaddr_un addr;
  1848. struct stat s_stat;
  1849. /* Stat socket to see if we have permission to access it. */
  1850. ret = stat (vclient->path, &s_stat);
  1851. if (ret < 0 && errno != ENOENT)
  1852. {
  1853. fprintf (stderr, "vtysh_connect(%s): stat = %s\n",
  1854. vclient->path, safe_strerror(errno));
  1855. exit(1);
  1856. }
  1857. if (ret >= 0)
  1858. {
  1859. if (! S_ISSOCK(s_stat.st_mode))
  1860. {
  1861. fprintf (stderr, "vtysh_connect(%s): Not a socket\n",
  1862. vclient->path);
  1863. exit (1);
  1864. }
  1865. }
  1866. sock = socket (AF_UNIX, SOCK_STREAM, 0);
  1867. if (sock < 0)
  1868. {
  1869. #ifdef DEBUG
  1870. fprintf(stderr, "vtysh_connect(%s): socket = %s\n", vclient->path,
  1871. safe_strerror(errno));
  1872. #endif /* DEBUG */
  1873. return -1;
  1874. }
  1875. memset (&addr, 0, sizeof (struct sockaddr_un));
  1876. addr.sun_family = AF_UNIX;
  1877. strncpy (addr.sun_path, vclient->path, strlen (vclient->path));
  1878. #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
  1879. len = addr.sun_len = SUN_LEN(&addr);
  1880. #else
  1881. len = sizeof (addr.sun_family) + strlen (addr.sun_path);
  1882. #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
  1883. ret = connect (sock, (struct sockaddr *) &addr, len);
  1884. if (ret < 0)
  1885. {
  1886. #ifdef DEBUG
  1887. fprintf(stderr, "vtysh_connect(%s): connect = %s\n", vclient->path,
  1888. safe_strerror(errno));
  1889. #endif /* DEBUG */
  1890. close (sock);
  1891. return -1;
  1892. }
  1893. vclient->fd = sock;
  1894. return 0;
  1895. }
  1896. int
  1897. vtysh_connect_all(const char *daemon_name)
  1898. {
  1899. u_int i;
  1900. int rc = 0;
  1901. int matches = 0;
  1902. for (i = 0; i < array_size(vtysh_client); i++)
  1903. {
  1904. if (!daemon_name || !strcmp(daemon_name, vtysh_client[i].name))
  1905. {
  1906. matches++;
  1907. if (vtysh_connect(&vtysh_client[i]) == 0)
  1908. rc++;
  1909. /* We need direct access to ripd in vtysh_exit_ripd_only. */
  1910. if (vtysh_client[i].flag == VTYSH_RIPD)
  1911. ripd_client = &vtysh_client[i];
  1912. }
  1913. }
  1914. if (!matches)
  1915. fprintf(stderr, "Error: no daemons match name %s!\n", daemon_name);
  1916. return rc;
  1917. }
  1918. /* To disable readline's filename completion. */
  1919. static char *
  1920. vtysh_completion_entry_function (const char *ignore, int invoking_key)
  1921. {
  1922. return NULL;
  1923. }
  1924. void
  1925. vtysh_readline_init (void)
  1926. {
  1927. /* readline related settings. */
  1928. rl_bind_key ('?', (rl_command_func_t *) vtysh_rl_describe);
  1929. rl_completion_entry_function = vtysh_completion_entry_function;
  1930. rl_attempted_completion_function = (rl_completion_func_t *)new_completion;
  1931. }
  1932. char *
  1933. vtysh_prompt (void)
  1934. {
  1935. static struct utsname names;
  1936. static char buf[100];
  1937. const char*hostname;
  1938. extern struct host host;
  1939. hostname = host.name;
  1940. if (!hostname)
  1941. {
  1942. if (!names.nodename[0])
  1943. uname (&names);
  1944. hostname = names.nodename;
  1945. }
  1946. snprintf (buf, sizeof buf, cmd_prompt (vty->node), hostname);
  1947. return buf;
  1948. }
  1949. void
  1950. vtysh_init_vty (void)
  1951. {
  1952. /* Make vty structure. */
  1953. vty = vty_new ();
  1954. vty->type = VTY_SHELL;
  1955. vty->node = VIEW_NODE;
  1956. /* Initialize commands. */
  1957. cmd_init (0);
  1958. /* Install nodes. */
  1959. install_node (&bgp_node, NULL);
  1960. install_node (&rip_node, NULL);
  1961. install_node (&interface_node, NULL);
  1962. install_node (&rmap_node, NULL);
  1963. install_node (&zebra_node, NULL);
  1964. install_node (&bgp_vpnv4_node, NULL);
  1965. install_node (&bgp_ipv4_node, NULL);
  1966. install_node (&bgp_ipv4m_node, NULL);
  1967. /* #ifdef HAVE_IPV6 */
  1968. install_node (&bgp_ipv6_node, NULL);
  1969. install_node (&bgp_ipv6m_node, NULL);
  1970. /* #endif */
  1971. install_node (&ospf_node, NULL);
  1972. /* #ifdef HAVE_IPV6 */
  1973. install_node (&ripng_node, NULL);
  1974. install_node (&ospf6_node, NULL);
  1975. /* #endif */
  1976. install_node (&babel_node, NULL);
  1977. install_node (&keychain_node, NULL);
  1978. install_node (&keychain_key_node, NULL);
  1979. install_node (&isis_node, NULL);
  1980. install_node (&vty_node, NULL);
  1981. vtysh_install_default (VIEW_NODE);
  1982. vtysh_install_default (ENABLE_NODE);
  1983. vtysh_install_default (CONFIG_NODE);
  1984. vtysh_install_default (BGP_NODE);
  1985. vtysh_install_default (RIP_NODE);
  1986. vtysh_install_default (INTERFACE_NODE);
  1987. vtysh_install_default (RMAP_NODE);
  1988. vtysh_install_default (ZEBRA_NODE);
  1989. vtysh_install_default (BGP_VPNV4_NODE);
  1990. vtysh_install_default (BGP_IPV4_NODE);
  1991. vtysh_install_default (BGP_IPV4M_NODE);
  1992. vtysh_install_default (BGP_IPV6_NODE);
  1993. vtysh_install_default (BGP_IPV6M_NODE);
  1994. vtysh_install_default (OSPF_NODE);
  1995. vtysh_install_default (RIPNG_NODE);
  1996. vtysh_install_default (OSPF6_NODE);
  1997. vtysh_install_default (BABEL_NODE);
  1998. vtysh_install_default (ISIS_NODE);
  1999. vtysh_install_default (KEYCHAIN_NODE);
  2000. vtysh_install_default (KEYCHAIN_KEY_NODE);
  2001. vtysh_install_default (VTY_NODE);
  2002. install_element (VIEW_NODE, &vtysh_enable_cmd);
  2003. install_element (ENABLE_NODE, &vtysh_config_terminal_cmd);
  2004. install_element (ENABLE_NODE, &vtysh_disable_cmd);
  2005. /* "exit" command. */
  2006. install_element (VIEW_NODE, &vtysh_exit_all_cmd);
  2007. install_element (VIEW_NODE, &vtysh_quit_all_cmd);
  2008. install_element (CONFIG_NODE, &vtysh_exit_all_cmd);
  2009. /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */
  2010. install_element (ENABLE_NODE, &vtysh_exit_all_cmd);
  2011. install_element (ENABLE_NODE, &vtysh_quit_all_cmd);
  2012. install_element (RIP_NODE, &vtysh_exit_ripd_cmd);
  2013. install_element (RIP_NODE, &vtysh_quit_ripd_cmd);
  2014. install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd);
  2015. install_element (RIPNG_NODE, &vtysh_quit_ripngd_cmd);
  2016. install_element (OSPF_NODE, &vtysh_exit_ospfd_cmd);
  2017. install_element (OSPF_NODE, &vtysh_quit_ospfd_cmd);
  2018. install_element (OSPF6_NODE, &vtysh_exit_ospf6d_cmd);
  2019. install_element (OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
  2020. install_element (BGP_NODE, &vtysh_exit_bgpd_cmd);
  2021. install_element (BGP_NODE, &vtysh_quit_bgpd_cmd);
  2022. install_element (BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
  2023. install_element (BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
  2024. install_element (BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
  2025. install_element (BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
  2026. install_element (BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
  2027. install_element (BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd);
  2028. install_element (BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd);
  2029. install_element (BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd);
  2030. install_element (BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd);
  2031. install_element (BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd);
  2032. install_element (ISIS_NODE, &vtysh_exit_isisd_cmd);
  2033. install_element (ISIS_NODE, &vtysh_quit_isisd_cmd);
  2034. install_element (KEYCHAIN_NODE, &vtysh_exit_ripd_cmd);
  2035. install_element (KEYCHAIN_NODE, &vtysh_quit_ripd_cmd);
  2036. install_element (KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd);
  2037. install_element (KEYCHAIN_KEY_NODE, &vtysh_quit_ripd_cmd);
  2038. install_element (RMAP_NODE, &vtysh_exit_rmap_cmd);
  2039. install_element (RMAP_NODE, &vtysh_quit_rmap_cmd);
  2040. install_element (VTY_NODE, &vtysh_exit_line_vty_cmd);
  2041. install_element (VTY_NODE, &vtysh_quit_line_vty_cmd);
  2042. /* "end" command. */
  2043. install_element (CONFIG_NODE, &vtysh_end_all_cmd);
  2044. install_element (ENABLE_NODE, &vtysh_end_all_cmd);
  2045. install_element (RIP_NODE, &vtysh_end_all_cmd);
  2046. install_element (RIPNG_NODE, &vtysh_end_all_cmd);
  2047. install_element (OSPF_NODE, &vtysh_end_all_cmd);
  2048. install_element (OSPF6_NODE, &vtysh_end_all_cmd);
  2049. install_element (BABEL_NODE, &vtysh_end_all_cmd);
  2050. install_element (BGP_NODE, &vtysh_end_all_cmd);
  2051. install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);
  2052. install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);
  2053. install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd);
  2054. install_element (BGP_IPV6_NODE, &vtysh_end_all_cmd);
  2055. install_element (BGP_IPV6M_NODE, &vtysh_end_all_cmd);
  2056. install_element (ISIS_NODE, &vtysh_end_all_cmd);
  2057. install_element (KEYCHAIN_NODE, &vtysh_end_all_cmd);
  2058. install_element (KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
  2059. install_element (RMAP_NODE, &vtysh_end_all_cmd);
  2060. install_element (VTY_NODE, &vtysh_end_all_cmd);
  2061. install_element (INTERFACE_NODE, &interface_desc_cmd);
  2062. install_element (INTERFACE_NODE, &no_interface_desc_cmd);
  2063. install_element (INTERFACE_NODE, &vtysh_end_all_cmd);
  2064. install_element (INTERFACE_NODE, &vtysh_exit_interface_cmd);
  2065. install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
  2066. install_element (CONFIG_NODE, &router_rip_cmd);
  2067. #ifdef HAVE_IPV6
  2068. install_element (CONFIG_NODE, &router_ripng_cmd);
  2069. #endif
  2070. install_element (CONFIG_NODE, &router_ospf_cmd);
  2071. #ifdef HAVE_IPV6
  2072. install_element (CONFIG_NODE, &router_ospf6_cmd);
  2073. #endif
  2074. install_element (CONFIG_NODE, &router_babel_cmd);
  2075. install_element (CONFIG_NODE, &router_isis_cmd);
  2076. install_element (CONFIG_NODE, &router_bgp_cmd);
  2077. install_element (CONFIG_NODE, &router_bgp_view_cmd);
  2078. install_element (BGP_NODE, &address_family_vpnv4_cmd);
  2079. install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd);
  2080. install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);
  2081. install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);
  2082. #ifdef HAVE_IPV6
  2083. install_element (BGP_NODE, &address_family_ipv6_cmd);
  2084. install_element (BGP_NODE, &address_family_ipv6_unicast_cmd);
  2085. #endif
  2086. install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
  2087. install_element (BGP_IPV4_NODE, &exit_address_family_cmd);
  2088. install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);
  2089. install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
  2090. install_element (BGP_IPV6M_NODE, &exit_address_family_cmd);
  2091. install_element (CONFIG_NODE, &key_chain_cmd);
  2092. install_element (CONFIG_NODE, &route_map_cmd);
  2093. install_element (CONFIG_NODE, &vtysh_line_vty_cmd);
  2094. install_element (KEYCHAIN_NODE, &key_cmd);
  2095. install_element (KEYCHAIN_NODE, &key_chain_cmd);
  2096. install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
  2097. install_element (CONFIG_NODE, &vtysh_interface_cmd);
  2098. install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
  2099. install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
  2100. install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
  2101. install_element (ENABLE_NODE, &vtysh_write_file_cmd);
  2102. install_element (ENABLE_NODE, &vtysh_write_cmd);
  2103. /* "write terminal" command. */
  2104. install_element (ENABLE_NODE, &vtysh_write_terminal_cmd);
  2105. install_element (CONFIG_NODE, &vtysh_integrated_config_cmd);
  2106. install_element (CONFIG_NODE, &no_vtysh_integrated_config_cmd);
  2107. /* "write memory" command. */
  2108. install_element (ENABLE_NODE, &vtysh_write_memory_cmd);
  2109. install_element (VIEW_NODE, &vtysh_terminal_length_cmd);
  2110. install_element (ENABLE_NODE, &vtysh_terminal_length_cmd);
  2111. install_element (VIEW_NODE, &vtysh_terminal_no_length_cmd);
  2112. install_element (ENABLE_NODE, &vtysh_terminal_no_length_cmd);
  2113. install_element (VIEW_NODE, &vtysh_show_daemons_cmd);
  2114. install_element (ENABLE_NODE, &vtysh_show_daemons_cmd);
  2115. install_element (VIEW_NODE, &vtysh_ping_cmd);
  2116. install_element (VIEW_NODE, &vtysh_ping_ip_cmd);
  2117. install_element (VIEW_NODE, &vtysh_traceroute_cmd);
  2118. install_element (VIEW_NODE, &vtysh_traceroute_ip_cmd);
  2119. #ifdef HAVE_IPV6
  2120. install_element (VIEW_NODE, &vtysh_ping6_cmd);
  2121. install_element (VIEW_NODE, &vtysh_traceroute6_cmd);
  2122. #endif
  2123. install_element (VIEW_NODE, &vtysh_telnet_cmd);
  2124. install_element (VIEW_NODE, &vtysh_telnet_port_cmd);
  2125. install_element (VIEW_NODE, &vtysh_ssh_cmd);
  2126. install_element (ENABLE_NODE, &vtysh_ping_cmd);
  2127. install_element (ENABLE_NODE, &vtysh_ping_ip_cmd);
  2128. install_element (ENABLE_NODE, &vtysh_traceroute_cmd);
  2129. install_element (ENABLE_NODE, &vtysh_traceroute_ip_cmd);
  2130. #ifdef HAVE_IPV6
  2131. install_element (ENABLE_NODE, &vtysh_ping6_cmd);
  2132. install_element (ENABLE_NODE, &vtysh_traceroute6_cmd);
  2133. #endif
  2134. install_element (ENABLE_NODE, &vtysh_telnet_cmd);
  2135. install_element (ENABLE_NODE, &vtysh_telnet_port_cmd);
  2136. install_element (ENABLE_NODE, &vtysh_ssh_cmd);
  2137. install_element (ENABLE_NODE, &vtysh_start_shell_cmd);
  2138. install_element (ENABLE_NODE, &vtysh_start_bash_cmd);
  2139. install_element (ENABLE_NODE, &vtysh_start_zsh_cmd);
  2140. install_element (VIEW_NODE, &vtysh_show_memory_cmd);
  2141. install_element (ENABLE_NODE, &vtysh_show_memory_cmd);
  2142. /* Logging */
  2143. install_element (ENABLE_NODE, &vtysh_show_logging_cmd);
  2144. install_element (VIEW_NODE, &vtysh_show_logging_cmd);
  2145. install_element (CONFIG_NODE, &vtysh_log_stdout_cmd);
  2146. install_element (CONFIG_NODE, &vtysh_log_stdout_level_cmd);
  2147. install_element (CONFIG_NODE, &no_vtysh_log_stdout_cmd);
  2148. install_element (CONFIG_NODE, &vtysh_log_file_cmd);
  2149. install_element (CONFIG_NODE, &vtysh_log_file_level_cmd);
  2150. install_element (CONFIG_NODE, &no_vtysh_log_file_cmd);
  2151. install_element (CONFIG_NODE, &no_vtysh_log_file_level_cmd);
  2152. install_element (CONFIG_NODE, &vtysh_log_monitor_cmd);
  2153. install_element (CONFIG_NODE, &vtysh_log_monitor_level_cmd);
  2154. install_element (CONFIG_NODE, &no_vtysh_log_monitor_cmd);
  2155. install_element (CONFIG_NODE, &vtysh_log_syslog_cmd);
  2156. install_element (CONFIG_NODE, &vtysh_log_syslog_level_cmd);
  2157. install_element (CONFIG_NODE, &no_vtysh_log_syslog_cmd);
  2158. install_element (CONFIG_NODE, &vtysh_log_trap_cmd);
  2159. install_element (CONFIG_NODE, &no_vtysh_log_trap_cmd);
  2160. install_element (CONFIG_NODE, &vtysh_log_facility_cmd);
  2161. install_element (CONFIG_NODE, &no_vtysh_log_facility_cmd);
  2162. install_element (CONFIG_NODE, &vtysh_log_record_priority_cmd);
  2163. install_element (CONFIG_NODE, &no_vtysh_log_record_priority_cmd);
  2164. install_element (CONFIG_NODE, &vtysh_log_timestamp_precision_cmd);
  2165. install_element (CONFIG_NODE, &no_vtysh_log_timestamp_precision_cmd);
  2166. install_element (CONFIG_NODE, &vtysh_service_password_encrypt_cmd);
  2167. install_element (CONFIG_NODE, &no_vtysh_service_password_encrypt_cmd);
  2168. install_element (CONFIG_NODE, &vtysh_password_cmd);
  2169. install_element (CONFIG_NODE, &vtysh_password_text_cmd);
  2170. install_element (CONFIG_NODE, &vtysh_enable_password_cmd);
  2171. install_element (CONFIG_NODE, &vtysh_enable_password_text_cmd);
  2172. install_element (CONFIG_NODE, &no_vtysh_enable_password_cmd);
  2173. }