1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/common/buffer.cc Tue Aug 29 17:42:13 2006 +0200
1.3 @@ -0,0 +1,595 @@
1.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
1.5 +/*
1.6 + * Copyright (c) 2005,2006 INRIA
1.7 + * All rights reserved.
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or modify
1.10 + * it under the terms of the GNU General Public License version 2 as
1.11 + * published by the Free Software Foundation;
1.12 + *
1.13 + * This program is distributed in the hope that it will be useful,
1.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.16 + * GNU General Public License for more details.
1.17 + *
1.18 + * You should have received a copy of the GNU General Public License
1.19 + * along with this program; if not, write to the Free Software
1.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.21 + *
1.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
1.23 + */
1.24 +#include "buffer.h"
1.25 +#include <cassert>
1.26 +
1.27 +#include <iostream>
1.28 +//#define TRACE(x) std::cout << x << std::endl;
1.29 +#define TRACE(x)
1.30 +
1.31 +namespace yans {
1.32 +
1.33 +Buffer::BufferDataList Buffer::m_free_list;
1.34 +uint32_t Buffer::m_max_total_add_start = 0;
1.35 +uint32_t Buffer::m_max_total_add_end = 0;
1.36 +
1.37 +struct Buffer::BufferData *
1.38 +Buffer::allocate (uint32_t req_size, uint32_t req_start)
1.39 +{
1.40 + if (req_size == 0) {
1.41 + req_size = 1;
1.42 + }
1.43 + assert (req_size >= 1);
1.44 + uint32_t size = req_size - 1 + sizeof (struct Buffer::BufferData);
1.45 + uint8_t *b = new uint8_t [size];
1.46 + struct BufferData *data = reinterpret_cast<struct Buffer::BufferData*>(b);
1.47 + data->m_size = req_size;
1.48 + data->m_initial_start = req_start;
1.49 + data->m_dirty_start = req_start;
1.50 + data->m_dirty_size = 0;
1.51 + data->m_count = 1;
1.52 + return data;
1.53 +}
1.54 +
1.55 +void
1.56 +Buffer::deallocate (struct Buffer::BufferData *data)
1.57 +{
1.58 + uint8_t *buf = reinterpret_cast<uint8_t *> (data);
1.59 + delete [] buf;
1.60 +}
1.61 +#ifdef USE_FREE_LIST
1.62 +void
1.63 +Buffer::recycle (struct Buffer::BufferData *data)
1.64 +{
1.65 + assert (data->m_count == 0);
1.66 + /* get rid of it if it is too small for later reuse. */
1.67 + if (data->m_size < (Buffer::m_max_total_add_start + Buffer::m_max_total_add_end)) {
1.68 + Buffer::deallocate (data);
1.69 + return;
1.70 + }
1.71 + /* feed into free list */
1.72 + if (Buffer::m_free_list.size () > 1000) {
1.73 + Buffer::deallocate (data);
1.74 + } else {
1.75 + Buffer::m_free_list.push_back (data);
1.76 + }
1.77 +}
1.78 +
1.79 +Buffer::BufferData *
1.80 +Buffer::create (void)
1.81 +{
1.82 + /* try to find a buffer correctly sized. */
1.83 + while (!Buffer::m_free_list.empty ()) {
1.84 + struct Buffer::BufferData *data = Buffer::m_free_list.back ();
1.85 + Buffer::m_free_list.pop_back ();
1.86 + if (data->m_size >= (m_max_total_add_start + m_max_total_add_end)) {
1.87 + data->m_initial_start = m_max_total_add_start;
1.88 + data->m_dirty_start = m_max_total_add_start;
1.89 + data->m_dirty_size = 0;
1.90 + data->m_count = 1;
1.91 + return data;
1.92 + }
1.93 + Buffer::deallocate (data);
1.94 + }
1.95 + struct Buffer::BufferData *data = Buffer::allocate (m_max_total_add_start+m_max_total_add_end,
1.96 + m_max_total_add_start);
1.97 + assert (data->m_count == 1);
1.98 + return data;
1.99 +}
1.100 +#else
1.101 +void
1.102 +Buffer::recycle (struct Buffer::BufferData *data)
1.103 +{
1.104 + Buffer::deallocate (data);
1.105 +}
1.106 +
1.107 +Buffer::BufferData *
1.108 +Buffer::create (void)
1.109 +{
1.110 + return Buffer::allocate (m_max_total_add_start+m_max_total_add_end,
1.111 + m_max_total_add_start);
1.112 +}
1.113 +#endif
1.114 +
1.115 +}; // namespace yans
1.116 +
1.117 +
1.118 +#include <cassert>
1.119 +
1.120 +namespace yans {
1.121 +
1.122 +
1.123 +void
1.124 +Buffer::add_at_start (uint32_t start)
1.125 +{
1.126 + assert (m_start <= m_data->m_initial_start);
1.127 + bool is_dirty = m_data->m_count > 1 && m_start > m_data->m_dirty_start;
1.128 + if (m_start >= start && !is_dirty) {
1.129 + /* enough space in the buffer and not dirty. */
1.130 + m_start -= start;
1.131 + m_size += start;
1.132 + } else if (m_size + start <= m_data->m_size && !is_dirty) {
1.133 + /* enough space but need to move data around to fit new data */
1.134 + memmove (m_data->m_data + start, get_start (), m_size);
1.135 + assert (start > m_start);
1.136 + m_data->m_initial_start += start;
1.137 + m_start = 0;
1.138 + m_size += start;
1.139 + } else if (m_start < start) {
1.140 + /* not enough space in buffer */
1.141 + uint32_t new_size = m_size + start;
1.142 + struct Buffer::BufferData *new_data = Buffer::allocate (new_size, 0);
1.143 + memcpy (new_data->m_data + start, get_start (), m_size);
1.144 + new_data->m_initial_start = m_data->m_initial_start + start;
1.145 + m_data->m_count--;
1.146 + if (m_data->m_count == 0) {
1.147 + Buffer::deallocate (m_data);
1.148 + }
1.149 + m_data = new_data;
1.150 + m_start = 0;
1.151 + m_size = new_size;
1.152 + } else {
1.153 + /* enough space in the buffer but it is dirty ! */
1.154 + assert (is_dirty);
1.155 + struct Buffer::BufferData *new_data = Buffer::create ();
1.156 + memcpy (new_data->m_data + m_start, get_start (), m_size);
1.157 + new_data->m_initial_start = m_data->m_initial_start;
1.158 + m_data->m_count--;
1.159 + if (m_data->m_count == 0) {
1.160 + recycle (m_data);
1.161 + }
1.162 + m_data = new_data;
1.163 + m_start -= start;
1.164 + m_size += start;
1.165 + }
1.166 + // update dirty area
1.167 + m_data->m_dirty_start = m_start;
1.168 + m_data->m_dirty_size = m_size;
1.169 + // update m_max_total_add_start
1.170 + uint32_t added_at_start;
1.171 + if (m_data->m_initial_start > m_start) {
1.172 + added_at_start = m_data->m_initial_start - m_start;
1.173 + } else {
1.174 + added_at_start = 0;
1.175 + }
1.176 + if (added_at_start > m_max_total_add_start) {
1.177 + m_max_total_add_start = added_at_start;
1.178 + }
1.179 + TRACE ("start add="<<start<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zero_area_size<<
1.180 + ", real size="<<m_data->m_size<<", ini start="<<m_data->m_initial_start<<
1.181 + ", dirty start="<<m_data->m_dirty_start<<", dirty size="<<m_data->m_dirty_size);
1.182 +}
1.183 +void
1.184 +Buffer::add_at_end (uint32_t end)
1.185 +{
1.186 + assert (m_start <= m_data->m_initial_start);
1.187 + bool is_dirty = m_data->m_count > 1 &&
1.188 + m_start + m_size < m_data->m_dirty_start + m_data->m_dirty_size;
1.189 + if (m_start + m_size + end <= m_data->m_size && !is_dirty) {
1.190 + /* enough space in buffer and not dirty */
1.191 + m_size += end;
1.192 + } else if (m_size + end <= m_data->m_size && !is_dirty) {
1.193 + /* enough space but need to move data around to fit the extra data */
1.194 + uint32_t new_start = m_data->m_size - (m_size + end);
1.195 + memmove (m_data->m_data + new_start, get_start (), m_size);
1.196 + assert (new_start < m_start);
1.197 + m_data->m_initial_start -= m_start - new_start;
1.198 + m_start = new_start;
1.199 + m_size += end;
1.200 + } else if (m_start + m_size + end > m_data->m_size) {
1.201 + /* not enough space in buffer */
1.202 + uint32_t new_size = m_size + end;
1.203 + struct Buffer::BufferData *new_data = Buffer::allocate (new_size, 0);
1.204 + memcpy (new_data->m_data, get_start (), m_size);
1.205 + new_data->m_initial_start = m_data->m_initial_start;
1.206 + m_data->m_count--;
1.207 + if (m_data->m_count == 0) {
1.208 + Buffer::deallocate (m_data);
1.209 + }
1.210 + m_data = new_data;
1.211 + m_size = new_size;
1.212 + m_start = 0;
1.213 + } else {
1.214 + /* enough space in the buffer but it is dirty ! */
1.215 + assert (is_dirty);
1.216 + struct Buffer::BufferData *new_data = Buffer::create ();
1.217 + memcpy (new_data->m_data + m_start, get_start (), m_size);
1.218 + new_data->m_initial_start = m_data->m_initial_start;
1.219 + m_data->m_count--;
1.220 + if (m_data->m_count == 0) {
1.221 + recycle (m_data);
1.222 + }
1.223 + m_data = new_data;
1.224 + m_size += end;
1.225 + }
1.226 + // update dirty area
1.227 + m_data->m_dirty_start = m_start;
1.228 + m_data->m_dirty_size = m_size;
1.229 + // update m_max_total_add_end
1.230 + uint32_t end_loc = m_start + m_size;
1.231 + uint32_t added_at_end;
1.232 + if (m_data->m_initial_start < end_loc) {
1.233 + added_at_end = end_loc - m_data->m_initial_start;
1.234 + } else {
1.235 + added_at_end = 0;
1.236 + }
1.237 + if (added_at_end > m_max_total_add_end) {
1.238 + m_max_total_add_end = added_at_end;
1.239 + }
1.240 + TRACE ("end add="<<end<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zero_area_size<<
1.241 + ", real size="<<m_data->m_size<<", ini start="<<m_data->m_initial_start<<
1.242 + ", dirty start="<<m_data->m_dirty_start<<", dirty size="<<m_data->m_dirty_size);
1.243 +}
1.244 +
1.245 +void
1.246 +Buffer::remove_at_start (uint32_t start)
1.247 +{
1.248 + if (m_zero_area_size == 0) {
1.249 + if (m_size <= start) {
1.250 + m_start += m_size;
1.251 + m_size = 0;
1.252 + } else {
1.253 + m_start += start;
1.254 + m_size -= start;
1.255 + }
1.256 + } else {
1.257 + assert (m_data->m_initial_start >= m_start);
1.258 + uint32_t zero_start = m_data->m_initial_start - m_start;
1.259 + uint32_t zero_end = zero_start + m_zero_area_size;
1.260 + uint32_t data_end = m_size + m_zero_area_size;
1.261 + if (start <= zero_start) {
1.262 + /* only remove start of buffer */
1.263 + m_start += start;
1.264 + m_size -= start;
1.265 + } else if (start <= zero_end) {
1.266 + /* remove start of buffer _and_ start of zero area */
1.267 + m_start += zero_start;
1.268 + uint32_t zero_delta = start - zero_start;
1.269 + m_zero_area_size -= zero_delta;
1.270 + assert (zero_delta <= start);
1.271 + m_size -= zero_start;
1.272 + } else if (start <= data_end) {
1.273 + /* remove start of buffer, complete zero area, and part
1.274 + * of end of buffer */
1.275 + m_start += start - m_zero_area_size;
1.276 + m_size -= start - m_zero_area_size;
1.277 + m_zero_area_size = 0;
1.278 + } else {
1.279 + /* remove all buffer */
1.280 + m_start += m_size;
1.281 + m_size = 0;
1.282 + m_zero_area_size = 0;
1.283 + }
1.284 + }
1.285 + TRACE ("start remove="<<start<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zero_area_size<<
1.286 + ", real size="<<m_data->m_size<<", ini start="<<m_data->m_initial_start<<
1.287 + ", dirty start="<<m_data->m_dirty_start<<", dirty size="<<m_data->m_dirty_size);
1.288 +}
1.289 +void
1.290 +Buffer::remove_at_end (uint32_t end)
1.291 +{
1.292 + if (m_zero_area_size == 0) {
1.293 + if (m_size <= end) {
1.294 + m_size = 0;
1.295 + } else {
1.296 + m_size -= end;
1.297 + }
1.298 + } else {
1.299 + assert (m_data->m_initial_start >= m_start);
1.300 + uint32_t zero_start = m_data->m_initial_start - m_start;
1.301 + uint32_t zero_end = zero_start + m_zero_area_size;
1.302 + uint32_t data_end = m_size + m_zero_area_size;
1.303 + assert (zero_start <= m_size);
1.304 + assert (zero_end <= m_size + m_zero_area_size);
1.305 + if (data_end <= end) {
1.306 + /* remove all buffer */
1.307 + m_zero_area_size = 0;
1.308 + m_start += m_size;
1.309 + m_size = 0;
1.310 + } else if (data_end - zero_start <= end) {
1.311 + /* remove end of buffer, zero area, part of start of buffer */
1.312 + assert (end >= m_zero_area_size);
1.313 + m_size -= end - m_zero_area_size;
1.314 + m_zero_area_size = 0;
1.315 + } else if (data_end - zero_end <= end) {
1.316 + /* remove end of buffer, part of zero area */
1.317 + uint32_t zero_delta = end - (data_end - zero_end);
1.318 + m_zero_area_size -= zero_delta;
1.319 + m_size -= end - zero_delta;
1.320 + } else {
1.321 + /* remove part of end of buffer */
1.322 + m_size -= end;
1.323 + }
1.324 + }
1.325 + TRACE ("end remove="<<end<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zero_area_size<<
1.326 + ", real size="<<m_data->m_size<<", ini start="<<m_data->m_initial_start<<
1.327 + ", dirty start="<<m_data->m_dirty_start<<", dirty size="<<m_data->m_dirty_size);
1.328 +}
1.329 +
1.330 +Buffer
1.331 +Buffer::create_fragment (uint32_t start, uint32_t length) const
1.332 +{
1.333 + uint32_t zero_start = m_data->m_initial_start - m_start;
1.334 + uint32_t zero_end = zero_start + m_zero_area_size;
1.335 + if (m_zero_area_size != 0 &&
1.336 + start + length > zero_start &&
1.337 + start <= zero_end) {
1.338 + transform_into_real_buffer ();
1.339 + }
1.340 + Buffer tmp = *this;
1.341 + tmp.remove_at_start (start);
1.342 + tmp.remove_at_end (get_size () - (start + length));
1.343 + return tmp;
1.344 +}
1.345 +
1.346 +void
1.347 +Buffer::transform_into_real_buffer (void) const
1.348 +{
1.349 + if (m_zero_area_size != 0) {
1.350 + assert (m_data->m_initial_start >= m_start);
1.351 + assert (m_size >= (m_data->m_initial_start - m_start));
1.352 + Buffer tmp;
1.353 + tmp.add_at_start (m_zero_area_size);
1.354 + tmp.begin ().write_u8 (0, m_zero_area_size);
1.355 + uint32_t data_start = m_data->m_initial_start - m_start;
1.356 + tmp.add_at_start (data_start);
1.357 + tmp.begin ().write (m_data->m_data+m_start, data_start);
1.358 + uint32_t data_end = m_size - (m_data->m_initial_start - m_start);
1.359 + tmp.add_at_end (data_end);
1.360 + Buffer::Iterator i = tmp.end ();
1.361 + i.prev (data_end);
1.362 + i.write (m_data->m_data+m_data->m_initial_start,data_end);
1.363 + *const_cast<Buffer *> (this) = tmp;
1.364 + }
1.365 +}
1.366 +
1.367 +
1.368 +uint8_t *
1.369 +Buffer::peek_data (void) const
1.370 +{
1.371 + transform_into_real_buffer ();
1.372 + return m_data->m_data + m_start;
1.373 +}
1.374 +
1.375 +
1.376 +
1.377 +
1.378 +}; // namespace yans
1.379 +
1.380 +
1.381 +#ifdef RUN_SELF_TESTS
1.382 +
1.383 +#include "yans/test.h"
1.384 +#include <iomanip>
1.385 +
1.386 +namespace yans {
1.387 +
1.388 +class BufferTest: public Test {
1.389 +private:
1.390 + bool ensure_written_bytes (Buffer b, uint32_t n, uint8_t array[]);
1.391 +public:
1.392 + virtual bool run_tests (void);
1.393 + BufferTest ();
1.394 +};
1.395 +
1.396 +
1.397 +BufferTest::BufferTest ()
1.398 + : Test ("Buffer") {}
1.399 +
1.400 +bool
1.401 +BufferTest::ensure_written_bytes (Buffer b, uint32_t n, uint8_t array[])
1.402 +{
1.403 + bool success = true;
1.404 + uint8_t *expected = array;
1.405 + uint8_t *got;
1.406 + got = b.peek_data ();
1.407 + for (uint32_t j = 0; j < n; j++) {
1.408 + if (got[j] != expected[j]) {
1.409 + success = false;
1.410 + }
1.411 + }
1.412 + if (!success) {
1.413 + failure () << "Buffer -- ";
1.414 + failure () << "expected: n=";
1.415 + failure () << n << ", ";
1.416 + failure ().setf (std::ios::hex, std::ios::basefield);
1.417 + for (uint32_t j = 0; j < n; j++) {
1.418 + failure () << (uint16_t)expected[j] << " ";
1.419 + }
1.420 + failure ().setf (std::ios::dec, std::ios::basefield);
1.421 + failure () << "got: ";
1.422 + failure ().setf (std::ios::hex, std::ios::basefield);
1.423 + for (uint32_t j = 0; j < n; j++) {
1.424 + failure () << (uint16_t)got[j] << " ";
1.425 + }
1.426 + failure () << std::endl;
1.427 + }
1.428 + return success;
1.429 +}
1.430 +
1.431 +/* Note: works only when variadic macros are
1.432 + * available which is the case for gcc.
1.433 + * XXX
1.434 + */
1.435 +#define ENSURE_WRITTEN_BYTES(buffer, n, ...) \
1.436 +{ \
1.437 + uint8_t bytes[] = {__VA_ARGS__}; \
1.438 + if (!ensure_written_bytes (buffer, n , bytes)) { \
1.439 + ok = false; \
1.440 + } \
1.441 +}
1.442 +
1.443 +bool
1.444 +BufferTest::run_tests (void)
1.445 +{
1.446 + bool ok = true;
1.447 + Buffer buffer;
1.448 + Buffer::Iterator i;
1.449 + buffer.add_at_start (6);
1.450 + i = buffer.begin ();
1.451 + i.write_u8 (0x66);
1.452 + ENSURE_WRITTEN_BYTES (buffer, 1, 0x66);
1.453 + i = buffer.begin ();
1.454 + i.write_u8 (0x67);
1.455 + ENSURE_WRITTEN_BYTES (buffer, 1, 0x67);
1.456 + i.write_hton_u16 (0x6568);
1.457 + i = buffer.begin ();
1.458 + ENSURE_WRITTEN_BYTES (buffer, 3, 0x67, 0x65, 0x68);
1.459 + i.write_hton_u16 (0x6369);
1.460 + ENSURE_WRITTEN_BYTES (buffer, 3, 0x63, 0x69, 0x68);
1.461 + i.write_hton_u32 (0xdeadbeaf);
1.462 + ENSURE_WRITTEN_BYTES (buffer, 6, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
1.463 + buffer.add_at_start (2);
1.464 + i = buffer.begin ();
1.465 + i.write_u16 (0);
1.466 + ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
1.467 + buffer.add_at_end (2);
1.468 + i = buffer.begin ();
1.469 + i.next (8);
1.470 + i.write_u16 (0);
1.471 + ENSURE_WRITTEN_BYTES (buffer, 10, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
1.472 + buffer.remove_at_start (3);
1.473 + i = buffer.begin ();
1.474 + ENSURE_WRITTEN_BYTES (buffer, 7, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
1.475 + buffer.remove_at_end (4);
1.476 + i = buffer.begin ();
1.477 + ENSURE_WRITTEN_BYTES (buffer, 3, 0x69, 0xde, 0xad);
1.478 + buffer.add_at_start (1);
1.479 + i = buffer.begin ();
1.480 + i.write_u8 (0xff);
1.481 + ENSURE_WRITTEN_BYTES (buffer, 4, 0xff, 0x69, 0xde, 0xad);
1.482 + buffer.add_at_end (1);
1.483 + i = buffer.begin ();
1.484 + i.next (4);
1.485 + i.write_u8 (0xff);
1.486 + i.prev (2);
1.487 + uint16_t saved = i.read_u16 ();
1.488 + i.prev (2);
1.489 + i.write_hton_u16 (0xff00);
1.490 + i.prev (2);
1.491 + if (i.read_ntoh_u16 () != 0xff00) {
1.492 + ok = false;
1.493 + }
1.494 + i.prev (2);
1.495 + i.write_u16 (saved);
1.496 + ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
1.497 + Buffer o = buffer;
1.498 + ENSURE_WRITTEN_BYTES (o, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
1.499 + o.add_at_start (1);
1.500 + i = o.begin ();
1.501 + i.write_u8 (0xfe);
1.502 + ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
1.503 + buffer.add_at_start (2);
1.504 + i = buffer.begin ();
1.505 + i.write_u8 (0xfd);
1.506 + i.write_u8 (0xfd);
1.507 + ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
1.508 + ENSURE_WRITTEN_BYTES (buffer, 7, 0xfd, 0xfd, 0xff, 0x69, 0xde, 0xad, 0xff);
1.509 +
1.510 + // test self-assignment
1.511 + {
1.512 + Buffer a = o;
1.513 + a = a;
1.514 + }
1.515 +
1.516 + // test remove start.
1.517 + buffer = Buffer (5);
1.518 + ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
1.519 + buffer.remove_at_start (1);
1.520 + ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
1.521 + buffer.add_at_start (1);
1.522 + buffer.begin ().write_u8 (0xff);
1.523 + ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0, 0, 0, 0);
1.524 + buffer.remove_at_start(3);
1.525 + ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
1.526 + buffer.add_at_start (4);
1.527 + buffer.begin ().write_hton_u32 (0xdeadbeaf);
1.528 + ENSURE_WRITTEN_BYTES (buffer, 6, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
1.529 + buffer.remove_at_start (2);
1.530 + ENSURE_WRITTEN_BYTES (buffer, 4, 0xbe, 0xaf, 0, 0);
1.531 + buffer.add_at_end (4);
1.532 + i = buffer.begin ();
1.533 + i.next (4);
1.534 + i.write_hton_u32 (0xdeadbeaf);
1.535 + ENSURE_WRITTEN_BYTES (buffer, 8, 0xbe, 0xaf, 0, 0, 0xde, 0xad, 0xbe, 0xaf);
1.536 + buffer.remove_at_start (5);
1.537 + ENSURE_WRITTEN_BYTES (buffer, 3, 0xad, 0xbe, 0xaf);
1.538 + // test remove end
1.539 + buffer = Buffer (5);
1.540 + ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
1.541 + buffer.remove_at_end (1);
1.542 + ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
1.543 + buffer.add_at_end (2);
1.544 + i = buffer.begin ();
1.545 + i.next (4);
1.546 + i.write_u8 (0xab);
1.547 + i.write_u8 (0xac);
1.548 + ENSURE_WRITTEN_BYTES (buffer, 6, 0, 0, 0, 0, 0xab, 0xac);
1.549 + buffer.remove_at_end (1);
1.550 + ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0xab);
1.551 + buffer.remove_at_end (3);
1.552 + ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
1.553 + buffer.add_at_end (6);
1.554 + i = buffer.begin ();
1.555 + i.next (2);
1.556 + i.write_u8 (0xac);
1.557 + i.write_u8 (0xad);
1.558 + i.write_u8 (0xae);
1.559 + i.write_u8 (0xaf);
1.560 + i.write_u8 (0xba);
1.561 + i.write_u8 (0xbb);
1.562 + ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
1.563 + buffer.add_at_start (3);
1.564 + i = buffer.begin ();
1.565 + i.write_u8 (0x30);
1.566 + i.write_u8 (0x31);
1.567 + i.write_u8 (0x32);
1.568 + ENSURE_WRITTEN_BYTES (buffer, 11, 0x30, 0x31, 0x32, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
1.569 + buffer.remove_at_end (9);
1.570 + ENSURE_WRITTEN_BYTES (buffer, 2, 0x30, 0x31);
1.571 + buffer = Buffer (3);
1.572 + buffer.add_at_end (2);
1.573 + i = buffer.begin ();
1.574 + i.next (3);
1.575 + i.write_hton_u16 (0xabcd);
1.576 + buffer.add_at_start (1);
1.577 + buffer.begin ().write_u8 (0x21);
1.578 + ENSURE_WRITTEN_BYTES (buffer, 6, 0x21, 0, 0, 0, 0xab, 0xcd);
1.579 + buffer.remove_at_end (8);
1.580 + if (buffer.get_size () != 0) {
1.581 + ok = false;
1.582 + }
1.583 +
1.584 +
1.585 +
1.586 +
1.587 + return ok;
1.588 +}
1.589 +
1.590 +
1.591 +
1.592 +static BufferTest g_buffer_test;
1.593 +
1.594 +}; // namespace yans
1.595 +
1.596 +#endif /* RUN_SELF_TESTS */
1.597 +
1.598 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/src/common/buffer.h Tue Aug 29 17:42:13 2006 +0200
2.3 @@ -0,0 +1,690 @@
2.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
2.5 +/*
2.6 + * Copyright (c) 2005,2006 INRIA
2.7 + * All rights reserved.
2.8 + *
2.9 + * This program is free software; you can redistribute it and/or modify
2.10 + * it under the terms of the GNU General Public License version 2 as
2.11 + * published by the Free Software Foundation;
2.12 + *
2.13 + * This program is distributed in the hope that it will be useful,
2.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.16 + * GNU General Public License for more details.
2.17 + *
2.18 + * You should have received a copy of the GNU General Public License
2.19 + * along with this program; if not, write to the Free Software
2.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.21 + *
2.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
2.23 + */
2.24 +#ifndef BUFFER_H
2.25 +#define BUFFER_H
2.26 +
2.27 +#include <stdint.h>
2.28 +#include <vector>
2.29 +
2.30 +namespace yans {
2.31 +
2.32 +/**
2.33 + * \brief automatically resized byte buffer
2.34 + *
2.35 + * This represents a buffer of bytes. Its size is
2.36 + * automatically adjusted to hold any data prepended
2.37 + * or appended by the user. Its implementation is optimized
2.38 + * to ensure that the number of buffer resizes is minimized,
2.39 + * by creating new Buffers of the maximum size ever used.
2.40 + * The correct maximum size is learned at runtime during use by
2.41 + * recording the maximum size of each packet.
2.42 + */
2.43 +class Buffer {
2.44 +public:
2.45 + /**
2.46 + * \brief iterator in a Buffer instance
2.47 + */
2.48 + class Iterator {
2.49 + public:
2.50 + inline Iterator ();
2.51 + /**
2.52 + * go forward by one byte
2.53 + */
2.54 + inline void next (void);
2.55 + /**
2.56 + * go backward by one byte
2.57 + */
2.58 + inline void prev (void);
2.59 + /**
2.60 + * \param delta number of bytes to go forward
2.61 + */
2.62 + inline void next (uint32_t delta);
2.63 + /**
2.64 + * \param delta number of bytes to go backward
2.65 + */
2.66 + inline void prev (uint32_t delta);
2.67 + /**
2.68 + * \param o the second iterator
2.69 + * \return number of bytes included between the two iterators
2.70 + *
2.71 + * This method works only if the two iterators point
2.72 + * to the same underlying buffer. Debug builds ensure
2.73 + * this with an assert.
2.74 + */
2.75 + inline int32_t get_distance_from (Iterator const &o) const;
2.76 +
2.77 + /**
2.78 + * \return true if this iterator points to the end of the byte array.
2.79 + * false otherwise.
2.80 + */
2.81 + inline bool is_end (void) const;
2.82 + /**
2.83 + * \return true if this iterator points to the start of the byte array.
2.84 + * false otherwise.
2.85 + */
2.86 + inline bool is_start (void) const;
2.87 +
2.88 + /**
2.89 + * \param data data to write in buffer
2.90 + *
2.91 + * Write the data in buffer and avance the iterator position
2.92 + * by one byte.
2.93 + */
2.94 + inline void write_u8 (uint8_t data);
2.95 + /**
2.96 + * \param data data to write in buffer
2.97 + * \param len number of times data must be written in buffer
2.98 + *
2.99 + * Write the data in buffer len times and avance the iterator position
2.100 + * by len byte.
2.101 + */
2.102 + inline void write_u8 (uint8_t data, uint32_t len);
2.103 + /**
2.104 + * \param data data to write in buffer
2.105 + *
2.106 + * Write the data in buffer and avance the iterator position
2.107 + * by two bytes. The format of the data written in the byte
2.108 + * buffer is non-portable. We only ensure that read_u16 will
2.109 + * return exactly what we wrote with write_u16 if the program
2.110 + * is run on the same machine.
2.111 + */
2.112 + inline void write_u16 (uint16_t data);
2.113 + /**
2.114 + * \param data data to write in buffer
2.115 + *
2.116 + * Write the data in buffer and avance the iterator position
2.117 + * by four bytes. The format of the data written in the byte
2.118 + * buffer is non-portable. We only ensure that read_u32 will
2.119 + * return exactly what we wrote with write_u32 if the program
2.120 + * is run on the same machine.
2.121 + */
2.122 + inline void write_u32 (uint32_t data);
2.123 + /**
2.124 + * \param data data to write in buffer
2.125 + *
2.126 + * Write the data in buffer and avance the iterator position
2.127 + * by eight bytes. The format of the data written in the byte
2.128 + * buffer is non-portable. We only ensure that read_u64 will
2.129 + * return exactly what we wrote with write_u64 if the program
2.130 + * is run on the same machine.
2.131 + */
2.132 + inline void write_u64 (uint64_t data);
2.133 + /**
2.134 + * \param data data to write in buffer
2.135 + *
2.136 + * Write the data in buffer and avance the iterator position
2.137 + * by two bytes. The data is written in network order and the
2.138 + * input data is expected to be in host order.
2.139 + */
2.140 + inline void write_hton_u16 (uint16_t data);
2.141 + /**
2.142 + * \param data data to write in buffer
2.143 + *
2.144 + * Write the data in buffer and avance the iterator position
2.145 + * by four bytes. The data is written in network order and the
2.146 + * input data is expected to be in host order.
2.147 + */
2.148 + inline void write_hton_u32 (uint32_t data);
2.149 + /**
2.150 + * \param data data to write in buffer
2.151 + *
2.152 + * Write the data in buffer and avance the iterator position
2.153 + * by eight bytes. The data is written in network order and the
2.154 + * input data is expected to be in host order.
2.155 + */
2.156 + inline void write_hton_u64 (uint64_t data);
2.157 + /**
2.158 + * \param buffer a byte buffer to copy in the internal buffer.
2.159 + * \param size number of bytes to copy.
2.160 + *
2.161 + * Write the data in buffer and avance the iterator position
2.162 + * by size bytes.
2.163 + */
2.164 + inline void write (uint8_t const*buffer, uint16_t size);
2.165 + /**
2.166 + * \param start the start of the data to copy
2.167 + * \param end the end of the data to copy
2.168 + *
2.169 + * Write the data delimited by start and end in internal buffer
2.170 + * and avance the iterator position by the number of bytes
2.171 + * copied.
2.172 + * The input interators _must_ not point to the same Buffer as
2.173 + * we do to avoid overlapping copies. This is enforced
2.174 + * in debug builds by asserts.
2.175 + */
2.176 + inline void write (Iterator start, Iterator end);
2.177 +
2.178 + /**
2.179 + * \return the byte read in the buffer.
2.180 + *
2.181 + * Read data and advance the Iterator by the number of bytes
2.182 + * read.
2.183 + */
2.184 + inline uint8_t read_u8 (void);
2.185 + /**
2.186 + * \return the two bytes read in the buffer.
2.187 + *
2.188 + * Read data and advance the Iterator by the number of bytes
2.189 + * read.
2.190 + * The data is read in the format written by write_u16.
2.191 + */
2.192 + inline uint16_t read_u16 (void);
2.193 + /**
2.194 + * \return the four bytes read in the buffer.
2.195 + *
2.196 + * Read data and advance the Iterator by the number of bytes
2.197 + * read.
2.198 + * The data is read in the format written by write_u32.
2.199 + */
2.200 + inline uint32_t read_u32 (void);
2.201 + /**
2.202 + * \return the eight bytes read in the buffer.
2.203 + *
2.204 + * Read data and advance the Iterator by the number of bytes
2.205 + * read.
2.206 + * The data is read in the format written by write_u64.
2.207 + */
2.208 + inline uint64_t read_u64 (void);
2.209 + /**
2.210 + * \return the two bytes read in the buffer.
2.211 + *
2.212 + * Read data and advance the Iterator by the number of bytes
2.213 + * read.
2.214 + * The data is read in network format and return in host format.
2.215 + */
2.216 + inline uint16_t read_ntoh_u16 (void);
2.217 + /**
2.218 + * \return the four bytes read in the buffer.
2.219 + *
2.220 + * Read data and advance the Iterator by the number of bytes
2.221 + * read.
2.222 + * The data is read in network format and return in host format.
2.223 + */
2.224 + inline uint32_t read_ntoh_u32 (void);
2.225 + /**
2.226 + * \return the eight bytes read in the buffer.
2.227 + *
2.228 + * Read data and advance the Iterator by the number of bytes
2.229 + * read.
2.230 + * The data is read in network format and return in host format.
2.231 + */
2.232 + inline uint64_t read_ntoh_u64 (void);
2.233 + /**
2.234 + * \param buffer buffer to copy data into
2.235 + * \param size number of bytes to copy
2.236 + *
2.237 + * Copy size bytes of data from the internal buffer to the
2.238 + * input buffer and avance the Iterator by the number of
2.239 + * bytes read.
2.240 + */
2.241 + inline void read (uint8_t *buffer, uint16_t size);
2.242 + private:
2.243 + friend class Buffer;
2.244 + inline Iterator (Buffer const*buffer, uint32_t m_current);
2.245 + inline uint32_t get_index (uint32_t n);
2.246 + uint32_t m_zero_start;
2.247 + uint32_t m_zero_end;
2.248 + uint32_t m_data_end;
2.249 + uint32_t m_current;
2.250 + uint8_t *m_data;
2.251 + };
2.252 +
2.253 + /**
2.254 + * \return the number of bytes stored in this buffer.
2.255 + */
2.256 + inline uint32_t get_size (void) const;
2.257 +
2.258 + /**
2.259 + * \return a pointer to the start of the internal
2.260 + * byte buffer.
2.261 + *
2.262 + * The returned pointer points to an area of
2.263 + * memory which is yans::Buffer::get_size () bytes big.
2.264 + * Please, try to never ever use this method. It is really
2.265 + * evil and is present only for a few specific uses.
2.266 + */
2.267 + uint8_t *peek_data (void) const;
2.268 +
2.269 + /**
2.270 + * \param start size to reserve
2.271 + *
2.272 + * Add bytes at the start of the Buffer. The
2.273 + * content of these bytes is undefined but debugging
2.274 + * builds initialize them to 0x33.
2.275 + * Any call to this method invalidates any Iterator
2.276 + * pointing to this Buffer.
2.277 + */
2.278 + void add_at_start (uint32_t start);
2.279 + /**
2.280 + * \param end size to reserve
2.281 + *
2.282 + * Add bytes at the end of the Buffer. The
2.283 + * content of these bytes is undefined but debugging
2.284 + * builds initialize them to 0x33.
2.285 + * Any call to this method invalidates any Iterator
2.286 + * pointing to this Buffer.
2.287 + */
2.288 + void add_at_end (uint32_t end);
2.289 + /**
2.290 + * \param start size to remove
2.291 + *
2.292 + * Remove bytes at the start of the Buffer.
2.293 + * Any call to this method invalidates any Iterator
2.294 + * pointing to this Buffer.
2.295 + */
2.296 + void remove_at_start (uint32_t start);
2.297 + /**
2.298 + * \param end size to remove
2.299 + *
2.300 + * Remove bytes at the end of the Buffer.
2.301 + * Any call to this method invalidates any Iterator
2.302 + * pointing to this Buffer.
2.303 + */
2.304 + void remove_at_end (uint32_t end);
2.305 +
2.306 + /**
2.307 + * \param start offset from start of packet
2.308 + * \param length
2.309 + *
2.310 + * \return a fragment of size length starting at offset
2.311 + * start.
2.312 + */
2.313 + Buffer create_fragment (uint32_t start, uint32_t length) const;
2.314 +
2.315 + /**
2.316 + * \return an Iterator which points to the
2.317 + * start of this Buffer.
2.318 + */
2.319 + inline Buffer::Iterator begin (void) const;
2.320 + /**
2.321 + * \return an Iterator which points to the
2.322 + * end of this Buffer.
2.323 + */
2.324 + inline Buffer::Iterator end (void) const;
2.325 +
2.326 + inline Buffer (Buffer const &o);
2.327 + inline Buffer &operator = (Buffer const &o);
2.328 + inline Buffer ();
2.329 + inline Buffer (uint32_t data_size);
2.330 + inline ~Buffer ();
2.331 +private:
2.332 + struct BufferData {
2.333 + uint32_t m_count;
2.334 + uint32_t m_size;
2.335 + uint32_t m_initial_start;
2.336 + uint32_t m_dirty_start;
2.337 + uint32_t m_dirty_size;
2.338 + uint8_t m_data[1];
2.339 + };
2.340 + typedef std::vector<struct Buffer::BufferData*> BufferDataList;
2.341 +
2.342 + inline uint8_t *get_start (void) const;
2.343 + void transform_into_real_buffer (void) const;
2.344 + static void recycle (struct Buffer::BufferData *data);
2.345 + static struct Buffer::BufferData *create (void);
2.346 + static struct Buffer::BufferData *allocate (uint32_t size, uint32_t start);
2.347 + static void deallocate (struct Buffer::BufferData *data);
2.348 +
2.349 + static BufferDataList m_free_list;
2.350 + static uint32_t m_max_total_add_start;
2.351 + static uint32_t m_max_total_add_end;
2.352 +
2.353 + struct BufferData *m_data;
2.354 + uint32_t m_zero_area_size;
2.355 + uint32_t m_start;
2.356 + uint32_t m_size;
2.357 +};
2.358 +
2.359 +}; // namespace yans
2.360 +
2.361 +#include <cassert>
2.362 +
2.363 +namespace yans {
2.364 +
2.365 +Buffer::Buffer ()
2.366 + : m_data (Buffer::create ()),
2.367 + m_zero_area_size (0),
2.368 + m_start (m_max_total_add_start),
2.369 + m_size (0)
2.370 +{
2.371 + if (m_start > m_data->m_size) {
2.372 + m_start = 0;
2.373 + }
2.374 + assert (m_start <= m_data->m_size);
2.375 +}
2.376 +
2.377 +Buffer::Buffer (uint32_t data_size)
2.378 + : m_data (Buffer::create ()),
2.379 + m_zero_area_size (data_size),
2.380 + m_start (m_max_total_add_start),
2.381 + m_size (0)
2.382 +{
2.383 + if (m_start > m_data->m_size) {
2.384 + m_start = 0;
2.385 + }
2.386 + assert (m_start <= m_data->m_size);
2.387 +}
2.388 +
2.389 +
2.390 +Buffer::Buffer (Buffer const&o)
2.391 + : m_data (o.m_data),
2.392 + m_zero_area_size (o.m_zero_area_size),
2.393 + m_start (o.m_start),
2.394 + m_size (o.m_size)
2.395 +{
2.396 + m_data->m_count++;
2.397 + assert (m_start <= m_data->m_size);
2.398 +}
2.399 +
2.400 +Buffer &
2.401 +Buffer::operator = (Buffer const&o)
2.402 +{
2.403 + if (m_data != o.m_data) {
2.404 + // not assignment to self.
2.405 + m_data->m_count--;
2.406 + if (m_data->m_count == 0) {
2.407 + recycle (m_data);
2.408 + }
2.409 + m_data = o.m_data;
2.410 + m_data->m_count++;
2.411 + }
2.412 + m_zero_area_size = o.m_zero_area_size;
2.413 + m_start = o.m_start;
2.414 + m_size = o.m_size;
2.415 + assert (m_start <= m_data->m_size);
2.416 + return *this;
2.417 +}
2.418 +
2.419 +Buffer::~Buffer ()
2.420 +{
2.421 + m_data->m_count--;
2.422 + if (m_data->m_count == 0) {
2.423 + recycle (m_data);
2.424 + }
2.425 +}
2.426 +
2.427 +
2.428 +uint8_t *
2.429 +Buffer::get_start (void) const
2.430 +{
2.431 + return m_data->m_data + m_start;
2.432 +}
2.433 +
2.434 +uint32_t
2.435 +Buffer::get_size (void) const
2.436 +{
2.437 + return m_size + m_zero_area_size;
2.438 +}
2.439 +
2.440 +Buffer::Iterator
2.441 +Buffer::begin (void) const
2.442 +{
2.443 + return Buffer::Iterator (this, 0);
2.444 +}
2.445 +Buffer::Iterator
2.446 +Buffer::end (void) const
2.447 +{
2.448 + return Buffer::Iterator (this, get_size ());
2.449 +}
2.450 +
2.451 +
2.452 +Buffer::Iterator::Iterator ()
2.453 + : m_zero_start (0),
2.454 + m_zero_end (0),
2.455 + m_data_end (0),
2.456 + m_current (0),
2.457 + m_data (0)
2.458 +{}
2.459 +Buffer::Iterator::Iterator (Buffer const*buffer, uint32_t current)
2.460 + : m_zero_start (buffer->m_data->m_initial_start-buffer->m_start),
2.461 + m_zero_end (m_zero_start+buffer->m_zero_area_size),
2.462 + m_data_end (buffer->get_size ()),
2.463 + m_current (current),
2.464 + m_data (buffer->m_data->m_data+buffer->m_start)
2.465 +{}
2.466 +
2.467 +void
2.468 +Buffer::Iterator::next (void)
2.469 +{
2.470 + assert (m_current + 1 <= m_data_end);
2.471 + m_current++;
2.472 +}
2.473 +void
2.474 +Buffer::Iterator::prev (void)
2.475 +{
2.476 + assert (m_current >= 1);
2.477 + m_current--;
2.478 +}
2.479 +void
2.480 +Buffer::Iterator::next (uint32_t delta)
2.481 +{
2.482 + assert (m_current + delta <= m_data_end);
2.483 + m_current += delta;
2.484 +}
2.485 +void
2.486 +Buffer::Iterator::prev (uint32_t delta)
2.487 +{
2.488 + assert (m_current >= delta);
2.489 + m_current -= delta;
2.490 +}
2.491 +int32_t
2.492 +Buffer::Iterator::get_distance_from (Iterator const &o) const
2.493 +{
2.494 + assert (m_data == o.m_data);
2.495 + int32_t start = m_current;
2.496 + int32_t end = o.m_current;
2.497 + return end - start;
2.498 +}
2.499 +
2.500 +bool
2.501 +Buffer::Iterator::is_end (void) const
2.502 +{
2.503 + return m_current == m_data_end;
2.504 +}
2.505 +bool
2.506 +Buffer::Iterator::is_start (void) const
2.507 +{
2.508 + return m_current == 0;
2.509 +}
2.510 +
2.511 +uint32_t
2.512 +Buffer::Iterator::get_index (uint32_t n)
2.513 +{
2.514 + assert (
2.515 + (m_current + n <= m_data_end) &&
2.516 + ((m_current + n <= m_zero_start) ||
2.517 + (m_current >= m_zero_end))
2.518 + );
2.519 + uint32_t index;
2.520 + if (m_current < m_zero_start) {
2.521 + index = m_current;
2.522 + } else {
2.523 + index = m_current - (m_zero_end-m_zero_start);
2.524 + }
2.525 + return index;
2.526 +}
2.527 +
2.528 +
2.529 +void
2.530 +Buffer::Iterator::write (Iterator start, Iterator end)
2.531 +{
2.532 + assert (start.m_data == end.m_data);
2.533 + assert (start.m_current <= end.m_current);
2.534 + assert (m_data != start.m_data);
2.535 + uint32_t size = end.m_current - start.m_current;
2.536 + uint8_t *src = start.m_data + start.get_index (size);
2.537 + uint8_t *dest = m_data + get_index (size);
2.538 + memcpy (dest, src, size);
2.539 + m_current += size;
2.540 +}
2.541 +
2.542 +void
2.543 +Buffer::Iterator::write_u8 (uint8_t data, uint32_t len)
2.544 +{
2.545 + uint8_t *current = m_data + get_index (len);
2.546 + memset (current, data, len);
2.547 + m_current += len;
2.548 +}
2.549 +void
2.550 +Buffer::Iterator::write_u8 (uint8_t data)
2.551 +{
2.552 + m_data[get_index (1)] = data;
2.553 + m_current++;
2.554 +}
2.555 +void
2.556 +Buffer::Iterator::write_u16 (uint16_t data)
2.557 +{
2.558 + uint16_t *buffer = (uint16_t *)(m_data + get_index (2));
2.559 + *buffer = data;
2.560 + m_current += 2;
2.561 +}
2.562 +void
2.563 +Buffer::Iterator::write_u32 (uint32_t data)
2.564 +{
2.565 + uint32_t *buffer = (uint32_t *)(m_data + get_index (4));
2.566 + *buffer = data;
2.567 + m_current += 4;
2.568 +}
2.569 +void
2.570 +Buffer::Iterator::write_u64 (uint64_t data)
2.571 +{
2.572 + uint64_t *buffer = (uint64_t *)(m_data + get_index (8));
2.573 + *buffer = data;
2.574 + m_current += 8;
2.575 +}
2.576 +void
2.577 +Buffer::Iterator::write_hton_u16 (uint16_t data)
2.578 +{
2.579 + uint8_t *current = m_data + get_index (2);
2.580 + *(current+0) = (data >> 8) & 0xff;
2.581 + *(current+1) = (data >> 0) & 0xff;
2.582 + m_current += 2;
2.583 +}
2.584 +void
2.585 +Buffer::Iterator::write_hton_u32 (uint32_t data)
2.586 +{
2.587 + uint8_t *current = m_data + get_index (4);
2.588 + *(current+0) = (data >> 24) & 0xff;
2.589 + *(current+1) = (data >> 16) & 0xff;
2.590 + *(current+2) = (data >> 8) & 0xff;
2.591 + *(current+3) = (data >> 0) & 0xff;
2.592 + m_current += 4;
2.593 +}
2.594 +void
2.595 +Buffer::Iterator::write_hton_u64 (uint64_t data)
2.596 +{
2.597 + uint8_t *current = m_data + get_index (8);
2.598 + *(current+0) = (data >> 56) & 0xff;
2.599 + *(current+1) = (data >> 48) & 0xff;
2.600 + *(current+2) = (data >> 40) & 0xff;
2.601 + *(current+3) = (data >> 32) & 0xff;
2.602 + *(current+4) = (data >> 24) & 0xff;
2.603 + *(current+5) = (data >> 16) & 0xff;
2.604 + *(current+6) = (data >> 8) & 0xff;
2.605 + *(current+7) = (data >> 0) & 0xff;
2.606 + m_current += 8;
2.607 +}
2.608 +void
2.609 +Buffer::Iterator::write (uint8_t const*buffer, uint16_t size)
2.610 +{
2.611 + uint8_t *current = m_data + get_index (size);
2.612 + memcpy (current, buffer, size);
2.613 + m_current += size;
2.614 +}
2.615 +
2.616 +uint8_t
2.617 +Buffer::Iterator::read_u8 (void)
2.618 +{
2.619 + uint8_t data = m_data[get_index(1)];
2.620 + m_current++;
2.621 + return data;
2.622 +}
2.623 +uint16_t
2.624 +Buffer::Iterator::read_u16 (void)
2.625 +{
2.626 + uint16_t *buffer = reinterpret_cast<uint16_t *>(m_data + get_index (2));
2.627 + m_current += 2;
2.628 + return *buffer;
2.629 +}
2.630 +uint32_t
2.631 +Buffer::Iterator::read_u32 (void)
2.632 +{
2.633 + uint32_t *buffer = reinterpret_cast<uint32_t *>(m_data + get_index (4));
2.634 + m_current += 4;
2.635 + return *buffer;
2.636 +}
2.637 +uint64_t
2.638 +Buffer::Iterator::read_u64 (void)
2.639 +{
2.640 + uint64_t *buffer = reinterpret_cast<uint64_t *>(m_data + get_index (8));
2.641 + m_current += 8;
2.642 + return *buffer;
2.643 +}
2.644 +uint16_t
2.645 +Buffer::Iterator::read_ntoh_u16 (void)
2.646 +{
2.647 + uint8_t *current = m_data + get_index (2);
2.648 + uint16_t retval = 0;
2.649 + retval |= static_cast<uint16_t> (current[0]) << 8;
2.650 + retval |= static_cast<uint16_t> (current[1]) << 0;
2.651 + m_current += 2;
2.652 + return retval;
2.653 +}
2.654 +uint32_t
2.655 +Buffer::Iterator::read_ntoh_u32 (void)
2.656 +{
2.657 + uint8_t *current = m_data + get_index (4);
2.658 + uint32_t retval = 0;
2.659 + retval |= static_cast<uint32_t> (current[0]) << 24;
2.660 + retval |= static_cast<uint32_t> (current[1]) << 16;
2.661 + retval |= static_cast<uint32_t> (current[2]) << 8;
2.662 + retval |= static_cast<uint32_t> (current[3]) << 0;
2.663 + m_current += 4;
2.664 + return retval;
2.665 +}
2.666 +uint64_t
2.667 +Buffer::Iterator::read_ntoh_u64 (void)
2.668 +{
2.669 + uint8_t *current = m_data + get_index (8);
2.670 + uint64_t retval = 0;
2.671 + retval |= static_cast<uint64_t> (current[0]) << 56;
2.672 + retval |= static_cast<uint64_t> (current[1]) << 48;
2.673 + retval |= static_cast<uint64_t> (current[2]) << 40;
2.674 + retval |= static_cast<uint64_t> (current[3]) << 32;
2.675 + retval |= static_cast<uint64_t> (current[4]) << 24;
2.676 + retval |= static_cast<uint64_t> (current[5]) << 16;
2.677 + retval |= static_cast<uint64_t> (current[6]) << 8;
2.678 + retval |= static_cast<uint64_t> (current[7]) << 0;
2.679 + m_current += 8;
2.680 + return retval;
2.681 +}
2.682 +void
2.683 +Buffer::Iterator::read (uint8_t *buffer, uint16_t size)
2.684 +{
2.685 + uint8_t *current = m_data + get_index (size);
2.686 + memcpy (buffer, current, size);
2.687 + m_current += size;
2.688 +}
2.689 +
2.690 +}; // namespace yans
2.691 +
2.692 +
2.693 +#endif /* BUFFER_H */
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/common/callback-logger.h Tue Aug 29 17:42:13 2006 +0200
3.3 @@ -0,0 +1,84 @@
3.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
3.5 +/*
3.6 + * Copyright (c) 2005,2006 INRIA
3.7 + * All rights reserved.
3.8 + *
3.9 + * This program is free software; you can redistribute it and/or modify
3.10 + * it under the terms of the GNU General Public License version 2 as
3.11 + * published by the Free Software Foundation;
3.12 + *
3.13 + * This program is distributed in the hope that it will be useful,
3.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.16 + * GNU General Public License for more details.
3.17 + *
3.18 + * You should have received a copy of the GNU General Public License
3.19 + * along with this program; if not, write to the Free Software
3.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3.21 + *
3.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
3.23 + */
3.24 +
3.25 +#ifndef CALLBACK_LOGGER_H
3.26 +#define CALLBACK_LOGGER_H
3.27 +
3.28 +#include "yans/callback.h"
3.29 +
3.30 +namespace yans {
3.31 +
3.32 +class CallbackLoggerBase {};
3.33 +
3.34 +/**
3.35 + * \brief log arbitrary number of parameters to a matching yans:Callback
3.36 + *
3.37 + * Whenever operator () is invoked on this class, the call and its arguments
3.38 + * are forwarded to the internal matching yans::Callback.
3.39 + */
3.40 +template<typename T1 = empty, typename T2 = empty,
3.41 + typename T3 = empty, typename T4 = empty,
3.42 + typename T5 = empty>
3.43 +class CallbackLogger : public CallbackLoggerBase{
3.44 +public:
3.45 + CallbackLogger ()
3.46 + : m_callback () {}
3.47 + void set_callback (Callback<void,T1,T2,T3,T4,T5> callback) {
3.48 + m_callback = callback;
3.49 + }
3.50 + void operator() (void) {
3.51 + if (!m_callback.is_null ()) {
3.52 + m_callback ();
3.53 + }
3.54 + }
3.55 + void operator() (T1 a1) {
3.56 + if (!m_callback.is_null ()) {
3.57 + m_callback (a1);
3.58 + }
3.59 + }
3.60 + void operator() (T1 a1, T2 a2) {
3.61 + if (!m_callback.is_null ()) {
3.62 + m_callback (a1,a2);
3.63 + }
3.64 + }
3.65 + void operator() (T1 a1, T2 a2, T3 a3) {
3.66 + if (!m_callback.is_null ()) {
3.67 + m_callback (a1,a2,a3);
3.68 + }
3.69 + }
3.70 + void operator() (T1 a1, T2 a2, T3 a3, T4 a4) {
3.71 + if (!m_callback.is_null ()) {
3.72 + m_callback (a1,a2,a3,a4);
3.73 + }
3.74 + }
3.75 + void operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) {
3.76 + if (!m_callback.is_null ()) {
3.77 + m_callback (a1,a2,a3,a4,a5);
3.78 + }
3.79 + }
3.80 +
3.81 +private:
3.82 + Callback<void,T1,T2,T3,T4,T5> m_callback;
3.83 +};
3.84 +
3.85 +}; // namespace yans
3.86 +
3.87 +#endif /* CALLBACK_LOGGER_H */
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/common/chunk-constant-data.cc Tue Aug 29 17:42:13 2006 +0200
4.3 @@ -0,0 +1,63 @@
4.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
4.5 +/*
4.6 + * Copyright (c) 2005 INRIA
4.7 + * All rights reserved.
4.8 + *
4.9 + * This program is free software; you can redistribute it and/or modify
4.10 + * it under the terms of the GNU General Public License version 2 as
4.11 + * published by the Free Software Foundation;
4.12 + *
4.13 + * This program is distributed in the hope that it will be useful,
4.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.16 + * GNU General Public License for more details.
4.17 + *
4.18 + * You should have received a copy of the GNU General Public License
4.19 + * along with this program; if not, write to the Free Software
4.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4.21 + *
4.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
4.23 + */
4.24 +
4.25 +#include "chunk-constant-data.h"
4.26 +
4.27 +namespace yans {
4.28 +
4.29 +ChunkConstantData::ChunkConstantData (uint32_t len, uint8_t data)
4.30 + : m_len (len), m_data (data)
4.31 +{}
4.32 +
4.33 +ChunkConstantData::~ChunkConstantData ()
4.34 +{}
4.35 +
4.36 +
4.37 +void
4.38 +ChunkConstantData::print (std::ostream *os) const
4.39 +{
4.40 + *os << "(constant data)"
4.41 + << " len=" << m_len
4.42 + << ", data=" << m_data;
4.43 +}
4.44 +
4.45 +void
4.46 +ChunkConstantData::add_to (Buffer *buffer) const
4.47 +{
4.48 + buffer->add_at_start (m_len);
4.49 +#ifndef NDEBUG
4.50 + buffer->begin ().write_u8 (m_data, m_len);
4.51 +#endif
4.52 +}
4.53 +void
4.54 +ChunkConstantData::peek_from (Buffer const *buffer)
4.55 +{
4.56 + m_len = buffer->get_size ();
4.57 + m_data = buffer->begin ().read_u8 ();
4.58 +}
4.59 +void
4.60 +ChunkConstantData::remove_from (Buffer *buffer)
4.61 +{
4.62 + buffer->remove_at_start (m_len);
4.63 +}
4.64 +
4.65 +
4.66 +}; // namespace yans
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/src/common/chunk-constant-data.h Tue Aug 29 17:42:13 2006 +0200
5.3 @@ -0,0 +1,47 @@
5.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
5.5 +/*
5.6 + * Copyright (c) 2005 INRIA
5.7 + * All rights reserved.
5.8 + *
5.9 + * This program is free software; you can redistribute it and/or modify
5.10 + * it under the terms of the GNU General Public License version 2 as
5.11 + * published by the Free Software Foundation;
5.12 + *
5.13 + * This program is distributed in the hope that it will be useful,
5.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.16 + * GNU General Public License for more details.
5.17 + *
5.18 + * You should have received a copy of the GNU General Public License
5.19 + * along with this program; if not, write to the Free Software
5.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5.21 + *
5.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
5.23 + */
5.24 +
5.25 +#ifndef CHUNK_CONSTANT_DATA_H
5.26 +#define CHUNK_CONSTANT_DATA_H
5.27 +
5.28 +#include "chunk.h"
5.29 +#include <stdint.h>
5.30 +
5.31 +namespace yans {
5.32 +
5.33 +
5.34 +class ChunkConstantData : public Chunk {
5.35 +public:
5.36 + ChunkConstantData (uint32_t len, uint8_t data);
5.37 + ~ChunkConstantData ();
5.38 +
5.39 +private:
5.40 + virtual void print (std::ostream *os) const;
5.41 + virtual void add_to (Buffer *buffer) const;
5.42 + virtual void peek_from (Buffer const *buffer);
5.43 + virtual void remove_from (Buffer *buffer);
5.44 + uint32_t m_len;
5.45 + uint8_t m_data;
5.46 +};
5.47 +
5.48 +}; // namespace yans
5.49 +
5.50 +#endif /* CHUNK_CONSTANT_DATA_H */
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/src/common/chunk-llc-snap.cc Tue Aug 29 17:42:13 2006 +0200
6.3 @@ -0,0 +1,94 @@
6.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
6.5 +/*
6.6 + * Copyright (c) 2005 INRIA
6.7 + * All rights reserved.
6.8 + *
6.9 + * This program is free software; you can redistribute it and/or modify
6.10 + * it under the terms of the GNU General Public License version 2 as
6.11 + * published by the Free Software Foundation;
6.12 + *
6.13 + * This program is distributed in the hope that it will be useful,
6.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.16 + * GNU General Public License for more details.
6.17 + *
6.18 + * You should have received a copy of the GNU General Public License
6.19 + * along with this program; if not, write to the Free Software
6.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6.21 + *
6.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
6.23 + */
6.24 +
6.25 +#include "chunk-llc-snap.h"
6.26 +#include <cassert>
6.27 +
6.28 +#define noTRACE_CHUNK_LLC_SNAP 1
6.29 +
6.30 +#ifdef TRACE_CHUNK_LLC_SNAP
6.31 +#include <iostream>
6.32 +#include "simulator.h"
6.33 +# define TRACE(x) \
6.34 +std::cout << "CHUNK LLCSNAP TRACE " << Simulator::now_s () << " " << x << std::endl;
6.35 +#else /* TRACE_CHUNK_LLC_SNAP */
6.36 +# define TRACE(format,...)
6.37 +#endif /* TRACE_CHUNK_LLC_SNAP */
6.38 +
6.39 +
6.40 +namespace yans {
6.41 +
6.42 +ChunkLlcSnap::ChunkLlcSnap ()
6.43 +{}
6.44 +
6.45 +ChunkLlcSnap::~ChunkLlcSnap ()
6.46 +{}
6.47 +void
6.48 +ChunkLlcSnap::set_type (enum Type type)
6.49 +{
6.50 + m_ether_type = type;
6.51 +}
6.52 +enum ChunkLlcSnap::Type
6.53 +ChunkLlcSnap::get_type (void)
6.54 +{
6.55 + return (enum ChunkLlcSnap::Type) m_ether_type;
6.56 +}
6.57 +
6.58 +uint32_t
6.59 +ChunkLlcSnap::get_size (void) const
6.60 +{
6.61 + return 1 + 1 + 1 + 3 + 2;
6.62 +}
6.63 +void
6.64 +ChunkLlcSnap::print (std::ostream *os) const
6.65 +{
6.66 + *os << "(mac)"
6.67 + << " EtherType: ";
6.68 + os->setf (std::ios::hex, std::ios::basefield);
6.69 + *os << m_ether_type;
6.70 + os->setf (std::ios::dec, std::ios::basefield);
6.71 +}
6.72 +
6.73 +void
6.74 +ChunkLlcSnap::add_to (Buffer *buffer) const
6.75 +{
6.76 + buffer->add_at_start (get_size ());
6.77 + Buffer::Iterator i = buffer->begin ();
6.78 + uint8_t buf[] = {0xaa, 0xaa, 0x03, 0, 0, 0};
6.79 + i.write (buf, 6);
6.80 + i.write_hton_u16 (m_ether_type);
6.81 +}
6.82 +void
6.83 +ChunkLlcSnap::peek_from (Buffer const *buffer)
6.84 +{
6.85 + Buffer::Iterator i = buffer->begin ();
6.86 + i.next (5+1);
6.87 + m_ether_type = i.read_ntoh_u16 ();
6.88 +}
6.89 +void
6.90 +ChunkLlcSnap::remove_from (Buffer *buffer)
6.91 +{
6.92 + buffer->remove_at_start (get_size ());
6.93 +}
6.94 +
6.95 +
6.96 +
6.97 +}; // namespace yans
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/common/chunk-llc-snap.h Tue Aug 29 17:42:13 2006 +0200
7.3 @@ -0,0 +1,55 @@
7.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
7.5 +/*
7.6 + * Copyright (c) 2005 INRIA
7.7 + * All rights reserved.
7.8 + *
7.9 + * This program is free software; you can redistribute it and/or modify
7.10 + * it under the terms of the GNU General Public License version 2 as
7.11 + * published by the Free Software Foundation;
7.12 + *
7.13 + * This program is distributed in the hope that it will be useful,
7.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.16 + * GNU General Public License for more details.
7.17 + *
7.18 + * You should have received a copy of the GNU General Public License
7.19 + * along with this program; if not, write to the Free Software
7.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7.21 + *
7.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7.23 + */
7.24 +
7.25 +#ifndef CHUNK_LLC_SNAP_H
7.26 +#define CHUNK_LLC_SNAP_H
7.27 +
7.28 +#include "chunk.h"
7.29 +#include <stdint.h>
7.30 +
7.31 +namespace yans {
7.32 +
7.33 +class ChunkLlcSnap : public Chunk {
7.34 + public:
7.35 + ChunkLlcSnap ();
7.36 + virtual ~ChunkLlcSnap ();
7.37 +
7.38 + enum Type {
7.39 + TYPE_IPV4 = 0x0800,
7.40 + TYPE_ARP = 0x0806
7.41 + };
7.42 +
7.43 + void set_type (enum Type type);
7.44 + enum Type get_type (void);
7.45 +
7.46 + uint32_t get_size (void) const;
7.47 +
7.48 +private:
7.49 + virtual void print (std::ostream *os) const;
7.50 + virtual void add_to (Buffer *buffer) const;
7.51 + virtual void peek_from (Buffer const *buffer);
7.52 + virtual void remove_from (Buffer *buffer);
7.53 + uint16_t m_ether_type;
7.54 +};
7.55 +
7.56 +}; // namespace yans
7.57 +
7.58 +#endif /* CHUNK_LLC_SNAP_H */
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/src/common/chunk-utils.cc Tue Aug 29 17:42:13 2006 +0200
8.3 @@ -0,0 +1,49 @@
8.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
8.5 +/*
8.6 + * Copyright (c) 2006 INRIA
8.7 + * All rights reserved.
8.8 + *
8.9 + * This program is free software; you can redistribute it and/or modify
8.10 + * it under the terms of the GNU General Public License version 2 as
8.11 + * published by the Free Software Foundation;
8.12 + *
8.13 + * This program is distributed in the hope that it will be useful,
8.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.16 + * GNU General Public License for more details.
8.17 + *
8.18 + * You should have received a copy of the GNU General Public License
8.19 + * along with this program; if not, write to the Free Software
8.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
8.21 + *
8.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
8.23 + */
8.24 +#include "chunk-utils.h"
8.25 +
8.26 +namespace yans {
8.27 +
8.28 +void write_to (Buffer::Iterator &i, Ipv4Address ad)
8.29 +{
8.30 + i.write_hton_u32 (ad.get_host_order ());
8.31 +}
8.32 +void write_to (Buffer::Iterator &i, MacAddress ad)
8.33 +{
8.34 + uint8_t mac[6];
8.35 + ad.peek (mac);
8.36 + i.write (mac, 6);
8.37 +}
8.38 +
8.39 +void read_from (Buffer::Iterator &i, Ipv4Address &ad)
8.40 +{
8.41 + ad.set_host_order (i.read_ntoh_u32 ());
8.42 +}
8.43 +void read_from (Buffer::Iterator &i, MacAddress &ad)
8.44 +{
8.45 + uint8_t mac[6];
8.46 + i.read (mac, 6);
8.47 + ad.set (mac);
8.48 +}
8.49 +
8.50 +
8.51 +
8.52 +}; // namespace yans
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/common/chunk-utils.h Tue Aug 29 17:42:13 2006 +0200
9.3 @@ -0,0 +1,38 @@
9.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
9.5 +/*
9.6 + * Copyright (c) 2006 INRIA
9.7 + * All rights reserved.
9.8 + *
9.9 + * This program is free software; you can redistribute it and/or modify
9.10 + * it under the terms of the GNU General Public License version 2 as
9.11 + * published by the Free Software Foundation;
9.12 + *
9.13 + * This program is distributed in the hope that it will be useful,
9.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.16 + * GNU General Public License for more details.
9.17 + *
9.18 + * You should have received a copy of the GNU General Public License
9.19 + * along with this program; if not, write to the Free Software
9.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9.21 + *
9.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
9.23 + */
9.24 +#ifndef CHUNK_UTILS_H
9.25 +#define CHUNK_UTILS_H
9.26 +
9.27 +#include "buffer.h"
9.28 +#include "ipv4-address.h"
9.29 +#include "mac-address.h"
9.30 +
9.31 +namespace yans {
9.32 +
9.33 +void write_to (Buffer::Iterator &i, Ipv4Address ad);
9.34 +void write_to (Buffer::Iterator &i, MacAddress ad);
9.35 +
9.36 +void read_from (Buffer::Iterator &i, Ipv4Address &ad);
9.37 +void read_from (Buffer::Iterator &i, MacAddress &ad);
9.38 +
9.39 +};
9.40 +
9.41 +#endif /* CHUNK_UTILS_H */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/src/common/chunk.cc Tue Aug 29 17:42:13 2006 +0200
10.3 @@ -0,0 +1,65 @@
10.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
10.5 +/*
10.6 + * Copyright (c) 2005 INRIA
10.7 + * All rights reserved.
10.8 + *
10.9 + * This program is free software; you can redistribute it and/or modify
10.10 + * it under the terms of the GNU General Public License version 2 as
10.11 + * published by the Free Software Foundation;
10.12 + *
10.13 + * This program is distributed in the hope that it will be useful,
10.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.16 + * GNU General Public License for more details.
10.17 + *
10.18 + * You should have received a copy of the GNU General Public License
10.19 + * along with this program; if not, write to the Free Software
10.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10.21 + *
10.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
10.23 + */
10.24 +
10.25 +#include "chunk.h"
10.26 +#include <cassert>
10.27 +
10.28 +namespace yans {
10.29 +
10.30 +Chunk::Chunk ()
10.31 + : m_must_peek_before_remove (false) {}
10.32 +
10.33 +void
10.34 +Chunk::print (std::ostream &os) const
10.35 +{
10.36 + print (&os);
10.37 +}
10.38 +void
10.39 +Chunk::add (Buffer *buffer) const
10.40 +{
10.41 + add_to (buffer);
10.42 +}
10.43 +void
10.44 +Chunk::peek (Buffer const *buffer)
10.45 +{
10.46 + peek_from (buffer);
10.47 + m_must_peek_before_remove = true;
10.48 +}
10.49 +void
10.50 +Chunk::remove (Buffer *buffer)
10.51 +{
10.52 + assert (m_must_peek_before_remove);
10.53 + remove_from (buffer);
10.54 + m_must_peek_before_remove = false;
10.55 +}
10.56 +
10.57 +
10.58 +
10.59 +Chunk::~Chunk ()
10.60 +{}
10.61 +
10.62 +std::ostream& operator<< (std::ostream& os, Chunk const& chunk)
10.63 +{
10.64 + chunk.print (os);
10.65 + return os;
10.66 +}
10.67 +
10.68 +}; // namespace yans
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/src/common/chunk.h Tue Aug 29 17:42:13 2006 +0200
11.3 @@ -0,0 +1,89 @@
11.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
11.5 +/*
11.6 + * Copyright (c) 2005 INRIA
11.7 + * All rights reserved.
11.8 + *
11.9 + * This program is free software; you can redistribute it and/or modify
11.10 + * it under the terms of the GNU General Public License version 2 as
11.11 + * published by the Free Software Foundation;
11.12 + *
11.13 + * This program is distributed in the hope that it will be useful,
11.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.16 + * GNU General Public License for more details.
11.17 + *
11.18 + * You should have received a copy of the GNU General Public License
11.19 + * along with this program; if not, write to the Free Software
11.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
11.21 + *
11.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
11.23 + */
11.24 +
11.25 +#ifndef CHUNK_H
11.26 +#define CHUNK_H
11.27 +
11.28 +#include <stdint.h>
11.29 +#include <ostream>
11.30 +#include "buffer.h"
11.31 +
11.32 +namespace yans {
11.33 +
11.34 +/**
11.35 + * \brief Protocol header serialization and deserialization.
11.36 + *
11.37 + * Every Protocol header which needs to be inserted and removed
11.38 + * from a Packet instance must derive from this abstract base class
11.39 + * and implement the private pure virtual methods defined here.
11.40 + */
11.41 +class Chunk {
11.42 +public:
11.43 + Chunk ();
11.44 + /**
11.45 + * Derived classes must provided an explicit virtual destructor
11.46 + */
11.47 + virtual ~Chunk () = 0;
11.48 +
11.49 + void print (std::ostream &os) const;
11.50 +
11.51 + void add (Buffer *buffer) const;
11.52 + void peek (Buffer const *buffer);
11.53 + void remove (Buffer *buffer);
11.54 +private:
11.55 + bool m_must_peek_before_remove;
11.56 + /**
11.57 + * \param os the std output stream in which this
11.58 + * protocol header must print itself.
11.59 + */
11.60 + virtual void print (std::ostream *os) const = 0;
11.61 +
11.62 + /**
11.63 + * \param buffer the buffer in which the protocol header
11.64 + * must serialize itself.
11.65 + *
11.66 + * This method must:
11.67 + * - reserve room for its serialized representation in the input buffer
11.68 + * - serialize itself in this reserved room
11.69 + */
11.70 + virtual void add_to (Buffer *buffer) const = 0;
11.71 + /**
11.72 + * \param buffer the buffer from which the protocol header must
11.73 + * deserialize itself.
11.74 + *
11.75 + */
11.76 + virtual void peek_from (Buffer const *buffer) = 0;
11.77 + /**
11.78 + * \param buffer the buffer from which the protocol header
11.79 + * must remove itself.
11.80 + *
11.81 + * This method must remove its serialized representation
11.82 + * from the input buffer. This method does not need to deserialize
11.83 + * the data itself.
11.84 + */
11.85 + virtual void remove_from (Buffer *buffer) = 0;
11.86 +};
11.87 +
11.88 +std::ostream& operator<< (std::ostream& os, Chunk const& chunk);
11.89 +
11.90 +}; // namespace yans
11.91 +
11.92 +#endif /* CHUNK_H */
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/src/common/count-ptr-holder.tcc Tue Aug 29 17:42:13 2006 +0200
12.3 @@ -0,0 +1,70 @@
12.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
12.5 +/*
12.6 + * Copyright (c) 2006 INRIA
12.7 + * All rights reserved.
12.8 + *
12.9 + * This program is free software; you can redistribute it and/or modify
12.10 + * it under the terms of the GNU General Public License version 2 as
12.11 + * published by the Free Software Foundation;
12.12 + *
12.13 + * This program is distributed in the hope that it will be useful,
12.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.16 + * GNU General Public License for more details.
12.17 + *
12.18 + * You should have received a copy of the GNU General Public License
12.19 + * along with this program; if not, write to the Free Software
12.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
12.21 + *
12.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
12.23 + */
12.24 +
12.25 +#ifndef COUNT_PTR_HOLDER_TCC
12.26 +#define COUNT_PTR_HOLDER_TCC
12.27 +
12.28 +namespace yans {
12.29 +
12.30 +template <typename T>
12.31 +class CountPtrHolder {
12.32 +public:
12.33 + typedef T *real_type;
12.34 +
12.35 + CountPtrHolder (T *env)
12.36 + : m_env (env) {
12.37 + m_env->ref ();
12.38 + }
12.39 + ~CountPtrHolder () {
12.40 + if (m_env != 0) {
12.41 + m_env->unref ();
12.42 + }
12.43 + }
12.44 + CountPtrHolder (CountPtrHolder const&o) {
12.45 + m_env = o.m_env;
12.46 + m_env->ref ();
12.47 + }
12.48 + T *remove (void) {
12.49 + T *env = m_env;
12.50 + m_env = 0;
12.51 + return env;
12.52 + }
12.53 +private:
12.54 + CountPtrHolder ();
12.55 + CountPtrHolder &operator = (CountPtrHolder const& o);
12.56 + T *m_env;
12.57 +};
12.58 +
12.59 +template<typename T>
12.60 +CountPtrHolder<T>
12.61 +make_count_ptr_holder (T *t) {
12.62 + return CountPtrHolder<T> (t);
12.63 +}
12.64 +
12.65 +template<typename T>
12.66 +CountPtrHolder<T const>
12.67 +make_const_count_ptr_holder (T *t) {
12.68 + return CountPtrHolder<T const> (t);
12.69 +}
12.70 +
12.71 +}; // namespace yans
12.72 +
12.73 +#endif /* REF_HOLDER_TCC */
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/src/common/data-writer.cc Tue Aug 29 17:42:13 2006 +0200
13.3 @@ -0,0 +1,119 @@
13.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
13.5 +/*
13.6 + * Copyright (c) 2005 INRIA
13.7 + * All rights reserved.
13.8 + *
13.9 + * This program is free software; you can redistribute it and/or modify
13.10 + * it under the terms of the GNU General Public License version 2 as
13.11 + * published by the Free Software Foundation;
13.12 + *
13.13 + * This program is distributed in the hope that it will be useful,
13.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.16 + * GNU General Public License for more details.
13.17 + *
13.18 + * You should have received a copy of the GNU General Public License
13.19 + * along with this program; if not, write to the Free Software
13.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13.21 + *
13.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
13.23 + */
13.24 +#include "data-writer.h"
13.25 +
13.26 +#include <sys/types.h>
13.27 +#include <sys/stat.h>
13.28 +#include <sys/poll.h>
13.29 +#include <fcntl.h>
13.30 +#include <unistd.h>
13.31 +#include <cassert>
13.32 +#include <string.h>
13.33 +#include <list>
13.34 +
13.35 +#define noTRACE_DATA_WRITER 1
13.36 +
13.37 +#ifdef TRACE_DATA_WRITER
13.38 +#include <iostream>
13.39 +# define TRACE(x) \
13.40 +std::cout << "DATA WRITER TRACE " << this << " " << x << std::endl;
13.41 +#else /* TRACE_DATA_WRITER */
13.42 +# define TRACE(format,...)
13.43 +#endif /* TRACE_DATA_WRITER */
13.44 +
13.45 +#define BUFFER_SIZE (4096)
13.46 +
13.47 +
13.48 +namespace yans {
13.49 +
13.50 +class DataWriterPrivate {
13.51 +public:
13.52 + DataWriterPrivate ();
13.53 + ~DataWriterPrivate ();
13.54 +
13.55 + void open (char const *filename);
13.56 + void write (uint8_t *buffer, uint32_t size);
13.57 +private:
13.58 + uint8_t m_data[BUFFER_SIZE];
13.59 + uint32_t m_current;
13.60 + int m_fd;
13.61 +};
13.62 +
13.63 +DataWriterPrivate::DataWriterPrivate ()
13.64 + : m_current (0)
13.65 +{}
13.66 +DataWriterPrivate::~DataWriterPrivate ()
13.67 +{
13.68 + ::write (m_fd, m_data, m_current);
13.69 + ::close (m_fd);
13.70 +}
13.71 +
13.72 +
13.73 +void
13.74 +DataWriterPrivate::open (char const *filename)
13.75 +{
13.76 + m_fd = ::open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
13.77 + assert (m_fd != -1);
13.78 +}
13.79 +
13.80 +#ifndef min
13.81 +#define min(a,b) ((a)<(b)?(a):(b))
13.82 +#endif /* min */
13.83 +
13.84 +void
13.85 +DataWriterPrivate::write (uint8_t *buffer, uint32_t size)
13.86 +{
13.87 + while (size > 0) {
13.88 + uint32_t to_copy = min (BUFFER_SIZE - m_current, size);
13.89 + memcpy (m_data + m_current, buffer, to_copy);
13.90 + size -= to_copy;
13.91 + m_current += to_copy;
13.92 + buffer += to_copy;
13.93 + if (m_current == BUFFER_SIZE) {
13.94 + ssize_t written = 0;
13.95 + written = ::write (m_fd, m_data, BUFFER_SIZE);
13.96 + assert (written == BUFFER_SIZE);
13.97 + m_current = 0;
13.98 + }
13.99 + }
13.100 +}
13.101 +
13.102 +DataWriter::DataWriter ()
13.103 + : m_priv (new DataWriterPrivate ())
13.104 +{}
13.105 +DataWriter::~DataWriter ()
13.106 +{
13.107 + delete m_priv;
13.108 + m_priv = 0;
13.109 +}
13.110 +
13.111 +void
13.112 +DataWriter::open (char const *filename)
13.113 +{
13.114 + m_priv->open (filename);
13.115 +}
13.116 +void
13.117 +DataWriter::write (uint8_t *buffer, uint32_t size)
13.118 +{
13.119 + m_priv->write (buffer, size);
13.120 +}
13.121 +
13.122 +}; // namespace
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/src/common/data-writer.h Tue Aug 29 17:42:13 2006 +0200
14.3 @@ -0,0 +1,44 @@
14.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
14.5 +/*
14.6 + * Copyright (c) 2005 INRIA
14.7 + * All rights reserved.
14.8 + *
14.9 + * This program is free software; you can redistribute it and/or modify
14.10 + * it under the terms of the GNU General Public License version 2 as
14.11 + * published by the Free Software Foundation;
14.12 + *
14.13 + * This program is distributed in the hope that it will be useful,
14.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.16 + * GNU General Public License for more details.
14.17 + *
14.18 + * You should have received a copy of the GNU General Public License
14.19 + * along with this program; if not, write to the Free Software
14.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14.21 + *
14.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
14.23 + */
14.24 +
14.25 +#ifndef DATA_WRITER_H
14.26 +#define DATA_WRITER_H
14.27 +
14.28 +#include <stdint.h>
14.29 +
14.30 +namespace yans {
14.31 +
14.32 +class DataWriterPrivate;
14.33 +
14.34 +class DataWriter {
14.35 +public:
14.36 + DataWriter ();
14.37 + ~DataWriter ();
14.38 +
14.39 + void open (char const *filename);
14.40 + void write (uint8_t *buffer, uint32_t size);
14.41 +private:
14.42 + DataWriterPrivate *m_priv;
14.43 +};
14.44 +
14.45 +}; //namespace yans
14.46 +
14.47 +#endif /* DATA_WRITER_H */
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/src/common/f-traced-variable.tcc Tue Aug 29 17:42:13 2006 +0200
15.3 @@ -0,0 +1,58 @@
15.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
15.5 +/*
15.6 + * Copyright (c) 2006 INRIA
15.7 + * All rights reserved.
15.8 + *
15.9 + * This program is free software; you can redistribute it and/or modify
15.10 + * it under the terms of the GNU General Public License version 2 as
15.11 + * published by the Free Software Foundation;
15.12 + *
15.13 + * This program is distributed in the hope that it will be useful,
15.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15.16 + * GNU General Public License for more details.
15.17 + *
15.18 + * You should have received a copy of the GNU General Public License
15.19 + * along with this program; if not, write to the Free Software
15.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15.21 + *
15.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
15.23 + */
15.24 +
15.25 +#ifndef F_TRACED_VARIABLE_TCC
15.26 +#define F_TRACED_VARIABLE_TCC
15.27 +
15.28 +#include "yans/callback.h"
15.29 +#include <stdint.h>
15.30 +
15.31 +namespace yans {
15.32 +
15.33 +class FTracedVariableBase {
15.34 +public:
15.35 + typedef Callback<void,double, double> ChangeNotifyCallback;
15.36 +
15.37 + FTracedVariableBase () {}
15.38 + FTracedVariableBase (FTracedVariableBase const &o) {}
15.39 + FTracedVariableBase &operator = (FTracedVariableBase const &o) {
15.40 + return *this;
15.41 + }
15.42 +
15.43 + ~FTracedVariableBase () {}
15.44 +
15.45 + void set_callback(ChangeNotifyCallback callback) {
15.46 + m_callback = callback;
15.47 + }
15.48 +protected:
15.49 + void notify (double old_val, double new_val) {
15.50 + if (old_val != new_val && !m_callback.is_null ()) {
15.51 + m_callback (old_val, new_val);
15.52 + }
15.53 + }
15.54 +private:
15.55 + ChangeNotifyCallback m_callback;
15.56 +};
15.57 +
15.58 +
15.59 +}; // namespace yans
15.60 +
15.61 +#endif /* F_TRACED_VARIABLE_TCC */
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/src/common/ipv4-address.cc Tue Aug 29 17:42:13 2006 +0200
16.3 @@ -0,0 +1,203 @@
16.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
16.5 +/*
16.6 + * Copyright (c) 2005 INRIA
16.7 + * All rights reserved.
16.8 + *
16.9 + * This program is free software; you can redistribute it and/or modify
16.10 + * it under the terms of the GNU General Public License version 2 as
16.11 + * published by the Free Software Foundation;
16.12 + *
16.13 + * This program is distributed in the hope that it will be useful,
16.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.16 + * GNU General Public License for more details.
16.17 + *
16.18 + * You should have received a copy of the GNU General Public License
16.19 + * along with this program; if not, write to the Free Software
16.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16.21 + *
16.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
16.23 + */
16.24 +
16.25 +#include "utils.h"
16.26 +#include "ipv4-address.h"
16.27 +
16.28 +namespace yans {
16.29 +
16.30 +Ipv4Mask::Ipv4Mask ()
16.31 + : m_mask (0x66666666)
16.32 +{}
16.33 +
16.34 +Ipv4Mask::Ipv4Mask (uint32_t mask)
16.35 + : m_mask (mask)
16.36 +{}
16.37 +Ipv4Mask::Ipv4Mask (char const *mask)
16.38 +{
16.39 + m_mask = ascii_to_ipv4_host (mask);
16.40 +}
16.41 +
16.42 +bool
16.43 +Ipv4Mask::is_equal (Ipv4Mask other) const
16.44 +{
16.45 + if (other.m_mask == m_mask) {
16.46 + return true;
16.47 + } else {
16.48 + return false;
16.49 + }
16.50 +}
16.51 +
16.52 +
16.53 +bool
16.54 +Ipv4Mask::is_match (Ipv4Address a, Ipv4Address b) const
16.55 +{
16.56 + if ((a.get_host_order () & m_mask) == (b.get_host_order () & m_mask)) {
16.57 + return true;
16.58 + } else {
16.59 + return false;
16.60 + }
16.61 +}
16.62 +
16.63 +uint32_t
16.64 +Ipv4Mask::get_host_order (void) const
16.65 +{
16.66 + return m_mask;
16.67 +}
16.68 +void
16.69 +Ipv4Mask::set_host_order (uint32_t value)
16.70 +{
16.71 + m_mask = value;
16.72 +}
16.73 +
16.74 +void
16.75 +Ipv4Mask::print (std::ostream *os) const
16.76 +{
16.77 + *os << ((m_mask >> 24) & 0xff) << "."
16.78 + << ((m_mask >> 16) & 0xff) << "."
16.79 + << ((m_mask >> 8) & 0xff) << "."
16.80 + << ((m_mask >> 0) & 0xff);
16.81 +}
16.82 +
16.83 +
16.84 +Ipv4Mask
16.85 +Ipv4Mask::get_loopback (void)
16.86 +{
16.87 + static Ipv4Mask loopback = Ipv4Mask ("255.0.0.0");
16.88 + return loopback;
16.89 +}
16.90 +Ipv4Mask
16.91 +Ipv4Mask::get_zero (void)
16.92 +{
16.93 + static Ipv4Mask zero = Ipv4Mask ("0.0.0.0");
16.94 + return zero;
16.95 +}
16.96 +
16.97 +Ipv4Address::Ipv4Address ()
16.98 + : m_address (0x66666666)
16.99 +{}
16.100 +Ipv4Address::Ipv4Address (uint32_t address)
16.101 +{
16.102 + m_address = address;
16.103 +}
16.104 +Ipv4Address::Ipv4Address (char const *address)
16.105 +{
16.106 + m_address = ascii_to_ipv4_host (address);
16.107 +}
16.108 +
16.109 +bool
16.110 +Ipv4Address::is_equal (Ipv4Address other) const
16.111 +{
16.112 + if (other.m_address == m_address) {
16.113 + return true;
16.114 + } else {
16.115 + return false;
16.116 + }
16.117 +}
16.118 +
16.119 +bool
16.120 +Ipv4Address::is_multicast (void)
16.121 +{
16.122 + // XXX
16.123 + return false;
16.124 +}
16.125 +
16.126 +uint32_t
16.127 +Ipv4Address::get_host_order (void) const
16.128 +{
16.129 + return m_address;
16.130 +}
16.131 +void
16.132 +Ipv4Address::set_host_order (uint32_t ip)
16.133 +{
16.134 + m_address = ip;
16.135 +}
16.136 +void
16.137 +Ipv4Address::serialize (uint8_t buf[4]) const
16.138 +{
16.139 + buf[0] = (m_address >> 24) & 0xff;
16.140 + buf[1] = (m_address >> 16) & 0xff;
16.141 + buf[2] = (m_address >> 8) & 0xff;
16.142 + buf[3] = (m_address >> 0) & 0xff;
16.143 +}
16.144 +
16.145 +void
16.146 +Ipv4Address::print (std::ostream *os) const
16.147 +{
16.148 + *os << ((m_address >> 24) & 0xff) << "."
16.149 + << ((m_address >> 16) & 0xff) << "."
16.150 + << ((m_address >> 8) & 0xff) << "."
16.151 + << ((m_address >> 0) & 0xff);
16.152 +}
16.153 +
16.154 +
16.155 +
16.156 +Ipv4Address
16.157 +Ipv4Address::get_zero (void)
16.158 +{
16.159 + static Ipv4Address zero ("0.0.0.0");
16.160 + return zero;
16.161 +}
16.162 +Ipv4Address
16.163 +Ipv4Address::get_any (void)
16.164 +{
16.165 + static Ipv4Address any ("0.0.0.0");
16.166 + return any;
16.167 +}
16.168 +Ipv4Address
16.169 +Ipv4Address::get_broadcast (void)
16.170 +{
16.171 + static Ipv4Address broadcast ("255.255.255.255");
16.172 + return broadcast;
16.173 +}
16.174 +Ipv4Address
16.175 +Ipv4Address::get_loopback (void)
16.176 +{
16.177 + Ipv4Address loopback ("127.0.0.1");
16.178 + return loopback;
16.179 +}
16.180 +
16.181 +bool operator == (Ipv4Address const &a, Ipv4Address const &b)
16.182 +{
16.183 + return a.is_equal (b);
16.184 +}
16.185 +bool operator != (Ipv4Address const &a, Ipv4Address const &b)
16.186 +{
16.187 + return !a.is_equal (b);
16.188 +}
16.189 +size_t Ipv4AddressHash::operator()(Ipv4Address const &x) const
16.190 +{
16.191 + return x.get_host_order ();
16.192 +}
16.193 +
16.194 +std::ostream& operator<< (std::ostream& os, Ipv4Address const& address)
16.195 +{
16.196 + address.print (&os);
16.197 + return os;
16.198 +}
16.199 +std::ostream& operator<< (std::ostream& os, Ipv4Mask const& mask)
16.200 +{
16.201 + mask.print (&os);
16.202 + return os;
16.203 +}
16.204 +
16.205 +
16.206 +}; // namespace yans
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/src/common/ipv4-address.h Tue Aug 29 17:42:13 2006 +0200
17.3 @@ -0,0 +1,107 @@
17.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
17.5 +/*
17.6 + * Copyright (c) 2005 INRIA
17.7 + * All rights reserved.
17.8 + *
17.9 + * This program is free software; you can redistribute it and/or modify
17.10 + * it under the terms of the GNU General Public License version 2 as
17.11 + * published by the Free Software Foundation;
17.12 + *
17.13 + * This program is distributed in the hope that it will be useful,
17.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17.16 + * GNU General Public License for more details.
17.17 + *
17.18 + * You should have received a copy of the GNU General Public License
17.19 + * along with this program; if not, write to the Free Software
17.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17.21 + *
17.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
17.23 + */
17.24 +
17.25 +#ifndef IPV4_ADDRESS_H
17.26 +#define IPV4_ADDRESS_H
17.27 +
17.28 +#include <stdint.h>
17.29 +#include <ostream>
17.30 +
17.31 +namespace yans {
17.32 +
17.33 +/* Ipv4 addresses are stored in host order in
17.34 + * this class.
17.35 + */
17.36 +class Ipv4Address {
17.37 +public:
17.38 + Ipv4Address ();
17.39 + /* input address is in host order. */
17.40 + Ipv4Address (uint32_t address);
17.41 + /* input address is in format:
17.42 + * hhh.xxx.xxx.lll
17.43 + * where h is the high byte and l the
17.44 + * low byte
17.45 + */
17.46 + Ipv4Address (char const *address);
17.47 +
17.48 + bool is_equal (Ipv4Address other) const;
17.49 +
17.50 + /* Using this method is frowned upon.
17.51 + * Please, do _not_ use this method.
17.52 + * It is there only for chunk-ipv4.
17.53 + */
17.54 + uint32_t get_host_order (void) const;
17.55 + void set_host_order (uint32_t ip);
17.56 + void serialize (uint8_t buf[4]) const;
17.57 +
17.58 + void print (std::ostream *os) const;
17.59 +
17.60 + bool is_broadcast (void);
17.61 + bool is_multicast (void);
17.62 +
17.63 + static Ipv4Address get_zero (void);
17.64 + static Ipv4Address get_any (void);
17.65 + static Ipv4Address get_broadcast (void);
17.66 + static Ipv4Address get_loopback (void);
17.67 +private:
17.68 + uint32_t m_address;
17.69 +};
17.70 +
17.71 +
17.72 +class Ipv4Mask {
17.73 +public:
17.74 + Ipv4Mask ();
17.75 + Ipv4Mask (uint32_t mask);
17.76 + Ipv4Mask (char const *mask);
17.77 +
17.78 + bool is_match (Ipv4Address a, Ipv4Address b) const;
17.79 +
17.80 + bool is_equal (Ipv4Mask other) const;
17.81 +
17.82 +
17.83 + /* Using this method is frowned upon.
17.84 + * Please, do _not_ use this method.
17.85 + */
17.86 + uint32_t get_host_order (void) const;
17.87 + void set_host_order (uint32_t value);
17.88 +
17.89 + void print (std::ostream *os) const;
17.90 +
17.91 + static Ipv4Mask get_loopback (void);
17.92 + static Ipv4Mask get_zero (void);
17.93 +private:
17.94 + uint32_t m_mask;
17.95 +};
17.96 +
17.97 +std::ostream& operator<< (std::ostream& os, Ipv4Address const& address);
17.98 +std::ostream& operator<< (std::ostream& os, Ipv4Mask const& mask);
17.99 +
17.100 +bool operator == (Ipv4Address const &a, Ipv4Address const &b);
17.101 +bool operator != (Ipv4Address const &a, Ipv4Address const &b);
17.102 +class Ipv4AddressHash : public std::unary_function<Ipv4Address, size_t> {
17.103 +public:
17.104 + size_t operator()(Ipv4Address const &x) const;
17.105 +};
17.106 +bool operator != (Ipv4Address const &a, Ipv4Address const &b);
17.107 +
17.108 +}; // namespace yans
17.109 +
17.110 +#endif /* IPV4_ADDRESS_H */
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/src/common/ipv4-network-interface.cc Tue Aug 29 17:42:13 2006 +0200
18.3 @@ -0,0 +1,82 @@
18.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
18.5 +/*
18.6 + * Copyright (c) 2006 INRIA
18.7 + * All rights reserved.
18.8 + *
18.9 + * This program is free software; you can redistribute it and/or modify
18.10 + * it under the terms of the GNU General Public License version 2 as
18.11 + * published by the Free Software Foundation;
18.12 + *
18.13 + * This program is distributed in the hope that it will be useful,
18.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.16 + * GNU General Public License for more details.
18.17 + *
18.18 + * You should have received a copy of the GNU General Public License
18.19 + * along with this program; if not, write to the Free Software
18.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18.21 + *
18.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18.23 + */
18.24 +#include "ipv4-network-interface.h"
18.25 +
18.26 +namespace yans {
18.27 +
18.28 +Ipv4NetworkInterface::~Ipv4NetworkInterface ()
18.29 +{}
18.30 +
18.31 +void
18.32 +Ipv4NetworkInterface::set_address (Ipv4Address ad)
18.33 +{
18.34 + m_address = ad;
18.35 +}
18.36 +void
18.37 +Ipv4NetworkInterface::set_mask (Ipv4Mask mask)
18.38 +{
18.39 + m_mask = mask;
18.40 +}
18.41 +uint16_t
18.42 +Ipv4NetworkInterface::get_mtu (void) const
18.43 +{
18.44 + return real_get_mtu ();
18.45 +}
18.46 +Ipv4Mask
18.47 +Ipv4NetworkInterface::get_mask (void) const
18.48 +{
18.49 + return m_mask;
18.50 +}
18.51 +Ipv4Address
18.52 +Ipv4NetworkInterface::get_address (void) const
18.53 +{
18.54 + return m_address;
18.55 +}
18.56 +Ipv4Address
18.57 +Ipv4NetworkInterface::get_broadcast (void) const
18.58 +{
18.59 + uint32_t mask = m_mask.get_host_order ();
18.60 + uint32_t address = m_address.get_host_order ();
18.61 + Ipv4Address broadcast = Ipv4Address (address | (~mask));
18.62 + return broadcast;
18.63 +}
18.64 +
18.65 +void
18.66 +Ipv4NetworkInterface::send (Packet packet, Ipv4Address to)
18.67 +{
18.68 + real_send (packet, to);
18.69 +}
18.70 +
18.71 +void
18.72 +Ipv4NetworkInterface::set_rx_callback (RxCallback callback)
18.73 +{
18.74 + m_rx_callback = callback;
18.75 +}
18.76 +
18.77 +void
18.78 +Ipv4NetworkInterface::forward_up (Packet packet)
18.79 +{
18.80 + m_rx_callback (packet, this);
18.81 +}
18.82 +
18.83 +
18.84 +
18.85 +}; // namespace yans
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/src/common/ipv4-network-interface.h Tue Aug 29 17:42:13 2006 +0200
19.3 @@ -0,0 +1,59 @@
19.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
19.5 +/*
19.6 + * Copyright (c) 2006 INRIA
19.7 + * All rights reserved.
19.8 + *
19.9 + * This program is free software; you can redistribute it and/or modify
19.10 + * it under the terms of the GNU General Public License version 2 as
19.11 + * published by the Free Software Foundation;
19.12 + *
19.13 + * This program is distributed in the hope that it will be useful,
19.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19.16 + * GNU General Public License for more details.
19.17 + *
19.18 + * You should have received a copy of the GNU General Public License
19.19 + * along with this program; if not, write to the Free Software
19.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19.21 + *
19.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19.23 + */
19.24 +#ifndef IPV4_NETWORK_INTERFACE
19.25 +#define IPV4_NETWORK_INTERFACE
19.26 +
19.27 +#include "ipv4-address.h"
19.28 +#include "yans/callback.h"
19.29 +#include "packet.h"
19.30 +
19.31 +namespace yans {
19.32 +
19.33 +class Packet;
19.34 +
19.35 +class Ipv4NetworkInterface {
19.36 +public:
19.37 + typedef Callback<void, Packet , Ipv4NetworkInterface *> RxCallback;
19.38 + virtual ~Ipv4NetworkInterface () = 0;
19.39 +
19.40 + void set_address (Ipv4Address ad);
19.41 + void set_mask (Ipv4Mask mask);
19.42 +
19.43 + uint16_t get_mtu (void) const;
19.44 + Ipv4Mask get_mask (void) const;
19.45 + Ipv4Address get_address (void) const;
19.46 + Ipv4Address get_broadcast (void) const;
19.47 +
19.48 + void send (Packet packet, Ipv4Address to);
19.49 + void set_rx_callback (RxCallback callback);
19.50 +protected:
19.51 + void forward_up (Packet packet);
19.52 +private:
19.53 + virtual uint16_t real_get_mtu (void) const = 0;
19.54 + virtual void real_send (Packet packet, Ipv4Address to) = 0;
19.55 + RxCallback m_rx_callback;
19.56 + Ipv4Address m_address;
19.57 + Ipv4Mask m_mask;
19.58 +};
19.59 +
19.60 +}; // namespace yans
19.61 +
19.62 +#endif /* IPV4_NETWORK_INTERFACE */
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/src/common/llc-snap-encapsulation.cc Tue Aug 29 17:42:13 2006 +0200
20.3 @@ -0,0 +1,89 @@
20.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
20.5 +/*
20.6 + * Copyright (c) 2006 INRIA
20.7 + * All rights reserved.
20.8 + *
20.9 + * This program is free software; you can redistribute it and/or modify
20.10 + * it under the terms of the GNU General Public License version 2 as
20.11 + * published by the Free Software Foundation;
20.12 + *
20.13 + * This program is distributed in the hope that it will be useful,
20.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
20.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20.16 + * GNU General Public License for more details.
20.17 + *
20.18 + * You should have received a copy of the GNU General Public License
20.19 + * along with this program; if not, write to the Free Software
20.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20.21 + *
20.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20.23 + */
20.24 +#include "llc-snap-encapsulation.h"
20.25 +#include "chunk-llc-snap.h"
20.26 +#include "packet.h"
20.27 +#include "chunk.h"
20.28 +#include "mac-network-interface.h"
20.29 +#include <cassert>
20.30 +
20.31 +namespace yans {
20.32 +
20.33 +uint32_t
20.34 +LlcSnapEncapsulation::get_overhead (void) const
20.35 +{
20.36 + ChunkLlcSnap llc;
20.37 + return llc.get_size ();
20.38 +}
20.39 +void
20.40 +LlcSnapEncapsulation::set_ipv4_callback (RxCallback callback)
20.41 +{
20.42 + m_ipv4_callback = callback;
20.43 +}
20.44 +void
20.45 +LlcSnapEncapsulation::set_arp_callback (RxCallback callback)
20.46 +{
20.47 + m_arp_callback = callback;
20.48 +}
20.49 +void
20.50 +LlcSnapEncapsulation::set_mac_interface (MacNetworkInterface *interface)
20.51 +{
20.52 + m_interface = interface;
20.53 +}
20.54 +void
20.55 +LlcSnapEncapsulation::send_ipv4 (Packet packet, MacAddress to)
20.56 +{
20.57 + ChunkLlcSnap llc;
20.58 + llc.set_type (ChunkLlcSnap::TYPE_IPV4);
20.59 + packet.add (&llc);
20.60 + m_interface->send (packet, to);
20.61 +}
20.62 +void
20.63 +LlcSnapEncapsulation::send_arp (Packet packet, MacAddress to)
20.64 +{
20.65 + ChunkLlcSnap llc;
20.66 + llc.set_type (ChunkLlcSnap::TYPE_ARP);
20.67 + packet.add (&llc);
20.68 + m_interface->send (packet, to);
20.69 +}
20.70 +
20.71 +void
20.72 +LlcSnapEncapsulation::receive (Packet packet, MacNetworkInterface *interface)
20.73 +{
20.74 + assert (interface == m_interface);
20.75 + ChunkLlcSnap llc;
20.76 + packet.peek (&llc);
20.77 + packet.remove (&llc);
20.78 + switch (llc.get_type ()) {
20.79 + case ChunkLlcSnap::TYPE_IPV4:
20.80 + m_ipv4_callback (packet);
20.81 + break;
20.82 + case ChunkLlcSnap::TYPE_ARP:
20.83 + m_arp_callback (packet);
20.84 + break;
20.85 + default:
20.86 + assert (false);
20.87 + //NOT REACHED
20.88 + break;
20.89 + }
20.90 +}
20.91 +
20.92 +}; // namespace yans
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/src/common/llc-snap-encapsulation.h Tue Aug 29 17:42:13 2006 +0200
21.3 @@ -0,0 +1,52 @@
21.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
21.5 +/*
21.6 + * Copyright (c) 2006 INRIA
21.7 + * All rights reserved.
21.8 + *
21.9 + * This program is free software; you can redistribute it and/or modify
21.10 + * it under the terms of the GNU General Public License version 2 as
21.11 + * published by the Free Software Foundation;
21.12 + *
21.13 + * This program is distributed in the hope that it will be useful,
21.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21.16 + * GNU General Public License for more details.
21.17 + *
21.18 + * You should have received a copy of the GNU General Public License
21.19 + * along with this program; if not, write to the Free Software
21.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21.21 + *
21.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
21.23 + */
21.24 +#ifndef LLC_SNAP_ENCAPSULATION
21.25 +#define LLC_SNAP_ENCAPSULATION
21.26 +
21.27 +#include <stdint.h>
21.28 +#include "yans/callback.h"
21.29 +#include "mac-address.h"
21.30 +#include "packet.h"
21.31 +
21.32 +namespace yans {
21.33 +
21.34 +class MacNetworkInterface;
21.35 +
21.36 +class LlcSnapEncapsulation {
21.37 +public:
21.38 + typedef Callback<void, Packet > RxCallback;
21.39 +
21.40 + uint32_t get_overhead (void) const;
21.41 + void set_ipv4_callback (RxCallback callback);
21.42 + void set_arp_callback (RxCallback callback);
21.43 + void set_mac_interface (MacNetworkInterface *interface);
21.44 + void send_ipv4 (Packet packet, MacAddress to);
21.45 + void send_arp (Packet packet, MacAddress to);
21.46 + void receive (Packet packet, MacNetworkInterface *interface);
21.47 +private:
21.48 + RxCallback m_ipv4_callback;
21.49 + RxCallback m_arp_callback;
21.50 + MacNetworkInterface *m_interface;
21.51 +};
21.52 +
21.53 +}; // namespace yans
21.54 +
21.55 +#endif /* LLC_SNAP_ENCAPSULATION */
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/src/common/mac-address-factory.cc Tue Aug 29 17:42:13 2006 +0200
22.3 @@ -0,0 +1,46 @@
22.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
22.5 +/*
22.6 + * Copyright (c) 2006 INRIA
22.7 + * All rights reserved.
22.8 + *
22.9 + * This program is free software; you can redistribute it and/or modify
22.10 + * it under the terms of the GNU General Public License version 2 as
22.11 + * published by the Free Software Foundation;
22.12 + *
22.13 + * This program is distributed in the hope that it will be useful,
22.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22.16 + * GNU General Public License for more details.
22.17 + *
22.18 + * You should have received a copy of the GNU General Public License
22.19 + * along with this program; if not, write to the Free Software
22.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22.21 + *
22.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
22.23 + */
22.24 +#include "mac-address-factory.h"
22.25 +
22.26 +namespace yans {
22.27 +
22.28 +MacAddressFactory::MacAddressFactory ()
22.29 +{
22.30 + m_addr[0] = 0;
22.31 + m_addr[1] = 0;
22.32 + m_addr[2] = 0;
22.33 + m_addr[3] = 0;
22.34 + m_addr[4] = 0;
22.35 + m_addr[5] = 0;
22.36 + m_index = 0;
22.37 +}
22.38 +
22.39 +MacAddress
22.40 +MacAddressFactory::get_next (void)
22.41 +{
22.42 + m_addr[m_index]++;
22.43 + if (m_addr[m_index] == 0) {
22.44 + m_index++;
22.45 + }
22.46 + return MacAddress (m_addr);
22.47 +}
22.48 +
22.49 +}; // namespace yans
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/src/common/mac-address-factory.h Tue Aug 29 17:42:13 2006 +0200
23.3 @@ -0,0 +1,40 @@
23.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
23.5 +/*
23.6 + * Copyright (c) 2006 INRIA
23.7 + * All rights reserved.
23.8 + *
23.9 + * This program is free software; you can redistribute it and/or modify
23.10 + * it under the terms of the GNU General Public License version 2 as
23.11 + * published by the Free Software Foundation;
23.12 + *
23.13 + * This program is distributed in the hope that it will be useful,
23.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23.16 + * GNU General Public License for more details.
23.17 + *
23.18 + * You should have received a copy of the GNU General Public License
23.19 + * along with this program; if not, write to the Free Software
23.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23.21 + *
23.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
23.23 + */
23.24 +#ifndef MAC_ADDRESS_FACTORY_H
23.25 +#define MAC_ADDRESS_FACTORY_H
23.26 +
23.27 +#include "mac-address.h"
23.28 +
23.29 +namespace yans {
23.30 +
23.31 +class MacAddressFactory {
23.32 +public:
23.33 + MacAddressFactory ();
23.34 + MacAddress get_next (void);
23.35 +private:
23.36 + uint8_t m_addr[6];
23.37 + uint8_t m_cur;
23.38 + uint8_t m_index;
23.39 +};
23.40 +
23.41 +}; // namespace yans
23.42 +
23.43 +#endif /* MAC_ADDRESS_FACTORY_H */
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/src/common/mac-address.cc Tue Aug 29 17:42:13 2006 +0200
24.3 @@ -0,0 +1,187 @@
24.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
24.5 +/*
24.6 + * Copyright (c) 2005 INRIA
24.7 + * All rights reserved.
24.8 + *
24.9 + * This program is free software; you can redistribute it and/or modify
24.10 + * it under the terms of the GNU General Public License version 2 as
24.11 + * published by the Free Software Foundation;
24.12 + *
24.13 + * This program is distributed in the hope that it will be useful,
24.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24.16 + * GNU General Public License for more details.
24.17 + *
24.18 + * You should have received a copy of the GNU General Public License
24.19 + * along with this program; if not, write to the Free Software
24.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24.21 + *
24.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
24.23 + */
24.24 +
24.25 +#include "mac-address.h"
24.26 +#include "utils.h"
24.27 +
24.28 +namespace yans {
24.29 +
24.30 +MacAddress::MacAddress ()
24.31 +{
24.32 + m_address[0] = 0;
24.33 + m_address[1] = 0;
24.34 + m_address[2] = 0;
24.35 + m_address[3] = 0;
24.36 + m_address[4] = 0;
24.37 + m_address[5] = 0;
24.38 +}
24.39 +
24.40 +MacAddress::MacAddress (uint8_t const address[6])
24.41 +{
24.42 + m_address[0] = address[0];
24.43 + m_address[1] = address[1];
24.44 + m_address[2] = address[2];
24.45 + m_address[3] = address[3];
24.46 + m_address[4] = address[4];
24.47 + m_address[5] = address[5];
24.48 +}
24.49 +MacAddress::MacAddress (char const *address)
24.50 +{
24.51 + ascii_to_mac_network (address, m_address);
24.52 +}
24.53 +MacAddress::MacAddress (uint32_t ip_multicast_address)
24.54 +{
24.55 + m_address[0] = 1 | ((ip_multicast_address & 0x7f) << 1);
24.56 + m_address[1] = (ip_multicast_address >> 7) & 0xff;
24.57 + m_address[2] = (ip_multicast_address >> 16) & 0xff;
24.58 + m_address[3] = 0x5e;
24.59 + m_address[4] = 0;
24.60 + m_address[5] = 0;
24.61 +}
24.62 +MacAddress::~MacAddress ()
24.63 +{}
24.64 +
24.65 +bool
24.66 +MacAddress::is_equal (MacAddress other) const
24.67 +{
24.68 + if (m_address[0] == other.m_address[0] &&
24.69 + m_address[1] == other.m_address[1] &&
24.70 + m_address[2] == other.m_address[2] &&
24.71 + m_address[3] == other.m_address[3] &&
24.72 + m_address[4] == other.m_address[4] &&
24.73 + m_address[5] == other.m_address[5]) {
24.74 + return true;
24.75 + } else {
24.76 + return false;
24.77 + }
24.78 +}
24.79 +bool
24.80 +MacAddress::is_broadcast (void) const
24.81 +{
24.82 + if (m_address[0] == 0xff &&
24.83 + m_address[1] == 0xff &&
24.84 + m_address[2] == 0xff &&
24.85 + m_address[3] == 0xff &&
24.86 + m_address[4] == 0xff &&
24.87 + m_address[5] == 0xff) {
24.88 + return true;
24.89 + } else {
24.90 + return false;
24.91 + }
24.92 +}
24.93 +bool
24.94 +MacAddress::is_multicast (void) const
24.95 +{
24.96 + if (m_address[0] & 0x1) {
24.97 + return true;
24.98 + } else {
24.99 + return false;
24.100 + }
24.101 +}
24.102 +bool
24.103 +MacAddress::is_multicast_equal (MacAddress other) const
24.104 +{
24.105 + if (get_multicast_part () == other.get_multicast_part ()) {
24.106 + return true;
24.107 + } else {
24.108 + return false;
24.109 + }
24.110 +}
24.111 +
24.112 +uint32_t
24.113 +MacAddress::get_multicast_part (void) const
24.114 +{
24.115 + uint32_t part = 0;
24.116 + part |= m_address[0] >> 1;
24.117 + part |= m_address[1] << 7;
24.118 + part |= (m_address[1] << 15);
24.119 + return part;
24.120 +}
24.121 +
24.122 +
24.123 +void
24.124 +MacAddress::peek (uint8_t ad[6]) const
24.125 +{
24.126 + memcpy (ad, m_address, 6);
24.127 +}
24.128 +void
24.129 +MacAddress::set (uint8_t const ad[6])
24.130 +{
24.131 + memcpy (m_address, ad, 6);
24.132 +}
24.133 +
24.134 +void
24.135 +MacAddress::print (std::ostream *os) const
24.136 +{
24.137 + os->setf (std::ios::hex, std::ios::basefield);
24.138 + *os << (uint32_t)m_address[0] << ":"
24.139 + << (uint32_t)m_address[1] << ":"
24.140 + << (uint32_t)m_address[2] << ":"
24.141 + << (uint32_t)m_address[3] << ":"
24.142 + << (uint32_t)m_address[4] << ":"
24.143 + << (uint32_t)m_address[5];
24.144 + os->setf (std::ios::dec, std::ios::basefield);
24.145 +}
24.146 +
24.147 +
24.148 +
24.149 +
24.150 +MacAddress
24.151 +MacAddress::get_broadcast (void)
24.152 +{
24.153 + static MacAddress broadcast = MacAddress ("ff:ff:ff:ff:ff:ff");
24.154 + return broadcast;
24.155 +}
24.156 +
24.157 +bool operator == (MacAddress const&a, MacAddress const&b)
24.158 +{
24.159 + return a.is_equal (b);
24.160 +}
24.161 +
24.162 +bool operator != (MacAddress const&a, MacAddress const&b)
24.163 +{
24.164 + return !a.is_equal (b);
24.165 +}
24.166 +
24.167 +bool operator < (MacAddress const&a, MacAddress const&b)
24.168 +{
24.169 + uint8_t a_p[6];
24.170 + uint8_t b_p[6];
24.171 + a.peek (a_p);
24.172 + b.peek (b_p);
24.173 + for (uint8_t i = 0; i < 6; i++) {
24.174 + if (a_p[i] < b_p[i]) {
24.175 + return true;
24.176 + } else if (a_p[i] > b_p[i]) {
24.177 + return false;
24.178 + }
24.179 + }
24.180 + return false;
24.181 +}
24.182 +
24.183 +std::ostream& operator<< (std::ostream& os, MacAddress const& address)
24.184 +{
24.185 + address.print (&os);
24.186 + return os;
24.187 +}
24.188 +
24.189 +
24.190 +}; // namespace yans
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/src/common/mac-address.h Tue Aug 29 17:42:13 2006 +0200
25.3 @@ -0,0 +1,72 @@
25.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
25.5 +/*
25.6 + * Copyright (c) 2005 INRIA
25.7 + * All rights reserved.
25.8 + *
25.9 + * This program is free software; you can redistribute it and/or modify
25.10 + * it under the terms of the GNU General Public License version 2 as
25.11 + * published by the Free Software Foundation;
25.12 + *
25.13 + * This program is distributed in the hope that it will be useful,
25.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25.16 + * GNU General Public License for more details.
25.17 + *
25.18 + * You should have received a copy of the GNU General Public License
25.19 + * along with this program; if not, write to the Free Software
25.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25.21 + *
25.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
25.23 + */
25.24 +
25.25 +#ifndef MAC_ADDRESS_H
25.26 +#define MAC_ADDRESS_H
25.27 +
25.28 +#include <stdint.h>
25.29 +#include <ostream>
25.30 +
25.31 +namespace yans {
25.32 +
25.33 +class MacAddress {
25.34 +public:
25.35 + MacAddress (void);
25.36 + /* low byte should be first.
25.37 + */
25.38 + MacAddress (uint8_t const address[6]);
25.39 + /* The string should look like this:
25.40 + * hh-xx-xx-xx-xx-ll
25.41 + * where hh is the high byte and ll is
25.42 + * the low byte.
25.43 + */
25.44 + MacAddress (char const *address);
25.45 + /* create the mac address associated to
25.46 + * this multicast ip address.
25.47 + */
25.48 + MacAddress (uint32_t multicast_ip_address);
25.49 + ~MacAddress ();
25.50 +
25.51 + bool is_equal (MacAddress other) const;
25.52 + bool is_broadcast (void) const;
25.53 + bool is_multicast (void) const;
25.54 + bool is_multicast_equal (MacAddress other) const;
25.55 +
25.56 + void print (std::ostream *os) const;
25.57 +
25.58 + void peek (uint8_t ad[6]) const;
25.59 + void set (uint8_t const ad[6]);
25.60 +
25.61 + static MacAddress get_broadcast (void);
25.62 +private:
25.63 + uint32_t get_multicast_part (void) const;
25.64 + uint8_t m_address[6];
25.65 +};
25.66 +
25.67 +bool operator == (MacAddress const&a, MacAddress const&b);
25.68 +bool operator != (MacAddress const&a, MacAddress const&b);
25.69 +bool operator < (MacAddress const&a, MacAddress const&b);
25.70 +
25.71 +std::ostream& operator<< (std::ostream& os, MacAddress const& address);
25.72 +
25.73 +}; // namespace yans
25.74 +
25.75 +#endif /* MAC_ADDRESS_H */
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/src/common/mac-network-interface.cc Tue Aug 29 17:42:13 2006 +0200
26.3 @@ -0,0 +1,96 @@
26.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
26.5 +/*
26.6 + * Copyright (c) 2006 INRIA
26.7 + * All rights reserved.
26.8 + *
26.9 + * This program is free software; you can redistribute it and/or modify
26.10 + * it under the terms of the GNU General Public License version 2 as
26.11 + * published by the Free Software Foundation;
26.12 + *
26.13 + * This program is distributed in the hope that it will be useful,
26.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
26.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26.16 + * GNU General Public License for more details.
26.17 + *
26.18 + * You should have received a copy of the GNU General Public License
26.19 + * along with this program; if not, write to the Free Software
26.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26.21 + *
26.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
26.23 + */
26.24 +#include "mac-network-interface.h"
26.25 +
26.26 +namespace yans {
26.27 +
26.28 +MacNetworkInterface::MacNetworkInterface (MacAddress self, uint16_t max_mtu)
26.29 + : m_self (self), m_max_mtu (max_mtu), m_mtu (max_mtu)
26.30 +{}
26.31 +MacNetworkInterface::~MacNetworkInterface ()
26.32 +{}
26.33 +
26.34 +MacAddress
26.35 +MacNetworkInterface::get_mac_address (void) const
26.36 +{
26.37 + return m_self;
26.38 +}
26.39 +void
26.40 +MacNetworkInterface::set_mtu (uint16_t mtu)
26.41 +{
26.42 + if (mtu > m_max_mtu ) {
26.43 + m_mtu = m_max_mtu;
26.44 + } else {
26.45 + m_mtu = mtu;
26.46 + }
26.47 +}
26.48 +uint16_t
26.49 +MacNetworkInterface::get_mtu (void) const
26.50 +{
26.51 + return m_mtu;
26.52 +}
26.53 +bool
26.54 +MacNetworkInterface::is_down (void) const
26.55 +{
26.56 + return m_is_down;
26.57 +}
26.58 +void
26.59 +MacNetworkInterface::set_up (void)
26.60 +{
26.61 + m_is_down = false;
26.62 + notify_up ();
26.63 +}
26.64 +void
26.65 +MacNetworkInterface::set_down (void)
26.66 +{
26.67 + m_is_down = true;
26.68 + notify_down ();
26.69 +}
26.70 +
26.71 +void
26.72 +MacNetworkInterface::set_status_change_callback (StatusChangeCallback callback)
26.73 +{
26.74 + m_status_change_callback = callback;
26.75 +}
26.76 +
26.77 +void
26.78 +MacNetworkInterface::set_rx_callback (RxCallback callback)
26.79 +{
26.80 + m_rx_callback = callback;
26.81 +}
26.82 +void
26.83 +MacNetworkInterface::send (Packet packet, MacAddress to)
26.84 +{
26.85 + real_send (packet, to);
26.86 +}
26.87 +void
26.88 +MacNetworkInterface::forward_up (Packet packet)
26.89 +{
26.90 + m_rx_callback (packet, this);
26.91 +}
26.92 +
26.93 +void
26.94 +MacNetworkInterface::notify_status_change (void)
26.95 +{
26.96 + m_status_change_callback (this);
26.97 +}
26.98 +
26.99 +}; // namespace yans
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/src/common/mac-network-interface.h Tue Aug 29 17:42:13 2006 +0200
27.3 @@ -0,0 +1,68 @@
27.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
27.5 +/*
27.6 + * Copyright (c) 2006 INRIA
27.7 + * All rights reserved.
27.8 + *
27.9 + * This program is free software; you can redistribute it and/or modify
27.10 + * it under the terms of the GNU General Public License version 2 as
27.11 + * published by the Free Software Foundation;
27.12 + *
27.13 + * This program is distributed in the hope that it will be useful,
27.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27.16 + * GNU General Public License for more details.
27.17 + *
27.18 + * You should have received a copy of the GNU General Public License
27.19 + * along with this program; if not, write to the Free Software
27.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27.21 + *
27.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
27.23 + */
27.24 +#ifndef MAC_NETWORK_INTERFACE_H
27.25 +#define MAC_NETWORK_INTERFACE_H
27.26 +
27.27 +#include <stdint.h>
27.28 +#include "yans/callback.h"
27.29 +#include "mac-address.h"
27.30 +#include "packet.h"
27.31 +
27.32 +namespace yans {
27.33 +
27.34 +class MacNetworkInterface {
27.35 +public:
27.36 + typedef Callback<void, Packet , MacNetworkInterface *> RxCallback;
27.37 + typedef Callback<void,MacNetworkInterface *> StatusChangeCallback;
27.38 +
27.39 + MacNetworkInterface (MacAddress self, uint16_t max_mtu);
27.40 + virtual ~MacNetworkInterface () = 0;
27.41 +
27.42 + MacAddress get_mac_address (void) const;
27.43 + void set_mtu (uint16_t mtu);
27.44 + uint16_t get_mtu (void) const;
27.45 +
27.46 + bool is_down (void) const;
27.47 + void set_up (void);
27.48 + void set_down (void);
27.49 +
27.50 + void set_status_change_callback (StatusChangeCallback callback);
27.51 + void set_rx_callback (RxCallback callback);
27.52 + void send (Packet packet, MacAddress to);
27.53 +protected:
27.54 + void forward_up (Packet packet);
27.55 + void notify_status_change (void);
27.56 +private:
27.57 + virtual void notify_up (void) = 0;
27.58 + virtual void notify_down (void) = 0;
27.59 + virtual void real_send (Packet packet, MacAddress to) = 0;
27.60 +
27.61 + StatusChangeCallback m_status_change_callback;
27.62 + RxCallback m_rx_callback;
27.63 + MacAddress m_self;
27.64 + uint16_t m_max_mtu;
27.65 + uint16_t m_mtu;
27.66 + bool m_is_down;
27.67 +};
27.68 +
27.69 +}; // namespace yans
27.70 +
27.71 +#endif /* MAC_NETWORK_INTERFACE_H */
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/src/common/packet-logger.cc Tue Aug 29 17:42:13 2006 +0200
28.3 @@ -0,0 +1,42 @@
28.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
28.5 +/*
28.6 + * Copyright (c) 2006 INRIA
28.7 + * All rights reserved.
28.8 + *
28.9 + * This program is free software; you can redistribute it and/or modify
28.10 + * it under the terms of the GNU General Public License version 2 as
28.11 + * published by the Free Software Foundation;
28.12 + *
28.13 + * This program is distributed in the hope that it will be useful,
28.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28.16 + * GNU General Public License for more details.
28.17 + *
28.18 + * You should have received a copy of the GNU General Public License
28.19 + * along with this program; if not, write to the Free Software
28.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28.21 + *
28.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
28.23 + */
28.24 +
28.25 +#include "packet-logger.h"
28.26 +
28.27 +namespace yans {
28.28 +
28.29 +PacketLogger::PacketLogger ()
28.30 +{}
28.31 +void
28.32 +PacketLogger::log (Packet const packet)
28.33 +{
28.34 + if (!m_callback.is_null ()) {
28.35 + m_callback (packet);
28.36 + }
28.37 +}
28.38 +void
28.39 +PacketLogger::set_callback (PacketLoggerCallback callback)
28.40 +{
28.41 + m_callback = callback;
28.42 +}
28.43 +
28.44 +}; // namespace yans
28.45 +
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/src/common/packet-logger.h Tue Aug 29 17:42:13 2006 +0200
29.3 @@ -0,0 +1,53 @@
29.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
29.5 +/*
29.6 + * Copyright (c) 2006 INRIA
29.7 + * All rights reserved.
29.8 + *
29.9 + * This program is free software; you can redistribute it and/or modify
29.10 + * it under the terms of the GNU General Public License version 2 as
29.11 + * published by the Free Software Foundation;
29.12 + *
29.13 + * This program is distributed in the hope that it will be useful,
29.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29.16 + * GNU General Public License for more details.
29.17 + *
29.18 + * You should have received a copy of the GNU General Public License
29.19 + * along with this program; if not, write to the Free Software
29.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29.21 + *
29.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
29.23 + */
29.24 +
29.25 +#ifndef PACKET_LOGGER_H
29.26 +#define PACKET_LOGGER_H
29.27 +
29.28 +#include "yans/callback.h"
29.29 +#include "packet.h"
29.30 +
29.31 +namespace yans {
29.32 +
29.33 +/**
29.34 + * \brief log packets
29.35 + */
29.36 +class PacketLogger {
29.37 +public:
29.38 + typedef Callback<void,Packet const> PacketLoggerCallback;
29.39 + PacketLogger ();
29.40 + /**
29.41 + * \param packet to log
29.42 + * If a non-null callback was set, the packet
29.43 + * is forwarded to that callback.
29.44 + */
29.45 + void log (Packet const packet);
29.46 + /**
29.47 + * \param callback callback to store
29.48 + */
29.49 + void set_callback (PacketLoggerCallback callback);
29.50 +private:
29.51 + PacketLoggerCallback m_callback;
29.52 +};
29.53 +
29.54 +}; // namespace yans
29.55 +
29.56 +#endif /* PACKET_LOGGER_H */
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/src/common/packet.cc Tue Aug 29 17:42:13 2006 +0200
30.3 @@ -0,0 +1,127 @@
30.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
30.5 +/*
30.6 + * Copyright (c) 2005,2006 INRIA
30.7 + * All rights reserved.
30.8 + *
30.9 + * This program is free software; you can redistribute it and/or modify
30.10 + * it under the terms of the GNU General Public License version 2 as
30.11 + * published by the Free Software Foundation;
30.12 + *
30.13 + * This program is distributed in the hope that it will be useful,
30.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30.16 + * GNU General Public License for more details.
30.17 + *
30.18 + * You should have received a copy of the GNU General Public License
30.19 + * along with this program; if not, write to the Free Software
30.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30.21 + *
30.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
30.23 + */
30.24 +#include "packet.h"
30.25 +#include <cassert>
30.26 +
30.27 +namespace yans {
30.28 +
30.29 +Packet::Packet ()
30.30 + : m_buffer () {}
30.31 +
30.32 +Packet::Packet (uint32_t size)
30.33 + : m_buffer (size)
30.34 +{}
30.35 +Packet::Packet (Buffer buffer, Tags tags)
30.36 + : m_buffer (buffer),
30.37 + m_tags (tags)
30.38 +{}
30.39 +
30.40 +
30.41 +Packet
30.42 +Packet::create_fragment (uint32_t start, uint32_t length) const
30.43 +{
30.44 + Buffer tmp = m_buffer.create_fragment (start, length);
30.45 + return Packet (tmp, m_tags);
30.46 +}
30.47 +
30.48 +uint32_t
30.49 +Packet::get_size (void) const
30.50 +{
30.51 + return m_buffer.get_size ();
30.52 +}
30.53 +
30.54 +void
30.55 +Packet::add (Chunk *chunk)
30.56 +{
30.57 + chunk->add (&m_buffer);
30.58 +}
30.59 +
30.60 +void
30.61 +Packet::peek (Chunk *chunk) const
30.62 +{
30.63 + chunk->peek (&m_buffer);
30.64 +}
30.65 +
30.66 +void
30.67 +Packet::remove (Chunk *chunk)
30.68 +{
30.69 + chunk->remove (&m_buffer);
30.70 +}
30.71 +
30.72 +
30.73 +void
30.74 +Packet::write (PacketReadWriteCallback callback) const
30.75 +{
30.76 + uint8_t *data = m_buffer.peek_data ();
30.77 + uint32_t to_write = get_size ();
30.78 + callback (data, to_write);
30.79 +}
30.80 +
30.81 +
30.82 +void
30.83 +Packet::add_at_end (Packet packet)
30.84 +{
30.85 + Buffer src = packet.m_buffer;
30.86 + m_buffer.add_at_end (src.get_size ());
30.87 + Buffer::Iterator dest_start = m_buffer.end ();
30.88 + dest_start.prev (src.get_size ());
30.89 + dest_start.write (src.begin (), src.end ());
30.90 + /**
30.91 + * XXX: we might need to merge the tag list of the
30.92 + * other packet into the current packet.
30.93 + */
30.94 +}
30.95 +void
30.96 +Packet::add_at_end (Packet packet, uint32_t start, uint32_t size)
30.97 +{
30.98 + assert (packet.get_size () <= start + size);
30.99 + Buffer src = packet.m_buffer;
30.100 + m_buffer.add_at_end (src.get_size ());
30.101 + Buffer::Iterator dest_start = m_buffer.end ();
30.102 + dest_start.prev (size);
30.103 + Buffer::Iterator src_start = src.begin ();
30.104 + src_start.next (start);
30.105 + Buffer::Iterator src_end = src_start;
30.106 + src_end.next (size);
30.107 + dest_start.write (src_start, src_end);
30.108 + /**
30.109 + * XXX: we might need to merge the tag list of the
30.110 + * other packet into the current packet.
30.111 + */
30.112 +}
30.113 +void
30.114 +Packet::remove_at_end (uint32_t size)
30.115 +{
30.116 + m_buffer.remove_at_end (size);
30.117 +}
30.118 +void
30.119 +Packet::remove_at_start (uint32_t size)
30.120 +{
30.121 + m_buffer.remove_at_start (size);
30.122 +}
30.123 +
30.124 +void
30.125 +Packet::remove_all_tags (void)
30.126 +{
30.127 + m_tags.remove_all ();
30.128 +}
30.129 +
30.130 +}; // namespace yans
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/src/common/packet.h Tue Aug 29 17:42:13 2006 +0200
31.3 @@ -0,0 +1,90 @@
31.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
31.5 +/*
31.6 + * Copyright (c) 2005,2006 INRIA
31.7 + * All rights reserved.
31.8 + *
31.9 + * This program is free software; you can redistribute it and/or modify
31.10 + * it under the terms of the GNU General Public License version 2 as
31.11 + * published by the Free Software Foundation;
31.12 + *
31.13 + * This program is distributed in the hope that it will be useful,
31.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31.16 + * GNU General Public License for more details.
31.17 + *
31.18 + * You should have received a copy of the GNU General Public License
31.19 + * along with this program; if not, write to the Free Software
31.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31.21 + *
31.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
31.23 + */
31.24 +#ifndef PACKET_H
31.25 +#define PACKET_H
31.26 +
31.27 +#include <stdint.h>
31.28 +#include "buffer.h"
31.29 +#include "chunk.h"
31.30 +#include "tags.h"
31.31 +#include "yans/callback.h"
31.32 +
31.33 +namespace yans {
31.34 +
31.35 +class Packet {
31.36 +public:
31.37 + typedef Callback<void,uint8_t *,uint32_t> PacketReadWriteCallback;
31.38 + Packet ();
31.39 + Packet (uint32_t size);
31.40 + Packet create_fragment (uint32_t start, uint32_t length) const;
31.41 + uint32_t get_size (void) const;
31.42 + void add (Chunk *chunk);
31.43 + void peek (Chunk *chunk) const;
31.44 + void remove (Chunk *chunk);
31.45 + template <typename T>
31.46 + void add_tag (T const *tag);
31.47 + template <typename T>
31.48 + bool remove_tag (T *tag);
31.49 + template <typename T>
31.50 + bool peek_tag (T *tag) const;
31.51 + template <typename T>
31.52 + bool update_tag (T const*tag);
31.53 + void remove_all_tags (void);
31.54 + void write (PacketReadWriteCallback callback) const;
31.55 + void add_at_end (Packet packet);
31.56 + void add_at_end (Packet packet, uint32_t offset, uint32_t size);
31.57 + void remove_at_end (uint32_t size);
31.58 + void remove_at_start (uint32_t size);
31.59 +
31.60 +private:
31.61 + Packet (Buffer buffer, Tags tags);
31.62 + Buffer m_buffer;
31.63 + Tags m_tags;
31.64 +};
31.65 +
31.66 +}; // namespace yans
31.67 +
31.68 +namespace yans {
31.69 +
31.70 +template <typename T>
31.71 +void Packet::add_tag (T const*tag)
31.72 +{
31.73 + m_tags.add (tag);
31.74 +}
31.75 +template <typename T>
31.76 +bool Packet::remove_tag (T *tag)
31.77 +{
31.78 + return m_tags.remove (tag);
31.79 +}
31.80 +template <typename T>
31.81 +bool Packet::peek_tag (T *tag) const
31.82 +{
31.83 + return m_tags.peek (tag);
31.84 +}
31.85 +template <typename T>
31.86 +bool Packet::update_tag (T const*tag)
31.87 +{
31.88 + return m_tags.update (tag);
31.89 +}
31.90 +
31.91 +}; // namespace yans
31.92 +
31.93 +#endif /* PACKET_H */
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/src/common/pcap-writer.cc Tue Aug 29 17:42:13 2006 +0200
32.3 @@ -0,0 +1,99 @@
32.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
32.5 +/*
32.6 + * Copyright (c) 2005,2006 INRIA
32.7 + * All rights reserved.
32.8 + *
32.9 + * This program is free software; you can redistribute it and/or modify
32.10 + * it under the terms of the GNU General Public License version 2 as
32.11 + * published by the Free Software Foundation;
32.12 + *
32.13 + * This program is distributed in the hope that it will be useful,
32.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
32.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32.16 + * GNU General Public License for more details.
32.17 + *
32.18 + * You should have received a copy of the GNU General Public License
32.19 + * along with this program; if not, write to the Free Software
32.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32.21 + *
32.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
32.23 + */
32.24 +
32.25 +/*
32.26 + * Documentation kindly pointed out by Tom Henderson:
32.27 + * http://wiki.ethereal.com/Development/LibpcapFileFormat
32.28 + */
32.29 +
32.30 +#include "yans/simulator.h"
32.31 +#include "yans/system-file.h"
32.32 +#include "pcap-writer.h"
32.33 +#include "packet.h"
32.34 +
32.35 +
32.36 +namespace yans {
32.37 +
32.38 +enum {
32.39 + PCAP_ETHERNET = 1
32.40 +};
32.41 +
32.42 +PcapWriter::PcapWriter ()
32.43 +{
32.44 + m_writer = 0;
32.45 + m_write_callback = make_callback (&PcapWriter::write_data, this);
32.46 +}
32.47 +PcapWriter::~PcapWriter ()
32.48 +{
32.49 + delete m_writer;
32.50 +}
32.51 +
32.52 +void
32.53 +PcapWriter::open (char const *name)
32.54 +{
32.55 + m_writer = new SystemFile ();
32.56 + m_writer->open (name);
32.57 +}
32.58 +
32.59 +void
32.60 +PcapWriter::write_header_ethernet (void)
32.61 +{
32.62 + write_32 (0xa1b2c3d4);
32.63 + write_16 (2);
32.64 + write_16 (4);
32.65 + write_32 (0);
32.66 + write_32 (0);
32.67 + write_32 (0xffff);
32.68 + write_32 (PCAP_ETHERNET);
32.69 +}
32.70 +
32.71 +void
32.72 +PcapWriter::write_packet (Packet const packet)
32.73 +{
32.74 + if (m_writer != 0) {
32.75 + uint64_t current = Simulator::now_us ();
32.76 + uint64_t s = current / 1000000;
32.77 + uint64_t us = current % 1000000;
32.78 + write_32 (s & 0xffffffff);
32.79 + write_32 (us & 0xffffffff);
32.80 + write_32 (packet.get_size ());
32.81 + write_32 (packet.get_size ());
32.82 + packet.write (m_write_callback);
32.83 + }
32.84 +}
32.85 +
32.86 +void
32.87 +PcapWriter::write_data (uint8_t *buffer, uint32_t size)
32.88 +{
32.89 + m_writer->write (buffer, size);
32.90 +}
32.91 +void
32.92 +PcapWriter::write_32 (uint32_t data)
32.93 +{
32.94 + m_writer->write ((uint8_t*)&data, 4);
32.95 +}
32.96 +void
32.97 +PcapWriter::write_16 (uint16_t data)
32.98 +{
32.99 + m_writer->write ((uint8_t*)&data, 2);
32.100 +}
32.101 +
32.102 +}; // namespace yans
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/src/common/pcap-writer.h Tue Aug 29 17:42:13 2006 +0200
33.3 @@ -0,0 +1,73 @@
33.4 +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
33.5 +/*
33.6 + * Copyright (c) 2005,2006 INRIA
33.7 + * All rights reserved.
33.8 + *
33.9 + * This program is free software; you can redistribute it and/or modify
33.10 + * it under the terms of the GNU General Public License version 2 as
33.11 + * published by the Free Software Foundation;
33.12 + *
33.13 + * This program is distributed in the hope that it will be useful,
33.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
33.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33.16 + * GNU General Public License for more details.
33.17 + *
33.18 + * You should have received a copy of the GNU General Public License
33.19 + * along with this program; if not, write to the Free Software
33.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33.21 + *
33.22 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
33.23 + */
33.24 +
33.25 +#ifndef PCAP_WRITER_H
33.26 +#define PCAP_WRITER_H
33.27 +
33.28 +#include "yans/callback.h"
33.29 +#include <stdint.h>
33.30 +#include "packet.h"
33.31 +
33.32 +namespace yans {
33.33 +
33.34 +class SystemFile;
33.35 +
33.36 +/**
33.37 + * \brief Pcap output for Packet logger
33.38 + *
33.39 + * Log Packets to a file in pcap format which can be
33.40 + * read by pcap readers.
33.41 + */
33.42 +class PcapWriter {
33.43 +public:
33.44 + PcapWriter ();
33.45 + ~PcapWriter ();
33.46 +
33.47 + /**
33.48 + * \param name the name of the file to store packet log into.
33.49 + * This method creates the file if it does not exist. If it
33.50 + * exists, the file is emptied.
33.51 + */
33.52 + void open (char const *name);
33.53 +
33.54 + /**
33.55 + * Write a pcap header in the output file which specifies
33.56 + * that the content of the file will Packets with
33.57 + * Ethernet/LLC/SNAP encapsulation.
33.58 + */
33.59 + void write_header_ethernet (void);
33.60 +
33.61 + /**
33.62 + * \param packet packet to write to output file
33.63 + */
33.64 + void write_packet (Packet const packet);
33.65 +