stream.c 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  1. /*
  2. * Packet interface
  3. * Copyright (C) 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. #include <zebra.h>
  23. #include <stddef.h>
  24. /* primarily for __STDC_IEC_559__ with clang */
  25. #include <features.h>
  26. #include "stream.h"
  27. #include "memory.h"
  28. #include "network.h"
  29. #include "prefix.h"
  30. #include "log.h"
  31. /* Tests whether a position is valid */
  32. #define GETP_VALID(S,G) \
  33. ((G) <= (S)->endp)
  34. #define PUT_AT_VALID(S,G) GETP_VALID(S,G)
  35. #define ENDP_VALID(S,E) \
  36. ((E) <= (S)->size)
  37. /* asserting sanity checks. Following must be true before
  38. * stream functions are called:
  39. *
  40. * Following must always be true of stream elements
  41. * before and after calls to stream functions:
  42. *
  43. * getp <= endp <= size
  44. *
  45. * Note that after a stream function is called following may be true:
  46. * if (getp == endp) then stream is no longer readable
  47. * if (endp == size) then stream is no longer writeable
  48. *
  49. * It is valid to put to anywhere within the size of the stream, but only
  50. * using stream_put..._at() functions.
  51. */
  52. #define STREAM_WARN_OFFSETS(S) \
  53. zlog_warn ("&(struct stream): %p, size: %lu, getp: %lu, endp: %lu\n", \
  54. (void *)(S), \
  55. (unsigned long) (S)->size, \
  56. (unsigned long) (S)->getp, \
  57. (unsigned long) (S)->endp)\
  58. #define STREAM_VERIFY_SANE(S) \
  59. do { \
  60. if ( !(GETP_VALID(S, (S)->getp) && ENDP_VALID(S, (S)->endp)) ) \
  61. STREAM_WARN_OFFSETS(S); \
  62. assert ( GETP_VALID(S, (S)->getp) ); \
  63. assert ( ENDP_VALID(S, (S)->endp) ); \
  64. } while (0)
  65. #define STREAM_BOUND_WARN(S, WHAT) \
  66. do { \
  67. zlog_warn ("%s: Attempt to %s out of bounds", __func__, (WHAT)); \
  68. STREAM_WARN_OFFSETS(S); \
  69. assert (0); \
  70. } while (0)
  71. /* XXX: Deprecated macro: do not use */
  72. #define CHECK_SIZE(S, Z) \
  73. do { \
  74. if (((S)->endp + (Z)) > (S)->size) \
  75. { \
  76. zlog_warn ("CHECK_SIZE: truncating requested size %lu\n", \
  77. (unsigned long) (Z)); \
  78. STREAM_WARN_OFFSETS(S); \
  79. (Z) = (S)->size - (S)->endp; \
  80. } \
  81. } while (0);
  82. /* Make stream buffer. */
  83. struct stream *
  84. stream_new (size_t size)
  85. {
  86. struct stream *s;
  87. assert (size > 0);
  88. if (size == 0)
  89. {
  90. zlog_warn ("stream_new(): called with 0 size!");
  91. return NULL;
  92. }
  93. s = XCALLOC (MTYPE_STREAM, sizeof (struct stream));
  94. if (s == NULL)
  95. return s;
  96. if ( (s->data = XMALLOC (MTYPE_STREAM_DATA, size)) == NULL)
  97. {
  98. XFREE (MTYPE_STREAM, s);
  99. return NULL;
  100. }
  101. s->size = size;
  102. return s;
  103. }
  104. /* Free it now. */
  105. void
  106. stream_free (struct stream *s)
  107. {
  108. if (!s)
  109. return;
  110. XFREE (MTYPE_STREAM_DATA, s->data);
  111. XFREE (MTYPE_STREAM, s);
  112. }
  113. struct stream *
  114. stream_copy (struct stream *new, struct stream *src)
  115. {
  116. STREAM_VERIFY_SANE (src);
  117. assert (new != NULL);
  118. assert (STREAM_SIZE(new) >= src->endp);
  119. new->endp = src->endp;
  120. new->getp = src->getp;
  121. memcpy (new->data, src->data, src->endp);
  122. return new;
  123. }
  124. struct stream *
  125. stream_dup (struct stream *s)
  126. {
  127. struct stream *new;
  128. STREAM_VERIFY_SANE (s);
  129. if ( (new = stream_new (s->endp)) == NULL)
  130. return NULL;
  131. return (stream_copy (new, s));
  132. }
  133. struct stream *
  134. stream_dupcat (struct stream *s1, struct stream *s2, size_t offset)
  135. {
  136. struct stream *new;
  137. STREAM_VERIFY_SANE (s1);
  138. STREAM_VERIFY_SANE (s2);
  139. if ( (new = stream_new (s1->endp + s2->endp)) == NULL)
  140. return NULL;
  141. memcpy (new->data, s1->data, offset);
  142. memcpy (new->data + offset, s2->data, s2->endp);
  143. memcpy (new->data + offset + s2->endp, s1->data + offset,
  144. (s1->endp - offset));
  145. new->endp = s1->endp + s2->endp;
  146. return new;
  147. }
  148. size_t
  149. stream_resize (struct stream *s, size_t newsize)
  150. {
  151. u_char *newdata;
  152. STREAM_VERIFY_SANE (s);
  153. newdata = XREALLOC (MTYPE_STREAM_DATA, s->data, newsize);
  154. if (newdata == NULL)
  155. return s->size;
  156. s->data = newdata;
  157. s->size = newsize;
  158. if (s->endp > s->size)
  159. s->endp = s->size;
  160. if (s->getp > s->endp)
  161. s->getp = s->endp;
  162. STREAM_VERIFY_SANE (s);
  163. return s->size;
  164. }
  165. size_t
  166. stream_get_getp (struct stream *s)
  167. {
  168. STREAM_VERIFY_SANE(s);
  169. return s->getp;
  170. }
  171. size_t
  172. stream_get_endp (struct stream *s)
  173. {
  174. STREAM_VERIFY_SANE(s);
  175. return s->endp;
  176. }
  177. size_t
  178. stream_get_size (struct stream *s)
  179. {
  180. STREAM_VERIFY_SANE(s);
  181. return s->size;
  182. }
  183. /* Stream structre' stream pointer related functions. */
  184. void
  185. stream_set_getp (struct stream *s, size_t pos)
  186. {
  187. STREAM_VERIFY_SANE(s);
  188. if (!GETP_VALID (s, pos))
  189. {
  190. STREAM_BOUND_WARN (s, "set getp");
  191. pos = s->endp;
  192. }
  193. s->getp = pos;
  194. }
  195. void
  196. stream_set_endp (struct stream *s, size_t pos)
  197. {
  198. STREAM_VERIFY_SANE(s);
  199. if (!ENDP_VALID(s, pos))
  200. {
  201. STREAM_BOUND_WARN (s, "set endp");
  202. return;
  203. }
  204. /*
  205. * Make sure the current read pointer is not beyond the new endp.
  206. */
  207. if (s->getp > pos)
  208. {
  209. STREAM_BOUND_WARN(s, "set endp");
  210. return;
  211. }
  212. s->endp = pos;
  213. STREAM_VERIFY_SANE(s);
  214. }
  215. /* Forward pointer. */
  216. void
  217. stream_forward_getp (struct stream *s, size_t size)
  218. {
  219. STREAM_VERIFY_SANE(s);
  220. if (!GETP_VALID (s, s->getp + size))
  221. {
  222. STREAM_BOUND_WARN (s, "seek getp");
  223. return;
  224. }
  225. s->getp += size;
  226. }
  227. void
  228. stream_forward_endp (struct stream *s, size_t size)
  229. {
  230. STREAM_VERIFY_SANE(s);
  231. if (!ENDP_VALID (s, s->endp + size))
  232. {
  233. STREAM_BOUND_WARN (s, "seek endp");
  234. return;
  235. }
  236. s->endp += size;
  237. }
  238. /* Copy from stream to destination. */
  239. void
  240. stream_get (void *dst, struct stream *s, size_t size)
  241. {
  242. STREAM_VERIFY_SANE(s);
  243. if (STREAM_READABLE(s) < size)
  244. {
  245. STREAM_BOUND_WARN (s, "get");
  246. return;
  247. }
  248. memcpy (dst, s->data + s->getp, size);
  249. s->getp += size;
  250. }
  251. /* Get next character from the stream. */
  252. u_char
  253. stream_getc (struct stream *s)
  254. {
  255. u_char c;
  256. STREAM_VERIFY_SANE (s);
  257. if (STREAM_READABLE(s) < sizeof (u_char))
  258. {
  259. STREAM_BOUND_WARN (s, "get char");
  260. return 0;
  261. }
  262. c = s->data[s->getp++];
  263. return c;
  264. }
  265. /* Get next character from the stream. */
  266. u_char
  267. stream_getc_from (struct stream *s, size_t from)
  268. {
  269. u_char c;
  270. STREAM_VERIFY_SANE(s);
  271. if (!GETP_VALID (s, from + sizeof (u_char)))
  272. {
  273. STREAM_BOUND_WARN (s, "get char");
  274. return 0;
  275. }
  276. c = s->data[from];
  277. return c;
  278. }
  279. /* Get next word from the stream. */
  280. u_int16_t
  281. stream_getw (struct stream *s)
  282. {
  283. u_int16_t w;
  284. STREAM_VERIFY_SANE (s);
  285. if (STREAM_READABLE (s) < sizeof (u_int16_t))
  286. {
  287. STREAM_BOUND_WARN (s, "get ");
  288. return 0;
  289. }
  290. w = s->data[s->getp++] << 8;
  291. w |= s->data[s->getp++];
  292. return w;
  293. }
  294. /* Get next word from the stream. */
  295. u_int16_t
  296. stream_getw_from (struct stream *s, size_t from)
  297. {
  298. u_int16_t w;
  299. STREAM_VERIFY_SANE(s);
  300. if (!GETP_VALID (s, from + sizeof (u_int16_t)))
  301. {
  302. STREAM_BOUND_WARN (s, "get ");
  303. return 0;
  304. }
  305. w = s->data[from++] << 8;
  306. w |= s->data[from];
  307. return w;
  308. }
  309. /* Get next long word from the stream. */
  310. u_int32_t
  311. stream_getl_from (struct stream *s, size_t from)
  312. {
  313. u_int32_t l;
  314. STREAM_VERIFY_SANE(s);
  315. if (!GETP_VALID (s, from + sizeof (u_int32_t)))
  316. {
  317. STREAM_BOUND_WARN (s, "get long");
  318. return 0;
  319. }
  320. l = s->data[from++] << 24;
  321. l |= s->data[from++] << 16;
  322. l |= s->data[from++] << 8;
  323. l |= s->data[from];
  324. return l;
  325. }
  326. u_int32_t
  327. stream_getl (struct stream *s)
  328. {
  329. u_int32_t l;
  330. STREAM_VERIFY_SANE(s);
  331. if (STREAM_READABLE (s) < sizeof (u_int32_t))
  332. {
  333. STREAM_BOUND_WARN (s, "get long");
  334. return 0;
  335. }
  336. l = s->data[s->getp++] << 24;
  337. l |= s->data[s->getp++] << 16;
  338. l |= s->data[s->getp++] << 8;
  339. l |= s->data[s->getp++];
  340. return l;
  341. }
  342. /* Get next quad word from the stream. */
  343. uint64_t
  344. stream_getq_from (struct stream *s, size_t from)
  345. {
  346. uint64_t q;
  347. STREAM_VERIFY_SANE(s);
  348. if (!GETP_VALID (s, from + sizeof (uint64_t)))
  349. {
  350. STREAM_BOUND_WARN (s, "get quad");
  351. return 0;
  352. }
  353. q = ((uint64_t) s->data[from++]) << 56;
  354. q |= ((uint64_t) s->data[from++]) << 48;
  355. q |= ((uint64_t) s->data[from++]) << 40;
  356. q |= ((uint64_t) s->data[from++]) << 32;
  357. q |= ((uint64_t) s->data[from++]) << 24;
  358. q |= ((uint64_t) s->data[from++]) << 16;
  359. q |= ((uint64_t) s->data[from++]) << 8;
  360. q |= ((uint64_t) s->data[from++]);
  361. return q;
  362. }
  363. uint64_t
  364. stream_getq (struct stream *s)
  365. {
  366. uint64_t q;
  367. STREAM_VERIFY_SANE(s);
  368. if (STREAM_READABLE (s) < sizeof (uint64_t))
  369. {
  370. STREAM_BOUND_WARN (s, "get quad");
  371. return 0;
  372. }
  373. q = ((uint64_t) s->data[s->getp++]) << 56;
  374. q |= ((uint64_t) s->data[s->getp++]) << 48;
  375. q |= ((uint64_t) s->data[s->getp++]) << 40;
  376. q |= ((uint64_t) s->data[s->getp++]) << 32;
  377. q |= ((uint64_t) s->data[s->getp++]) << 24;
  378. q |= ((uint64_t) s->data[s->getp++]) << 16;
  379. q |= ((uint64_t) s->data[s->getp++]) << 8;
  380. q |= ((uint64_t) s->data[s->getp++]);
  381. return q;
  382. }
  383. /* Get next long word from the stream. */
  384. u_int32_t
  385. stream_get_ipv4 (struct stream *s)
  386. {
  387. u_int32_t l;
  388. STREAM_VERIFY_SANE(s);
  389. if (STREAM_READABLE (s) < sizeof(u_int32_t))
  390. {
  391. STREAM_BOUND_WARN (s, "get ipv4");
  392. return 0;
  393. }
  394. memcpy (&l, s->data + s->getp, sizeof(u_int32_t));
  395. s->getp += sizeof(u_int32_t);
  396. return l;
  397. }
  398. float
  399. stream_getf (struct stream *s)
  400. {
  401. #if !defined(__STDC_IEC_559__) && __GCC_IEC_559 < 1
  402. #warning "Unknown floating-point format, __func__ may be wrong"
  403. #endif
  404. /* we assume 'float' is in the single precision IEC 60559 binary
  405. format, in host byte order */
  406. union {
  407. float r;
  408. uint32_t d;
  409. } u;
  410. u.d = stream_getl (s);
  411. return u.r;
  412. }
  413. double
  414. stream_getd (struct stream *s)
  415. {
  416. #if !defined(__STDC_IEC_559__) && __GCC_IEC_559 < 1
  417. #warning "Unknown floating-point format, __func__ may be wrong"
  418. #endif
  419. union {
  420. double r;
  421. uint64_t d;
  422. } u;
  423. u.d = stream_getq (s);
  424. return u.r;
  425. }
  426. /* Copy to source to stream.
  427. *
  428. * XXX: This uses CHECK_SIZE and hence has funny semantics -> Size will wrap
  429. * around. This should be fixed once the stream updates are working.
  430. *
  431. * stream_write() is saner
  432. */
  433. void
  434. stream_put (struct stream *s, const void *src, size_t size)
  435. {
  436. /* XXX: CHECK_SIZE has strange semantics. It should be deprecated */
  437. CHECK_SIZE(s, size);
  438. STREAM_VERIFY_SANE(s);
  439. if (STREAM_WRITEABLE (s) < size)
  440. {
  441. STREAM_BOUND_WARN (s, "put");
  442. return;
  443. }
  444. if (src)
  445. memcpy (s->data + s->endp, src, size);
  446. else
  447. memset (s->data + s->endp, 0, size);
  448. s->endp += size;
  449. }
  450. /* Put character to the stream. */
  451. int
  452. stream_putc (struct stream *s, u_char c)
  453. {
  454. STREAM_VERIFY_SANE(s);
  455. if (STREAM_WRITEABLE (s) < sizeof(u_char))
  456. {
  457. STREAM_BOUND_WARN (s, "put");
  458. return 0;
  459. }
  460. s->data[s->endp++] = c;
  461. return sizeof (u_char);
  462. }
  463. /* Put word to the stream. */
  464. int
  465. stream_putw (struct stream *s, u_int16_t w)
  466. {
  467. STREAM_VERIFY_SANE (s);
  468. if (STREAM_WRITEABLE (s) < sizeof (u_int16_t))
  469. {
  470. STREAM_BOUND_WARN (s, "put");
  471. return 0;
  472. }
  473. s->data[s->endp++] = (u_char)(w >> 8);
  474. s->data[s->endp++] = (u_char) w;
  475. return 2;
  476. }
  477. /* Put long word to the stream. */
  478. int
  479. stream_putl (struct stream *s, u_int32_t l)
  480. {
  481. STREAM_VERIFY_SANE (s);
  482. if (STREAM_WRITEABLE (s) < sizeof (u_int32_t))
  483. {
  484. STREAM_BOUND_WARN (s, "put");
  485. return 0;
  486. }
  487. s->data[s->endp++] = (u_char)(l >> 24);
  488. s->data[s->endp++] = (u_char)(l >> 16);
  489. s->data[s->endp++] = (u_char)(l >> 8);
  490. s->data[s->endp++] = (u_char)l;
  491. return 4;
  492. }
  493. /* Put quad word to the stream. */
  494. int
  495. stream_putq (struct stream *s, uint64_t q)
  496. {
  497. STREAM_VERIFY_SANE (s);
  498. if (STREAM_WRITEABLE (s) < sizeof (uint64_t))
  499. {
  500. STREAM_BOUND_WARN (s, "put quad");
  501. return 0;
  502. }
  503. s->data[s->endp++] = (u_char)(q >> 56);
  504. s->data[s->endp++] = (u_char)(q >> 48);
  505. s->data[s->endp++] = (u_char)(q >> 40);
  506. s->data[s->endp++] = (u_char)(q >> 32);
  507. s->data[s->endp++] = (u_char)(q >> 24);
  508. s->data[s->endp++] = (u_char)(q >> 16);
  509. s->data[s->endp++] = (u_char)(q >> 8);
  510. s->data[s->endp++] = (u_char)q;
  511. return 8;
  512. }
  513. int
  514. stream_putf (struct stream *s, float f)
  515. {
  516. #if !defined(__STDC_IEC_559__) && __GCC_IEC_559 < 1
  517. #warning "Unknown floating-point format, __func__ may be wrong"
  518. #endif
  519. /* we can safely assume 'float' is in the single precision
  520. IEC 60559 binary format in host order */
  521. union {
  522. float i;
  523. uint32_t o;
  524. } u;
  525. u.i = f;
  526. return stream_putl (s, u.o);
  527. }
  528. int
  529. stream_putd (struct stream *s, double d)
  530. {
  531. #if !defined(__STDC_IEC_559__) && __GCC_IEC_559 < 1
  532. #warning "Unknown floating-point format, __func__ may be wrong"
  533. #endif
  534. union {
  535. double i;
  536. uint64_t o;
  537. } u;
  538. u.i = d;
  539. return stream_putq (s, u.o);
  540. }
  541. int
  542. stream_putc_at (struct stream *s, size_t putp, u_char c)
  543. {
  544. STREAM_VERIFY_SANE(s);
  545. if (!PUT_AT_VALID (s, putp + sizeof (u_char)))
  546. {
  547. STREAM_BOUND_WARN (s, "put");
  548. return 0;
  549. }
  550. s->data[putp] = c;
  551. return 1;
  552. }
  553. int
  554. stream_putw_at (struct stream *s, size_t putp, u_int16_t w)
  555. {
  556. STREAM_VERIFY_SANE(s);
  557. if (!PUT_AT_VALID (s, putp + sizeof (u_int16_t)))
  558. {
  559. STREAM_BOUND_WARN (s, "put");
  560. return 0;
  561. }
  562. s->data[putp] = (u_char)(w >> 8);
  563. s->data[putp + 1] = (u_char) w;
  564. return 2;
  565. }
  566. int
  567. stream_putl_at (struct stream *s, size_t putp, u_int32_t l)
  568. {
  569. STREAM_VERIFY_SANE(s);
  570. if (!PUT_AT_VALID (s, putp + sizeof (u_int32_t)))
  571. {
  572. STREAM_BOUND_WARN (s, "put");
  573. return 0;
  574. }
  575. s->data[putp] = (u_char)(l >> 24);
  576. s->data[putp + 1] = (u_char)(l >> 16);
  577. s->data[putp + 2] = (u_char)(l >> 8);
  578. s->data[putp + 3] = (u_char)l;
  579. return 4;
  580. }
  581. int
  582. stream_putq_at (struct stream *s, size_t putp, uint64_t q)
  583. {
  584. STREAM_VERIFY_SANE(s);
  585. if (!PUT_AT_VALID (s, putp + sizeof (uint64_t)))
  586. {
  587. STREAM_BOUND_WARN (s, "put");
  588. return 0;
  589. }
  590. s->data[putp] = (u_char)(q >> 56);
  591. s->data[putp + 1] = (u_char)(q >> 48);
  592. s->data[putp + 2] = (u_char)(q >> 40);
  593. s->data[putp + 3] = (u_char)(q >> 32);
  594. s->data[putp + 4] = (u_char)(q >> 24);
  595. s->data[putp + 5] = (u_char)(q >> 16);
  596. s->data[putp + 6] = (u_char)(q >> 8);
  597. s->data[putp + 7] = (u_char)q;
  598. return 8;
  599. }
  600. /* Put long word to the stream. */
  601. int
  602. stream_put_ipv4 (struct stream *s, u_int32_t l)
  603. {
  604. STREAM_VERIFY_SANE(s);
  605. if (STREAM_WRITEABLE (s) < sizeof (u_int32_t))
  606. {
  607. STREAM_BOUND_WARN (s, "put");
  608. return 0;
  609. }
  610. memcpy (s->data + s->endp, &l, sizeof (u_int32_t));
  611. s->endp += sizeof (u_int32_t);
  612. return sizeof (u_int32_t);
  613. }
  614. /* Put long word to the stream. */
  615. int
  616. stream_put_in_addr (struct stream *s, struct in_addr *addr)
  617. {
  618. STREAM_VERIFY_SANE(s);
  619. if (STREAM_WRITEABLE (s) < sizeof (u_int32_t))
  620. {
  621. STREAM_BOUND_WARN (s, "put");
  622. return 0;
  623. }
  624. memcpy (s->data + s->endp, addr, sizeof (u_int32_t));
  625. s->endp += sizeof (u_int32_t);
  626. return sizeof (u_int32_t);
  627. }
  628. /* Put prefix by nlri type format. */
  629. int
  630. stream_put_prefix (struct stream *s, struct prefix *p)
  631. {
  632. size_t psize;
  633. STREAM_VERIFY_SANE(s);
  634. psize = PSIZE (p->prefixlen);
  635. if (STREAM_WRITEABLE (s) < (psize + sizeof (u_char)))
  636. {
  637. STREAM_BOUND_WARN (s, "put");
  638. return 0;
  639. }
  640. s->data[s->endp++] = p->prefixlen;
  641. memcpy (s->data + s->endp, &p->u.prefix, psize);
  642. s->endp += psize;
  643. return psize;
  644. }
  645. /* Read size from fd. */
  646. int
  647. stream_read (struct stream *s, int fd, size_t size)
  648. {
  649. int nbytes;
  650. STREAM_VERIFY_SANE(s);
  651. if (STREAM_WRITEABLE (s) < size)
  652. {
  653. STREAM_BOUND_WARN (s, "put");
  654. return 0;
  655. }
  656. nbytes = readn (fd, s->data + s->endp, size);
  657. if (nbytes > 0)
  658. s->endp += nbytes;
  659. return nbytes;
  660. }
  661. ssize_t
  662. stream_read_try(struct stream *s, int fd, size_t size)
  663. {
  664. ssize_t nbytes;
  665. STREAM_VERIFY_SANE(s);
  666. if (STREAM_WRITEABLE(s) < size)
  667. {
  668. STREAM_BOUND_WARN (s, "put");
  669. /* Fatal (not transient) error, since retrying will not help
  670. (stream is too small to contain the desired data). */
  671. return -1;
  672. }
  673. if ((nbytes = read(fd, s->data + s->endp, size)) >= 0)
  674. {
  675. s->endp += nbytes;
  676. return nbytes;
  677. }
  678. /* Error: was it transient (return -2) or fatal (return -1)? */
  679. if (ERRNO_IO_RETRY(errno))
  680. return -2;
  681. zlog_warn("%s: read failed on fd %d: %s", __func__, fd, safe_strerror(errno));
  682. return -1;
  683. }
  684. /* Read up to size bytes into the stream from the fd, using recvmsgfrom
  685. * whose arguments match the remaining arguments to this function
  686. */
  687. ssize_t
  688. stream_recvfrom (struct stream *s, int fd, size_t size, int flags,
  689. struct sockaddr *from, socklen_t *fromlen)
  690. {
  691. ssize_t nbytes;
  692. STREAM_VERIFY_SANE(s);
  693. if (STREAM_WRITEABLE(s) < size)
  694. {
  695. STREAM_BOUND_WARN (s, "put");
  696. /* Fatal (not transient) error, since retrying will not help
  697. (stream is too small to contain the desired data). */
  698. return -1;
  699. }
  700. if ((nbytes = recvfrom (fd, s->data + s->endp, size,
  701. flags, from, fromlen)) >= 0)
  702. {
  703. s->endp += nbytes;
  704. return nbytes;
  705. }
  706. /* Error: was it transient (return -2) or fatal (return -1)? */
  707. if (ERRNO_IO_RETRY(errno))
  708. return -2;
  709. zlog_warn("%s: read failed on fd %d: %s", __func__, fd, safe_strerror(errno));
  710. return -1;
  711. }
  712. /* Read up to smaller of size or SIZE_REMAIN() bytes to the stream, starting
  713. * from endp.
  714. * First iovec will be used to receive the data.
  715. * Stream need not be empty.
  716. */
  717. ssize_t
  718. stream_recvmsg (struct stream *s, int fd, struct msghdr *msgh, int flags,
  719. size_t size)
  720. {
  721. int nbytes;
  722. struct iovec *iov;
  723. STREAM_VERIFY_SANE(s);
  724. assert (msgh->msg_iovlen > 0);
  725. if (STREAM_WRITEABLE (s) < size)
  726. {
  727. STREAM_BOUND_WARN (s, "put");
  728. /* This is a logic error in the calling code: the stream is too small
  729. to hold the desired data! */
  730. return -1;
  731. }
  732. iov = &(msgh->msg_iov[0]);
  733. iov->iov_base = (s->data + s->endp);
  734. iov->iov_len = size;
  735. nbytes = recvmsg (fd, msgh, flags);
  736. if (nbytes > 0)
  737. s->endp += nbytes;
  738. return nbytes;
  739. }
  740. /* Write data to buffer. */
  741. size_t
  742. stream_write (struct stream *s, const void *ptr, size_t size)
  743. {
  744. CHECK_SIZE(s, size);
  745. STREAM_VERIFY_SANE(s);
  746. if (STREAM_WRITEABLE (s) < size)
  747. {
  748. STREAM_BOUND_WARN (s, "put");
  749. return 0;
  750. }
  751. memcpy (s->data + s->endp, ptr, size);
  752. s->endp += size;
  753. return size;
  754. }
  755. /* Return current read pointer.
  756. * DEPRECATED!
  757. * Use stream_get_pnt_to if you must, but decoding streams properly
  758. * is preferred
  759. */
  760. u_char *
  761. stream_pnt (struct stream *s)
  762. {
  763. STREAM_VERIFY_SANE(s);
  764. return s->data + s->getp;
  765. }
  766. /* Check does this stream empty? */
  767. int
  768. stream_empty (struct stream *s)
  769. {
  770. STREAM_VERIFY_SANE(s);
  771. return (s->endp == 0);
  772. }
  773. /* Reset stream. */
  774. void
  775. stream_reset (struct stream *s)
  776. {
  777. STREAM_VERIFY_SANE (s);
  778. s->getp = s->endp = 0;
  779. }
  780. /* Write stream contens to the file discriptor. */
  781. int
  782. stream_flush (struct stream *s, int fd)
  783. {
  784. int nbytes;
  785. STREAM_VERIFY_SANE(s);
  786. nbytes = write (fd, s->data + s->getp, s->endp - s->getp);
  787. return nbytes;
  788. }
  789. /* Stream first in first out queue. */
  790. struct stream_fifo *
  791. stream_fifo_new (void)
  792. {
  793. struct stream_fifo *new;
  794. new = XCALLOC (MTYPE_STREAM_FIFO, sizeof (struct stream_fifo));
  795. return new;
  796. }
  797. /* Add new stream to fifo. */
  798. void
  799. stream_fifo_push (struct stream_fifo *fifo, struct stream *s)
  800. {
  801. if (fifo->tail)
  802. fifo->tail->next = s;
  803. else
  804. fifo->head = s;
  805. fifo->tail = s;
  806. fifo->count++;
  807. }
  808. /* Delete first stream from fifo. */
  809. struct stream *
  810. stream_fifo_pop (struct stream_fifo *fifo)
  811. {
  812. struct stream *s;
  813. s = fifo->head;
  814. if (s)
  815. {
  816. fifo->head = s->next;
  817. if (fifo->head == NULL)
  818. fifo->tail = NULL;
  819. fifo->count--;
  820. }
  821. return s;
  822. }
  823. /* Return first fifo entry. */
  824. struct stream *
  825. stream_fifo_head (struct stream_fifo *fifo)
  826. {
  827. return fifo->head;
  828. }
  829. void
  830. stream_fifo_clean (struct stream_fifo *fifo)
  831. {
  832. struct stream *s;
  833. struct stream *next;
  834. for (s = fifo->head; s; s = next)
  835. {
  836. next = s->next;
  837. stream_free (s);
  838. }
  839. fifo->head = fifo->tail = NULL;
  840. fifo->count = 0;
  841. }
  842. void
  843. stream_fifo_free (struct stream_fifo *fifo)
  844. {
  845. stream_fifo_clean (fifo);
  846. XFREE (MTYPE_STREAM_FIFO, fifo);
  847. }