log.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. /*
  2. * Logging of zebra
  3. * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro
  4. *
  5. * This file is part of GNU Zebra.
  6. *
  7. * GNU Zebra is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2, or (at your option) any
  10. * later version.
  11. *
  12. * GNU Zebra is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  19. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20. * 02111-1307, USA.
  21. */
  22. #define QUAGGA_DEFINE_DESC_TABLE
  23. #include <zebra.h>
  24. #include "log.h"
  25. #include "memory.h"
  26. #include "command.h"
  27. #ifndef SUNOS_5
  28. #include <sys/un.h>
  29. #endif
  30. /* for printstack on solaris */
  31. #ifdef HAVE_UCONTEXT_H
  32. #include <ucontext.h>
  33. #endif
  34. static int logfile_fd = -1; /* Used in signal handler. */
  35. struct zlog *zlog_default = NULL;
  36. const char *zlog_proto_names[] =
  37. {
  38. "NONE",
  39. "DEFAULT",
  40. "ZEBRA",
  41. "RIP",
  42. "BGP",
  43. "OSPF",
  44. "RIPNG",
  45. "BABEL",
  46. "OSPF6",
  47. "ISIS",
  48. "PIM",
  49. "MASC",
  50. "NHRP",
  51. NULL,
  52. };
  53. const char *zlog_priority[] =
  54. {
  55. "emergencies",
  56. "alerts",
  57. "critical",
  58. "errors",
  59. "warnings",
  60. "notifications",
  61. "informational",
  62. "debugging",
  63. NULL,
  64. };
  65. /* For time string format. */
  66. size_t
  67. quagga_timestamp(int timestamp_precision, char *buf, size_t buflen)
  68. {
  69. static struct {
  70. time_t last;
  71. size_t len;
  72. char buf[28];
  73. } cache;
  74. struct timeval clock;
  75. /* would it be sufficient to use global 'recent_time' here? I fear not... */
  76. gettimeofday(&clock, NULL);
  77. /* first, we update the cache if the time has changed */
  78. if (cache.last != clock.tv_sec)
  79. {
  80. struct tm *tm;
  81. cache.last = clock.tv_sec;
  82. tm = localtime(&cache.last);
  83. cache.len = strftime(cache.buf, sizeof(cache.buf),
  84. "%Y/%m/%d %H:%M:%S", tm);
  85. }
  86. /* note: it's not worth caching the subsecond part, because
  87. chances are that back-to-back calls are not sufficiently close together
  88. for the clock not to have ticked forward */
  89. if (buflen > cache.len)
  90. {
  91. memcpy(buf, cache.buf, cache.len);
  92. if ((timestamp_precision > 0) &&
  93. (buflen > cache.len+1+timestamp_precision))
  94. {
  95. /* should we worry about locale issues? */
  96. static const int divisor[] = {0, 100000, 10000, 1000, 100, 10, 1};
  97. int prec;
  98. char *p = buf+cache.len+1+(prec = timestamp_precision);
  99. *p-- = '\0';
  100. while (prec > 6)
  101. /* this is unlikely to happen, but protect anyway */
  102. {
  103. *p-- = '0';
  104. prec--;
  105. }
  106. clock.tv_usec /= divisor[prec];
  107. do
  108. {
  109. *p-- = '0'+(clock.tv_usec % 10);
  110. clock.tv_usec /= 10;
  111. }
  112. while (--prec > 0);
  113. *p = '.';
  114. return cache.len+1+timestamp_precision;
  115. }
  116. buf[cache.len] = '\0';
  117. return cache.len;
  118. }
  119. if (buflen > 0)
  120. buf[0] = '\0';
  121. return 0;
  122. }
  123. /* Utility routine for current time printing. */
  124. static void
  125. time_print(FILE *fp, struct timestamp_control *ctl)
  126. {
  127. if (!ctl->already_rendered)
  128. {
  129. ctl->len = quagga_timestamp(ctl->precision, ctl->buf, sizeof(ctl->buf));
  130. ctl->already_rendered = 1;
  131. }
  132. fprintf(fp, "%s ", ctl->buf);
  133. }
  134. /* va_list version of zlog. */
  135. static void
  136. vzlog (struct zlog *zl, int priority, const char *format, va_list args)
  137. {
  138. int original_errno = errno;
  139. struct timestamp_control tsctl;
  140. tsctl.already_rendered = 0;
  141. /* If zlog is not specified, use default one. */
  142. if (zl == NULL)
  143. zl = zlog_default;
  144. /* When zlog_default is also NULL, use stderr for logging. */
  145. if (zl == NULL)
  146. {
  147. tsctl.precision = 0;
  148. time_print(stderr, &tsctl);
  149. fprintf (stderr, "%s: ", "unknown");
  150. vfprintf (stderr, format, args);
  151. fprintf (stderr, "\n");
  152. fflush (stderr);
  153. /* In this case we return at here. */
  154. errno = original_errno;
  155. return;
  156. }
  157. tsctl.precision = zl->timestamp_precision;
  158. /* Syslog output */
  159. if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG])
  160. {
  161. va_list ac;
  162. va_copy(ac, args);
  163. vsyslog (priority|zlog_default->facility, format, ac);
  164. va_end(ac);
  165. }
  166. /* File output. */
  167. if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp)
  168. {
  169. va_list ac;
  170. time_print (zl->fp, &tsctl);
  171. if (zl->record_priority)
  172. fprintf (zl->fp, "%s: ", zlog_priority[priority]);
  173. fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]);
  174. va_copy(ac, args);
  175. vfprintf (zl->fp, format, ac);
  176. va_end(ac);
  177. fprintf (zl->fp, "\n");
  178. fflush (zl->fp);
  179. }
  180. /* stdout output. */
  181. if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT])
  182. {
  183. va_list ac;
  184. time_print (stdout, &tsctl);
  185. if (zl->record_priority)
  186. fprintf (stdout, "%s: ", zlog_priority[priority]);
  187. fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]);
  188. va_copy(ac, args);
  189. vfprintf (stdout, format, ac);
  190. va_end(ac);
  191. fprintf (stdout, "\n");
  192. fflush (stdout);
  193. }
  194. /* Terminal monitor. */
  195. if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR])
  196. vty_log ((zl->record_priority ? zlog_priority[priority] : NULL),
  197. zlog_proto_names[zl->protocol], format, &tsctl, args);
  198. errno = original_errno;
  199. }
  200. static char *
  201. str_append(char *dst, int len, const char *src)
  202. {
  203. while ((len-- > 0) && *src)
  204. *dst++ = *src++;
  205. return dst;
  206. }
  207. static char *
  208. num_append(char *s, int len, u_long x)
  209. {
  210. char buf[30];
  211. char *t;
  212. if (!x)
  213. return str_append(s,len,"0");
  214. *(t = &buf[sizeof(buf)-1]) = '\0';
  215. while (x && (t > buf))
  216. {
  217. *--t = '0'+(x % 10);
  218. x /= 10;
  219. }
  220. return str_append(s,len,t);
  221. }
  222. #if defined(SA_SIGINFO) || defined(HAVE_STACK_TRACE)
  223. static char *
  224. hex_append(char *s, int len, u_long x)
  225. {
  226. char buf[30];
  227. char *t;
  228. if (!x)
  229. return str_append(s,len,"0");
  230. *(t = &buf[sizeof(buf)-1]) = '\0';
  231. while (x && (t > buf))
  232. {
  233. u_int cc = (x % 16);
  234. *--t = ((cc < 10) ? ('0'+cc) : ('a'+cc-10));
  235. x /= 16;
  236. }
  237. return str_append(s,len,t);
  238. }
  239. #endif
  240. /* Needs to be enhanced to support Solaris. */
  241. static int
  242. syslog_connect(void)
  243. {
  244. #ifdef SUNOS_5
  245. return -1;
  246. #else
  247. int fd;
  248. char *s;
  249. struct sockaddr_un addr;
  250. if ((fd = socket(AF_UNIX,SOCK_DGRAM,0)) < 0)
  251. return -1;
  252. addr.sun_family = AF_UNIX;
  253. #ifdef _PATH_LOG
  254. #define SYSLOG_SOCKET_PATH _PATH_LOG
  255. #else
  256. #define SYSLOG_SOCKET_PATH "/dev/log"
  257. #endif
  258. s = str_append(addr.sun_path,sizeof(addr.sun_path),SYSLOG_SOCKET_PATH);
  259. #undef SYSLOG_SOCKET_PATH
  260. *s = '\0';
  261. if (connect(fd,(struct sockaddr *)&addr,sizeof(addr)) < 0)
  262. {
  263. close(fd);
  264. return -1;
  265. }
  266. return fd;
  267. #endif
  268. }
  269. static void
  270. syslog_sigsafe(int priority, const char *msg, size_t msglen)
  271. {
  272. static int syslog_fd = -1;
  273. char buf[sizeof("<1234567890>ripngd[1234567890]: ")+msglen+50];
  274. char *s;
  275. if ((syslog_fd < 0) && ((syslog_fd = syslog_connect()) < 0))
  276. return;
  277. #define LOC s,buf+sizeof(buf)-s
  278. s = buf;
  279. s = str_append(LOC,"<");
  280. s = num_append(LOC,priority);
  281. s = str_append(LOC,">");
  282. /* forget about the timestamp, too difficult in a signal handler */
  283. s = str_append(LOC,zlog_default->ident);
  284. if (zlog_default->syslog_options & LOG_PID)
  285. {
  286. s = str_append(LOC,"[");
  287. s = num_append(LOC,getpid());
  288. s = str_append(LOC,"]");
  289. }
  290. s = str_append(LOC,": ");
  291. s = str_append(LOC,msg);
  292. write(syslog_fd,buf,s-buf);
  293. #undef LOC
  294. }
  295. static int
  296. open_crashlog(void)
  297. {
  298. #define CRASHLOG_PREFIX "/var/tmp/quagga."
  299. #define CRASHLOG_SUFFIX "crashlog"
  300. if (zlog_default && zlog_default->ident)
  301. {
  302. /* Avoid strlen since it is not async-signal-safe. */
  303. const char *p;
  304. size_t ilen;
  305. for (p = zlog_default->ident, ilen = 0; *p; p++)
  306. ilen++;
  307. {
  308. char buf[sizeof(CRASHLOG_PREFIX)+ilen+sizeof(CRASHLOG_SUFFIX)+3];
  309. char *s = buf;
  310. #define LOC s,buf+sizeof(buf)-s
  311. s = str_append(LOC, CRASHLOG_PREFIX);
  312. s = str_append(LOC, zlog_default->ident);
  313. s = str_append(LOC, ".");
  314. s = str_append(LOC, CRASHLOG_SUFFIX);
  315. #undef LOC
  316. *s = '\0';
  317. return open(buf, O_WRONLY|O_CREAT|O_EXCL, LOGFILE_MASK);
  318. }
  319. }
  320. return open(CRASHLOG_PREFIX CRASHLOG_SUFFIX, O_WRONLY|O_CREAT|O_EXCL,
  321. LOGFILE_MASK);
  322. #undef CRASHLOG_SUFFIX
  323. #undef CRASHLOG_PREFIX
  324. }
  325. /* Note: the goal here is to use only async-signal-safe functions. */
  326. void
  327. zlog_signal(int signo, const char *action
  328. #ifdef SA_SIGINFO
  329. , siginfo_t *siginfo, void *program_counter
  330. #endif
  331. )
  332. {
  333. time_t now;
  334. char buf[sizeof("DEFAULT: Received signal S at T (si_addr 0xP, PC 0xP); aborting...")+100];
  335. char *s = buf;
  336. char *msgstart = buf;
  337. #define LOC s,buf+sizeof(buf)-s
  338. time(&now);
  339. if (zlog_default)
  340. {
  341. s = str_append(LOC,zlog_proto_names[zlog_default->protocol]);
  342. *s++ = ':';
  343. *s++ = ' ';
  344. msgstart = s;
  345. }
  346. s = str_append(LOC,"Received signal ");
  347. s = num_append(LOC,signo);
  348. s = str_append(LOC," at ");
  349. s = num_append(LOC,now);
  350. #ifdef SA_SIGINFO
  351. s = str_append(LOC," (si_addr 0x");
  352. s = hex_append(LOC,(u_long)(siginfo->si_addr));
  353. if (program_counter)
  354. {
  355. s = str_append(LOC,", PC 0x");
  356. s = hex_append(LOC,(u_long)program_counter);
  357. }
  358. s = str_append(LOC,"); ");
  359. #else /* SA_SIGINFO */
  360. s = str_append(LOC,"; ");
  361. #endif /* SA_SIGINFO */
  362. s = str_append(LOC,action);
  363. if (s < buf+sizeof(buf))
  364. *s++ = '\n';
  365. /* N.B. implicit priority is most severe */
  366. #define PRI LOG_CRIT
  367. #define DUMP(FD) write(FD, buf, s-buf);
  368. /* If no file logging configured, try to write to fallback log file. */
  369. if ((logfile_fd >= 0) || ((logfile_fd = open_crashlog()) >= 0))
  370. DUMP(logfile_fd)
  371. if (!zlog_default)
  372. DUMP(STDERR_FILENO)
  373. else
  374. {
  375. if (PRI <= zlog_default->maxlvl[ZLOG_DEST_STDOUT])
  376. DUMP(STDOUT_FILENO)
  377. /* Remove trailing '\n' for monitor and syslog */
  378. *--s = '\0';
  379. if (PRI <= zlog_default->maxlvl[ZLOG_DEST_MONITOR])
  380. vty_log_fixed(buf,s-buf);
  381. if (PRI <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG])
  382. syslog_sigsafe(PRI|zlog_default->facility,msgstart,s-msgstart);
  383. }
  384. #undef DUMP
  385. zlog_backtrace_sigsafe(PRI,
  386. #ifdef SA_SIGINFO
  387. program_counter
  388. #else
  389. NULL
  390. #endif
  391. );
  392. s = buf;
  393. if (!thread_current)
  394. s = str_append (LOC, "no thread information available\n");
  395. else
  396. {
  397. s = str_append (LOC, "in thread ");
  398. s = str_append (LOC, thread_current->funcname);
  399. s = str_append (LOC, " scheduled from ");
  400. s = str_append (LOC, thread_current->schedfrom);
  401. s = str_append (LOC, ":");
  402. s = num_append (LOC, thread_current->schedfrom_line);
  403. s = str_append (LOC, "\n");
  404. }
  405. #define DUMP(FD) write(FD, buf, s-buf);
  406. /* If no file logging configured, try to write to fallback log file. */
  407. if (logfile_fd >= 0)
  408. DUMP(logfile_fd)
  409. if (!zlog_default)
  410. DUMP(STDERR_FILENO)
  411. else
  412. {
  413. if (PRI <= zlog_default->maxlvl[ZLOG_DEST_STDOUT])
  414. DUMP(STDOUT_FILENO)
  415. /* Remove trailing '\n' for monitor and syslog */
  416. *--s = '\0';
  417. if (PRI <= zlog_default->maxlvl[ZLOG_DEST_MONITOR])
  418. vty_log_fixed(buf,s-buf);
  419. if (PRI <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG])
  420. syslog_sigsafe(PRI|zlog_default->facility,msgstart,s-msgstart);
  421. }
  422. #undef DUMP
  423. #undef PRI
  424. #undef LOC
  425. }
  426. /* Log a backtrace using only async-signal-safe functions.
  427. Needs to be enhanced to support syslog logging. */
  428. void
  429. zlog_backtrace_sigsafe(int priority, void *program_counter)
  430. {
  431. #ifdef HAVE_STACK_TRACE
  432. static const char pclabel[] = "Program counter: ";
  433. void *array[64];
  434. int size;
  435. char buf[100];
  436. char *s, **bt = NULL;
  437. #define LOC s,buf+sizeof(buf)-s
  438. #ifdef HAVE_GLIBC_BACKTRACE
  439. size = backtrace(array, array_size(array));
  440. if (size <= 0 || (size_t)size > array_size(array))
  441. return;
  442. #define DUMP(FD) { \
  443. if (program_counter) \
  444. { \
  445. write(FD, pclabel, sizeof(pclabel)-1); \
  446. backtrace_symbols_fd(&program_counter, 1, FD); \
  447. } \
  448. write(FD, buf, s-buf); \
  449. backtrace_symbols_fd(array, size, FD); \
  450. }
  451. #elif defined(HAVE_PRINTSTACK)
  452. #define DUMP(FD) { \
  453. if (program_counter) \
  454. write((FD), pclabel, sizeof(pclabel)-1); \
  455. write((FD), buf, s-buf); \
  456. printstack((FD)); \
  457. }
  458. #endif /* HAVE_GLIBC_BACKTRACE, HAVE_PRINTSTACK */
  459. s = buf;
  460. s = str_append(LOC,"Backtrace for ");
  461. s = num_append(LOC,size);
  462. s = str_append(LOC," stack frames:\n");
  463. if ((logfile_fd >= 0) || ((logfile_fd = open_crashlog()) >= 0))
  464. DUMP(logfile_fd)
  465. if (!zlog_default)
  466. DUMP(STDERR_FILENO)
  467. else
  468. {
  469. if (priority <= zlog_default->maxlvl[ZLOG_DEST_STDOUT])
  470. DUMP(STDOUT_FILENO)
  471. /* Remove trailing '\n' for monitor and syslog */
  472. *--s = '\0';
  473. if (priority <= zlog_default->maxlvl[ZLOG_DEST_MONITOR])
  474. vty_log_fixed(buf,s-buf);
  475. if (priority <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG])
  476. syslog_sigsafe(priority|zlog_default->facility,buf,s-buf);
  477. {
  478. int i;
  479. #ifdef HAVE_GLIBC_BACKTRACE
  480. bt = backtrace_symbols(array, size);
  481. #endif
  482. /* Just print the function addresses. */
  483. for (i = 0; i < size; i++)
  484. {
  485. s = buf;
  486. if (bt)
  487. s = str_append(LOC, bt[i]);
  488. else {
  489. s = str_append(LOC,"[bt ");
  490. s = num_append(LOC,i);
  491. s = str_append(LOC,"] 0x");
  492. s = hex_append(LOC,(u_long)(array[i]));
  493. }
  494. *s = '\0';
  495. if (priority <= zlog_default->maxlvl[ZLOG_DEST_MONITOR])
  496. vty_log_fixed(buf,s-buf);
  497. if (priority <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG])
  498. syslog_sigsafe(priority|zlog_default->facility,buf,s-buf);
  499. }
  500. if (bt)
  501. free(bt);
  502. }
  503. }
  504. #undef DUMP
  505. #undef LOC
  506. #endif /* HAVE_STRACK_TRACE */
  507. }
  508. void
  509. zlog_backtrace(int priority)
  510. {
  511. #ifndef HAVE_GLIBC_BACKTRACE
  512. zlog(NULL, priority, "No backtrace available on this platform.");
  513. #else
  514. void *array[20];
  515. int size, i;
  516. char **strings;
  517. size = backtrace(array, array_size(array));
  518. if (size <= 0 || (size_t)size > array_size(array))
  519. {
  520. zlog_err("Cannot get backtrace, returned invalid # of frames %d "
  521. "(valid range is between 1 and %lu)",
  522. size, (unsigned long)(array_size(array)));
  523. return;
  524. }
  525. zlog(NULL, priority, "Backtrace for %d stack frames:", size);
  526. if (!(strings = backtrace_symbols(array, size)))
  527. {
  528. zlog_err("Cannot get backtrace symbols (out of memory?)");
  529. for (i = 0; i < size; i++)
  530. zlog(NULL, priority, "[bt %d] %p",i,array[i]);
  531. }
  532. else
  533. {
  534. for (i = 0; i < size; i++)
  535. zlog(NULL, priority, "[bt %d] %s",i,strings[i]);
  536. free(strings);
  537. }
  538. #endif /* HAVE_GLIBC_BACKTRACE */
  539. }
  540. void
  541. zlog (struct zlog *zl, int priority, const char *format, ...)
  542. {
  543. va_list args;
  544. va_start(args, format);
  545. vzlog (zl, priority, format, args);
  546. va_end (args);
  547. }
  548. #define ZLOG_FUNC(FUNCNAME,PRIORITY) \
  549. void \
  550. FUNCNAME(const char *format, ...) \
  551. { \
  552. va_list args; \
  553. va_start(args, format); \
  554. vzlog (NULL, PRIORITY, format, args); \
  555. va_end(args); \
  556. }
  557. ZLOG_FUNC(zlog_err, LOG_ERR)
  558. ZLOG_FUNC(zlog_warn, LOG_WARNING)
  559. ZLOG_FUNC(zlog_info, LOG_INFO)
  560. ZLOG_FUNC(zlog_notice, LOG_NOTICE)
  561. ZLOG_FUNC(zlog_debug, LOG_DEBUG)
  562. #undef ZLOG_FUNC
  563. #define PLOG_FUNC(FUNCNAME,PRIORITY) \
  564. void \
  565. FUNCNAME(struct zlog *zl, const char *format, ...) \
  566. { \
  567. va_list args; \
  568. va_start(args, format); \
  569. vzlog (zl, PRIORITY, format, args); \
  570. va_end(args); \
  571. }
  572. PLOG_FUNC(plog_err, LOG_ERR)
  573. PLOG_FUNC(plog_warn, LOG_WARNING)
  574. PLOG_FUNC(plog_info, LOG_INFO)
  575. PLOG_FUNC(plog_notice, LOG_NOTICE)
  576. PLOG_FUNC(plog_debug, LOG_DEBUG)
  577. #undef PLOG_FUNC
  578. void zlog_thread_info (int log_level)
  579. {
  580. if (thread_current)
  581. zlog(NULL, log_level, "Current thread function %s, scheduled from "
  582. "file %s, line %u", thread_current->funcname,
  583. thread_current->schedfrom, thread_current->schedfrom_line);
  584. else
  585. zlog(NULL, log_level, "Current thread not known/applicable");
  586. }
  587. void
  588. _zlog_assert_failed (const char *assertion, const char *file,
  589. unsigned int line, const char *function)
  590. {
  591. /* Force fallback file logging? */
  592. if (zlog_default && !zlog_default->fp &&
  593. ((logfile_fd = open_crashlog()) >= 0) &&
  594. ((zlog_default->fp = fdopen(logfile_fd, "w")) != NULL))
  595. zlog_default->maxlvl[ZLOG_DEST_FILE] = LOG_ERR;
  596. zlog(NULL, LOG_CRIT, "Assertion `%s' failed in file %s, line %u, function %s",
  597. assertion,file,line,(function ? function : "?"));
  598. zlog_backtrace(LOG_CRIT);
  599. zlog_thread_info(LOG_CRIT);
  600. abort();
  601. }
  602. /* Open log stream */
  603. struct zlog *
  604. openzlog (const char *progname, zlog_proto_t protocol,
  605. int syslog_flags, int syslog_facility)
  606. {
  607. struct zlog *zl;
  608. u_int i;
  609. zl = XCALLOC(MTYPE_ZLOG, sizeof (struct zlog));
  610. zl->ident = progname;
  611. zl->protocol = protocol;
  612. zl->facility = syslog_facility;
  613. zl->syslog_options = syslog_flags;
  614. /* Set default logging levels. */
  615. for (i = 0; i < array_size(zl->maxlvl); i++)
  616. zl->maxlvl[i] = ZLOG_DISABLED;
  617. zl->maxlvl[ZLOG_DEST_MONITOR] = LOG_DEBUG;
  618. zl->default_lvl = LOG_DEBUG;
  619. openlog (progname, syslog_flags, zl->facility);
  620. return zl;
  621. }
  622. void
  623. closezlog (struct zlog *zl)
  624. {
  625. closelog();
  626. if (zl->fp != NULL)
  627. fclose (zl->fp);
  628. if (zl->filename != NULL)
  629. free (zl->filename);
  630. XFREE (MTYPE_ZLOG, zl);
  631. }
  632. /* Called from command.c. */
  633. void
  634. zlog_set_level (struct zlog *zl, zlog_dest_t dest, int log_level)
  635. {
  636. if (zl == NULL)
  637. zl = zlog_default;
  638. zl->maxlvl[dest] = log_level;
  639. }
  640. int
  641. zlog_set_file (struct zlog *zl, const char *filename, int log_level)
  642. {
  643. FILE *fp;
  644. mode_t oldumask;
  645. /* There is opend file. */
  646. zlog_reset_file (zl);
  647. /* Set default zl. */
  648. if (zl == NULL)
  649. zl = zlog_default;
  650. /* Open file. */
  651. oldumask = umask (0777 & ~LOGFILE_MASK);
  652. fp = fopen (filename, "a");
  653. umask(oldumask);
  654. if (fp == NULL)
  655. return 0;
  656. /* Set flags. */
  657. zl->filename = strdup (filename);
  658. zl->maxlvl[ZLOG_DEST_FILE] = log_level;
  659. zl->fp = fp;
  660. logfile_fd = fileno(fp);
  661. return 1;
  662. }
  663. /* Reset opend file. */
  664. int
  665. zlog_reset_file (struct zlog *zl)
  666. {
  667. if (zl == NULL)
  668. zl = zlog_default;
  669. if (zl->fp)
  670. fclose (zl->fp);
  671. zl->fp = NULL;
  672. logfile_fd = -1;
  673. zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED;
  674. if (zl->filename)
  675. free (zl->filename);
  676. zl->filename = NULL;
  677. return 1;
  678. }
  679. /* Reopen log file. */
  680. int
  681. zlog_rotate (struct zlog *zl)
  682. {
  683. int level;
  684. if (zl == NULL)
  685. zl = zlog_default;
  686. if (zl->fp)
  687. fclose (zl->fp);
  688. zl->fp = NULL;
  689. logfile_fd = -1;
  690. level = zl->maxlvl[ZLOG_DEST_FILE];
  691. zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED;
  692. if (zl->filename)
  693. {
  694. mode_t oldumask;
  695. int save_errno;
  696. oldumask = umask (0777 & ~LOGFILE_MASK);
  697. zl->fp = fopen (zl->filename, "a");
  698. save_errno = errno;
  699. umask(oldumask);
  700. if (zl->fp == NULL)
  701. {
  702. zlog_err("Log rotate failed: cannot open file %s for append: %s",
  703. zl->filename, safe_strerror(save_errno));
  704. return -1;
  705. }
  706. logfile_fd = fileno(zl->fp);
  707. zl->maxlvl[ZLOG_DEST_FILE] = level;
  708. }
  709. return 1;
  710. }
  711. /* Message lookup function. */
  712. const char *
  713. lookup (const struct message *mes, int key)
  714. {
  715. const struct message *pnt;
  716. for (pnt = mes; pnt->key != 0; pnt++)
  717. if (pnt->key == key)
  718. return pnt->str;
  719. return "";
  720. }
  721. /* Older/faster version of message lookup function, but requires caller to pass
  722. * in the array size (instead of relying on a 0 key to terminate the search).
  723. *
  724. * The return value is the message string if found, or the 'none' pointer
  725. * provided otherwise.
  726. */
  727. const char *
  728. mes_lookup (const struct message *meslist, int max, int index,
  729. const char *none, const char *mesname)
  730. {
  731. int pos = index - meslist[0].key;
  732. /* first check for best case: index is in range and matches the key
  733. * value in that slot.
  734. * NB: key numbering might be offset from 0. E.g. protocol constants
  735. * often start at 1.
  736. */
  737. if ((pos >= 0) && (pos < max)
  738. && (meslist[pos].key == index))
  739. return meslist[pos].str;
  740. /* fall back to linear search */
  741. {
  742. int i;
  743. for (i = 0; i < max; i++, meslist++)
  744. {
  745. if (meslist->key == index)
  746. {
  747. const char *str = (meslist->str ? meslist->str : none);
  748. zlog_debug ("message index %d [%s] found in %s at position %d (max is %d)",
  749. index, str, mesname, i, max);
  750. return str;
  751. }
  752. }
  753. }
  754. zlog_err("message index %d not found in %s (max is %d)", index, mesname, max);
  755. assert (none);
  756. return none;
  757. }
  758. /* Wrapper around strerror to handle case where it returns NULL. */
  759. const char *
  760. safe_strerror(int errnum)
  761. {
  762. const char *s = strerror(errnum);
  763. return (s != NULL) ? s : "Unknown error";
  764. }
  765. #define DESC_ENTRY(T) [(T)] = { (T), (#T), '\0' }
  766. static const struct zebra_desc_table command_types[] = {
  767. DESC_ENTRY (ZEBRA_INTERFACE_ADD),
  768. DESC_ENTRY (ZEBRA_INTERFACE_DELETE),
  769. DESC_ENTRY (ZEBRA_INTERFACE_ADDRESS_ADD),
  770. DESC_ENTRY (ZEBRA_INTERFACE_ADDRESS_DELETE),
  771. DESC_ENTRY (ZEBRA_INTERFACE_UP),
  772. DESC_ENTRY (ZEBRA_INTERFACE_DOWN),
  773. DESC_ENTRY (ZEBRA_IPV4_ROUTE_ADD),
  774. DESC_ENTRY (ZEBRA_IPV4_ROUTE_DELETE),
  775. DESC_ENTRY (ZEBRA_IPV6_ROUTE_ADD),
  776. DESC_ENTRY (ZEBRA_IPV6_ROUTE_DELETE),
  777. DESC_ENTRY (ZEBRA_REDISTRIBUTE_ADD),
  778. DESC_ENTRY (ZEBRA_REDISTRIBUTE_DELETE),
  779. DESC_ENTRY (ZEBRA_REDISTRIBUTE_DEFAULT_ADD),
  780. DESC_ENTRY (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE),
  781. DESC_ENTRY (ZEBRA_IPV4_NEXTHOP_LOOKUP),
  782. DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_LOOKUP),
  783. DESC_ENTRY (ZEBRA_IPV4_IMPORT_LOOKUP),
  784. DESC_ENTRY (ZEBRA_IPV6_IMPORT_LOOKUP),
  785. DESC_ENTRY (ZEBRA_INTERFACE_RENAME),
  786. DESC_ENTRY (ZEBRA_ROUTER_ID_ADD),
  787. DESC_ENTRY (ZEBRA_ROUTER_ID_DELETE),
  788. DESC_ENTRY (ZEBRA_ROUTER_ID_UPDATE),
  789. DESC_ENTRY (ZEBRA_HELLO),
  790. DESC_ENTRY (ZEBRA_NEXTHOP_REGISTER),
  791. DESC_ENTRY (ZEBRA_NEXTHOP_UNREGISTER),
  792. DESC_ENTRY (ZEBRA_NEXTHOP_UPDATE),
  793. };
  794. #undef DESC_ENTRY
  795. static const struct zebra_desc_table unknown = { 0, "unknown", '?' };
  796. static const struct zebra_desc_table *
  797. zroute_lookup(u_int zroute)
  798. {
  799. u_int i;
  800. if (zroute >= array_size(route_types))
  801. {
  802. zlog_err("unknown zebra route type: %u", zroute);
  803. return &unknown;
  804. }
  805. if (zroute == route_types[zroute].type)
  806. return &route_types[zroute];
  807. for (i = 0; i < array_size(route_types); i++)
  808. {
  809. if (zroute == route_types[i].type)
  810. {
  811. zlog_warn("internal error: route type table out of order "
  812. "while searching for %u, please notify developers", zroute);
  813. return &route_types[i];
  814. }
  815. }
  816. zlog_err("internal error: cannot find route type %u in table!", zroute);
  817. return &unknown;
  818. }
  819. const char *
  820. zebra_route_string(u_int zroute)
  821. {
  822. return zroute_lookup(zroute)->string;
  823. }
  824. char
  825. zebra_route_char(u_int zroute)
  826. {
  827. return zroute_lookup(zroute)->chr;
  828. }
  829. const char *
  830. zserv_command_string (unsigned int command)
  831. {
  832. if (command >= array_size(command_types))
  833. {
  834. zlog_err ("unknown zserv command type: %u", command);
  835. return unknown.string;
  836. }
  837. return command_types[command].string;
  838. }
  839. int
  840. proto_name2num(const char *s)
  841. {
  842. unsigned i;
  843. for (i=0; i<array_size(route_types); ++i)
  844. if (strcasecmp(s, route_types[i].string) == 0)
  845. return route_types[i].type;
  846. return -1;
  847. }
  848. int
  849. proto_redistnum(int afi, const char *s)
  850. {
  851. if (! s)
  852. return -1;
  853. if (afi == AFI_IP)
  854. {
  855. if (strncmp (s, "k", 1) == 0)
  856. return ZEBRA_ROUTE_KERNEL;
  857. else if (strncmp (s, "c", 1) == 0)
  858. return ZEBRA_ROUTE_CONNECT;
  859. else if (strncmp (s, "s", 1) == 0)
  860. return ZEBRA_ROUTE_STATIC;
  861. else if (strncmp (s, "r", 1) == 0)
  862. return ZEBRA_ROUTE_RIP;
  863. else if (strncmp (s, "o", 1) == 0)
  864. return ZEBRA_ROUTE_OSPF;
  865. else if (strncmp (s, "i", 1) == 0)
  866. return ZEBRA_ROUTE_ISIS;
  867. else if (strncmp (s, "bg", 2) == 0)
  868. return ZEBRA_ROUTE_BGP;
  869. else if (strncmp (s, "ba", 2) == 0)
  870. return ZEBRA_ROUTE_BABEL;
  871. else if (strncmp (s, "n", 1) == 0)
  872. return ZEBRA_ROUTE_NHRP;
  873. }
  874. if (afi == AFI_IP6)
  875. {
  876. if (strncmp (s, "k", 1) == 0)
  877. return ZEBRA_ROUTE_KERNEL;
  878. else if (strncmp (s, "c", 1) == 0)
  879. return ZEBRA_ROUTE_CONNECT;
  880. else if (strncmp (s, "s", 1) == 0)
  881. return ZEBRA_ROUTE_STATIC;
  882. else if (strncmp (s, "r", 1) == 0)
  883. return ZEBRA_ROUTE_RIPNG;
  884. else if (strncmp (s, "o", 1) == 0)
  885. return ZEBRA_ROUTE_OSPF6;
  886. else if (strncmp (s, "i", 1) == 0)
  887. return ZEBRA_ROUTE_ISIS;
  888. else if (strncmp (s, "bg", 2) == 0)
  889. return ZEBRA_ROUTE_BGP;
  890. else if (strncmp (s, "ba", 2) == 0)
  891. return ZEBRA_ROUTE_BABEL;
  892. else if (strncmp (s, "n", 1) == 0)
  893. return ZEBRA_ROUTE_NHRP;
  894. }
  895. return -1;
  896. }
  897. void
  898. zlog_hexdump (void *mem, unsigned int len) {
  899. unsigned long i = 0;
  900. unsigned int j = 0;
  901. unsigned int columns = 8;
  902. char buf[(len * 4) + ((len/4) * 20) + 30];
  903. char *s = buf;
  904. for (i = 0; i < len + ((len % columns) ? (columns - len % columns) : 0); i++)
  905. {
  906. /* print offset */
  907. if (i % columns == 0)
  908. s += sprintf(s, "0x%016lx: ", (unsigned long)mem + i);
  909. /* print hex data */
  910. if (i < len)
  911. s += sprintf(s, "%02x ", 0xFF & ((char*)mem)[i]);
  912. /* end of block, just aligning for ASCII dump */
  913. else
  914. s += sprintf(s, " ");
  915. /* print ASCII dump */
  916. if (i % columns == (columns - 1))
  917. {
  918. for (j = i - (columns - 1); j <= i; j++)
  919. {
  920. if (j >= len) /* end of block, not really printing */
  921. s += sprintf(s, " ");
  922. else if(isprint((int)((char*)mem)[j])) /* printable char */
  923. s += sprintf(s, "%c", 0xFF & ((char*)mem)[j]);
  924. else /* other char */
  925. s += sprintf(s, ".");
  926. }
  927. s += sprintf(s, "\n");
  928. }
  929. }
  930. zlog_debug("\n%s", buf);
  931. }