import from yans
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue Aug 29 17:42:13 2006 +0200 (2006-08-29)
changeset 92c31ae7c94db
parent 8 cb4ae01ba180
child 10 e409dc8cb135
import from yans
src/common/buffer.cc
src/common/buffer.h
src/common/callback-logger.h
src/common/chunk-constant-data.cc
src/common/chunk-constant-data.h
src/common/chunk-llc-snap.cc
src/common/chunk-llc-snap.h
src/common/chunk-utils.cc
src/common/chunk-utils.h
src/common/chunk.cc
src/common/chunk.h
src/common/count-ptr-holder.tcc
src/common/data-writer.cc
src/common/data-writer.h
src/common/f-traced-variable.tcc
src/common/ipv4-address.cc
src/common/ipv4-address.h
src/common/ipv4-network-interface.cc
src/common/ipv4-network-interface.h
src/common/llc-snap-encapsulation.cc
src/common/llc-snap-encapsulation.h
src/common/mac-address-factory.cc
src/common/mac-address-factory.h
src/common/mac-address.cc
src/common/mac-address.h
src/common/mac-network-interface.cc
src/common/mac-network-interface.h
src/common/packet-logger.cc
src/common/packet-logger.h
src/common/packet.cc
src/common/packet.h
src/common/pcap-writer.cc
src/common/pcap-writer.h
src/common/population-analysis.cc
src/common/population-analysis.h
src/common/position.cc
src/common/position.h
src/common/random-uniform-mrg32k3a.cc
src/common/random-uniform.h
src/common/ref-ptr.h
src/common/rng-mrg32k3a.cc
src/common/rng-mrg32k3a.h
src/common/seed-generator-mrg32k3a.cc
src/common/seed-generator.h
src/common/sgi-hashmap.h
src/common/si-traced-variable.tcc
src/common/static-position.cc
src/common/static-position.h
src/common/static-speed-position.cc
src/common/static-speed-position.h
src/common/tags.cc
src/common/tags.h
src/common/timeout.cc
src/common/timeout.h
src/common/trace-container.cc
src/common/trace-container.h
src/common/trace-stream-test.cc
src/common/trace-stream.h
src/common/traced-variable-test.cc
src/common/ui-traced-variable.tcc
src/common/utils.cc
src/common/utils.h
src/core/callback-test.cc
src/core/callback.h
src/core/exec-commands.h
src/core/reference-list-test.cc
src/core/reference-list.h
src/core/system-file.h
src/core/system-mutex.h
src/core/system-semaphore.h
src/core/system-thread.h
src/core/test.cc
src/core/test.h
src/core/unix-exec-commands.cc
src/core/unix-system-file.cc
src/core/unix-system-mutex.cc
src/core/unix-system-semaphore.cc
src/core/unix-system-thread.cc
src/core/unix-wall-clock-ms.cc
src/core/wall-clock-ms.h
src/core/win32-system-file.cc
src/core/win32-system-mutex.cc
src/core/win32-system-semaphore.cc
src/core/win32-system-thread.cc
src/core/win32-wall-clock-ms.cc
src/simulator/event-impl.cc
src/simulator/event-impl.h
src/simulator/event-tcc-test.cc
src/simulator/event-tcc.cc
src/simulator/event.h
src/simulator/event.tcc
src/simulator/scheduler-heap.cc
src/simulator/scheduler-heap.h
src/simulator/scheduler-list.cc
src/simulator/scheduler-list.h
src/simulator/scheduler-map.cc
src/simulator/scheduler-map.h
src/simulator/scheduler.cc
src/simulator/scheduler.h
src/simulator/simulator.cc
src/simulator/simulator.h
     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 +