stream.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:8k
源码类别:

网络

开发平台:

Unix_Linux

  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 "stream.h"
  24. #include "memory.h"
  25. #include "network.h"
  26. #include "prefix.h"
  27. /*A macro to check pointers in order to not
  28.   go behind the allocated mem block 
  29.   S -- stream reference
  30.   Z -- size of data to be written 
  31. */
  32. #define CHECK_SIZE(S, Z) 
  33. if (((S)->putp + (Z)) > (S)->size) 
  34.            (Z) = (S)->size - (S)->putp;
  35. /* Stream is fixed length buffer for network output/input. */
  36. /* Make stream buffer. */
  37. struct stream *
  38. stream_new (size_t size)
  39. {
  40.   struct stream *s;
  41.   s = XCALLOC (MTYPE_STREAM, sizeof (struct stream));
  42.   s->data = XCALLOC (MTYPE_STREAM_DATA, size);
  43.   s->size = size;
  44.   return s;
  45. }
  46. /* Free it now. */
  47. void
  48. stream_free (struct stream *s)
  49. {
  50.   XFREE (MTYPE_STREAM_DATA, s->data);
  51.   XFREE (MTYPE_STREAM, s);
  52. }
  53. unsigned long
  54. stream_get_getp (struct stream *s)
  55. {
  56.   return s->getp;
  57. }
  58. unsigned long
  59. stream_get_putp (struct stream *s)
  60. {
  61.   return s->putp;
  62. }
  63. unsigned long
  64. stream_get_endp (struct stream *s)
  65. {
  66.   return s->endp;
  67. }
  68. unsigned long
  69. stream_get_size (struct stream *s)
  70. {
  71.   return s->size;
  72. }
  73. /* Stream structre' stream pointer related functions.  */
  74. void
  75. stream_set_getp (struct stream *s, unsigned long pos)
  76. {
  77.   s->getp = pos;
  78. }
  79. void
  80. stream_set_putp (struct stream *s, unsigned long pos)
  81. {
  82.   s->putp = pos;
  83. }
  84. /* Forward pointer. */
  85. void
  86. stream_forward (struct stream *s, int size)
  87. {
  88.   s->getp += size;
  89. }
  90. /* Copy from stream to destination. */
  91. void
  92. stream_get (void *dst, struct stream *s, size_t size)
  93. {
  94.   memcpy (dst, s->data + s->getp, size);
  95.   s->getp += size;
  96. }
  97. /* Get next character from the stream. */
  98. u_char
  99. stream_getc (struct stream *s)
  100. {
  101.   u_char c;
  102.   c = s->data[s->getp];
  103.   s->getp++;
  104.   return c;
  105. }
  106. /* Get next character from the stream. */
  107. u_char
  108. stream_getc_from (struct stream *s, unsigned long from)
  109. {
  110.   u_char c;
  111.   c = s->data[from];
  112.   return c;
  113. }
  114. /* Get next word from the stream. */
  115. u_int16_t
  116. stream_getw (struct stream *s)
  117. {
  118.   u_int16_t w;
  119.   w = s->data[s->getp++] << 8;
  120.   w |= s->data[s->getp++];
  121.   return w;
  122. }
  123. /* Get next word from the stream. */
  124. u_int16_t
  125. stream_getw_from (struct stream *s, unsigned long from)
  126. {
  127.   u_int16_t w;
  128.   w = s->data[from++] << 8;
  129.   w |= s->data[from];
  130.   return w;
  131. }
  132. /* Get next long word from the stream. */
  133. u_int32_t
  134. stream_getl (struct stream *s)
  135. {
  136.   u_int32_t l;
  137.   l  = s->data[s->getp++] << 24;
  138.   l |= s->data[s->getp++] << 16;
  139.   l |= s->data[s->getp++] << 8;
  140.   l |= s->data[s->getp++];
  141.   return l;
  142. }
  143. /* Get next long word from the stream. */
  144. u_int32_t
  145. stream_get_ipv4 (struct stream *s)
  146. {
  147.   u_int32_t l;
  148.   memcpy (&l, s->data + s->getp, 4);
  149.   s->getp += 4;
  150.   return l;
  151. }
  152. /* Copy to source to stream. */
  153. void
  154. stream_put (struct stream *s, void *src, size_t size)
  155. {
  156.   CHECK_SIZE(s, size);
  157.   if (src)
  158.     memcpy (s->data + s->putp, src, size);
  159.   else
  160.     memset (s->data + s->putp, 0, size);
  161.   s->putp += size;
  162.   if (s->putp > s->endp)
  163.     s->endp = s->putp;
  164. }
  165. /* Put character to the stream. */
  166. int
  167. stream_putc (struct stream *s, u_char c)
  168. {
  169.   if (s->putp >= s->size) return 0;
  170.   s->data[s->putp] = c;
  171.   s->putp++;
  172.   if (s->putp > s->endp)
  173.     s->endp = s->putp;
  174.   return 1;
  175. }
  176. /* Put word to the stream. */
  177. int
  178. stream_putw (struct stream *s, u_int16_t w)
  179. {
  180.   if ((s->size - s->putp) < 2) return 0;
  181.   s->data[s->putp++] = (u_char)(w >>  8);
  182.   s->data[s->putp++] = (u_char) w;
  183.   if (s->putp > s->endp)
  184.     s->endp = s->putp;
  185.   return 2;
  186. }
  187. /* Put long word to the stream. */
  188. int
  189. stream_putl (struct stream *s, u_int32_t l)
  190. {
  191.   if ((s->size - s->putp) < 4) return 0;
  192.   s->data[s->putp++] = (u_char)(l >> 24);
  193.   s->data[s->putp++] = (u_char)(l >> 16);
  194.   s->data[s->putp++] = (u_char)(l >>  8);
  195.   s->data[s->putp++] = (u_char)l;
  196.   if (s->putp > s->endp)
  197.     s->endp = s->putp;
  198.   return 4;
  199. }
  200. int
  201. stream_putc_at (struct stream *s, unsigned long putp, u_char c)
  202. {
  203.   s->data[putp] = c;
  204.   return 1;
  205. }
  206. int
  207. stream_putw_at (struct stream *s, unsigned long putp, u_int16_t w)
  208. {
  209.   s->data[putp] = (u_char)(w >>  8);
  210.   s->data[putp + 1] = (u_char) w;
  211.   return 2;
  212. }
  213. int
  214. stream_putl_at (struct stream *s, unsigned long putp, u_int32_t l)
  215. {
  216.   s->data[putp] = (u_char)(l >> 24);
  217.   s->data[putp + 1] = (u_char)(l >> 16);
  218.   s->data[putp + 2] = (u_char)(l >>  8);
  219.   s->data[putp + 3] = (u_char)l;
  220.   return 4;
  221. }
  222. /* Put long word to the stream. */
  223. int
  224. stream_put_ipv4 (struct stream *s, u_int32_t l)
  225. {
  226.   if ((s->size - s->putp) < 4)
  227.     return 0;
  228.   memcpy (s->data + s->putp, &l, 4);
  229.   s->putp += 4;
  230.   if (s->putp > s->endp)
  231.     s->endp = s->putp;
  232.   return 4;
  233. }
  234. /* Put long word to the stream. */
  235. int
  236. stream_put_in_addr (struct stream *s, struct in_addr *addr)
  237. {
  238.   if ((s->size - s->putp) < 4)
  239.     return 0;
  240.   memcpy (s->data + s->putp, addr, 4);
  241.   s->putp += 4;
  242.   if (s->putp > s->endp)
  243.     s->endp = s->putp;
  244.   return 4;
  245. }
  246. /* Put prefix by nlri type format. */
  247. int
  248. stream_put_prefix (struct stream *s, struct prefix *p)
  249. {
  250.   u_char psize;
  251.   psize = PSIZE (p->prefixlen);
  252.   if ((s->size - s->putp) < psize) return 0;
  253.   stream_putc (s, p->prefixlen);
  254.   memcpy (s->data + s->putp, &p->u.prefix, psize);
  255.   s->putp += psize;
  256.   
  257.   if (s->putp > s->endp)
  258.     s->endp = s->putp;
  259.   return psize;
  260. }
  261. /* Read size from fd. */
  262. int
  263. stream_read (struct stream *s, int fd, size_t size)
  264. {
  265.   int nbytes;
  266.   nbytes = readn (fd, s->data + s->putp, size);
  267.   if (nbytes > 0)
  268.     {
  269.       s->putp += nbytes;
  270.       s->endp += nbytes;
  271.     }
  272.   return nbytes;
  273. }
  274. /* Read size from fd. */
  275. int
  276. stream_read_unblock (struct stream *s, int fd, size_t size)
  277. {
  278.   int nbytes;
  279.   int val;
  280.   val = fcntl (fd, F_GETFL, 0);
  281.   fcntl (fd, F_SETFL, val|O_NONBLOCK);
  282.   nbytes = read (fd, s->data + s->putp, size);
  283.   fcntl (fd, F_SETFL, val);
  284.   if (nbytes > 0)
  285.     {
  286.       s->putp += nbytes;
  287.       s->endp += nbytes;
  288.     }
  289.   return nbytes;
  290. }
  291. /* Write data to buffer. */
  292. int
  293. stream_write (struct stream *s, u_char *ptr, size_t size)
  294. {
  295.   CHECK_SIZE(s, size);
  296.   memcpy (s->data + s->putp, ptr, size);
  297.   s->putp += size;
  298.   if (s->putp > s->endp)
  299.     s->endp = s->putp;
  300.   return size;
  301. }
  302. /* Return current read pointer. */
  303. u_char *
  304. stream_pnt (struct stream *s)
  305. {
  306.   return s->data + s->getp;
  307. }
  308. /* Check does this stream empty? */
  309. int
  310. stream_empty (struct stream *s)
  311. {
  312.   if (s->putp == 0 && s->endp == 0 && s->getp == 0)
  313.     return 1;
  314.   else
  315.     return 0;
  316. }
  317. /* Reset stream. */
  318. void
  319. stream_reset (struct stream *s)
  320. {
  321.   s->putp = 0;
  322.   s->endp = 0;
  323.   s->getp = 0;
  324. }
  325. /* Write stream contens to the file discriptor. */
  326. int
  327. stream_flush (struct stream *s, int fd)
  328. {
  329.   int nbytes;
  330.   nbytes = write (fd, s->data + s->getp, s->endp - s->getp);
  331.   return nbytes;
  332. }
  333. /* Stream first in first out queue. */
  334. struct stream_fifo *
  335. stream_fifo_new ()
  336. {
  337.   struct stream_fifo *new;
  338.  
  339.   new = XCALLOC (MTYPE_STREAM_FIFO, sizeof (struct stream_fifo));
  340.   return new;
  341. }
  342. /* Add new stream to fifo. */
  343. void
  344. stream_fifo_push (struct stream_fifo *fifo, struct stream *s)
  345. {
  346.   if (fifo->tail)
  347.     fifo->tail->next = s;
  348.   else
  349.     fifo->head = s;
  350.      
  351.   fifo->tail = s;
  352.   fifo->count++;
  353. }
  354. /* Delete first stream from fifo. */
  355. struct stream *
  356. stream_fifo_pop (struct stream_fifo *fifo)
  357. {
  358.   struct stream *s;
  359.   
  360.   s = fifo->head; 
  361.   if (s)
  362.     { 
  363.       fifo->head = s->next;
  364.       if (fifo->head == NULL)
  365. fifo->tail = NULL;
  366.     }
  367.   fifo->count--;
  368.   return s; 
  369. }
  370. /* Return first fifo entry. */
  371. struct stream *
  372. stream_fifo_head (struct stream_fifo *fifo)
  373. {
  374.   return fifo->head;
  375. }
  376. void
  377. stream_fifo_clean (struct stream_fifo *fifo)
  378. {
  379.   struct stream *s;
  380.   struct stream *next;
  381.   for (s = fifo->head; s; s = next)
  382.     {
  383.       next = s->next;
  384.       stream_free (s);
  385.     }
  386.   fifo->head = fifo->tail = NULL;
  387.   fifo->count = 0;
  388. }
  389. void
  390. stream_fifo_free (struct stream_fifo *fifo)
  391. {
  392.   stream_fifo_clean (fifo);
  393.   XFREE (MTYPE_STREAM_FIFO, fifo);
  394. }