merge with trunk
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue, 28 Aug 2007 12:05:35 +0200
changeset 1376 ad7e61edfb9d
parent 1375 4f45bec005b8 (current diff)
parent 1299 394c16278532 (diff)
child 1377 2fcc78ee9558
merge with trunk
SConstruct
examples/csma-cd-one-subnet.cc
examples/csma-cd-packet-socket.cc
examples/simple-p2p.cc
src/common/packet.cc
src/devices/csma-cd/backoff.cc
src/devices/csma-cd/backoff.h
src/devices/csma-cd/csma-cd-channel.cc
src/devices/csma-cd/csma-cd-channel.h
src/devices/csma-cd/csma-cd-ipv4-topology.cc
src/devices/csma-cd/csma-cd-ipv4-topology.h
src/devices/csma-cd/csma-cd-net-device.cc
src/devices/csma-cd/csma-cd-net-device.h
src/devices/csma-cd/csma-cd-topology.cc
src/devices/csma-cd/csma-cd-topology.h
src/devices/csma-cd/wscript
src/devices/csma/csma-net-device.cc
src/devices/csma/csma-net-device.h
src/devices/point-to-point/point-to-point-net-device.cc
src/devices/point-to-point/point-to-point-net-device.h
src/internet-node/ascii-trace.cc
src/internet-node/ipv4-loopback-interface.cc
src/node/net-device.cc
src/node/net-device.h
src/routing/global-routing/global-route-manager-impl.cc
utils/print-trace-sources.cc
--- a/.hgtags	Tue Aug 28 11:22:01 2007 +0200
+++ b/.hgtags	Tue Aug 28 12:05:35 2007 +0200
@@ -3,3 +3,4 @@
 0dc81e76166c56aaae64da48b673b62155943aad packet-history-working
 38099dd26e9467b8f49f8632f22789858149a6e7 release ns-3.0.3
 5701e60bf01a8ac1308945e69001e0cc07948faf release ns-3.0.4
+08046b6aef37932507696a2f2f427b42d693781e release ns-3.0.5
--- a/AUTHORS	Tue Aug 28 11:22:01 2007 +0200
+++ b/AUTHORS	Tue Aug 28 12:05:35 2007 +0200
@@ -3,4 +3,5 @@
 Craig Dowell (craigdo@ee.washington.edu)
 Tom Henderson (tomhend@u.washington.edu)
 Mathieu Lacage (mathieu.lacage@sophia.inria.fr)
+Emmanuelle Laprise (emmmanuelle.laprise@bluekazoo.ca)
 George F. Riley (riley@ece.gatech.edu)
--- a/RELEASE_NOTES	Tue Aug 28 11:22:01 2007 +0200
+++ b/RELEASE_NOTES	Tue Aug 28 12:05:35 2007 +0200
@@ -3,12 +3,16 @@
 
 This file contains ns-3 release notes (most recent releases first).
 
-Release 3.0.5 (2007/08/XX)
+Release 3.0.5 (2007/08/15)
 ========================
 
-  - Add CSMA/CD model (Emmanuelle Laprise)
-  - Modularize ipv4 routing support (Gustavo Carneiro)
-  - Add mobility framework and basic mobility models
+  - Refactoring to support win32-based unix environments (Cygwin, mingw)
+  - "Packet socket" for allowing applications to access NetDevices directly
+  - Generalized, polymorphic Address class
+  - Add CSMA NetDevice model (from Emmanuelle Laprise)
+  - Modularize IPv4 routing support (from Gustavo Carneiro)
+  - Add mobility framework and basic mobility models 
+  - Global unicast centralized routing 
 
 Release 3.0.4 (2007/07/15)
 ========================
--- a/SConstruct	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,521 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-import os.path
-import build
-
-version_file = open ('VERSION', 'r')
-version = version_file.readline ()
-version_file.close ()
-version = version.strip ()
-
-ns3 = build.Ns3()
-ns3.build_dir = 'build-dir'
-ns3.version = version
-ns3.name = 'ns3'
-ns3.distname = 'ns'
-ns3.doxygen_config = os.path.join('doc', 'doxygen.conf')
-ns3.add_extra_dist(os.path.join('doc', 'main.txt'))
-ns3.add_extra_dist ('doc/architecture.pdf')
-ns3.add_extra_dist ('doc/contributing.txt')
-ns3.add_extra_dist ('doc/build.txt')
-ns3.add_extra_dist ('doc/codingstd.txt')
-ns3.add_extra_dist ('doc/mercurial.txt')
-ns3.add_extra_dist ('README')
-ns3.add_extra_dist ('RELEASE_NOTES')
-ns3.add_extra_dist ('AUTHORS')
-ns3.add_extra_dist ('VERSION')
-
-ns3.add_extra_dist('doc/build-waf.txt')
-ns3.add_extra_dist('ns3/_placeholder_')
-for wscript in [
-    "src/core/wscript",
-    "src/node/wscript",
-    "src/devices/p2p/wscript",
-    "src/common/wscript",
-    "src/applications/wscript",
-    "src/simulator/wscript",
-    "src/internet-node/wscript",
-    "src/wscript",
-    "utils/wscript",
-    "samples/wscript",
-    "examples/wscript",
-    "wscript",
-    ]:
-    ns3.add_extra_dist(wscript)
-ns3.add_extra_dist('waf')
-ns3.add_extra_dist('waf.bat')
-
-#
-# The Core module
-#
-core = build.Ns3Module('core', 'src/core')
-ns3.add(core)
-core.add_sources([
-    'callback-test.cc',
-    'debug.cc',
-    'assert.cc',
-    'ptr.cc',
-    'object.cc',
-    'test.cc',
-    'random-variable.cc',
-    'rng-stream.cc',
-    'uid-manager.cc',
-    'default-value.cc',
-    'command-line.cc',
-    'type-name.cc',
-    'component-manager.cc',
-    ])
-env = Environment()
-if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin':
-    core.add_external_dep('pthread')
-    core.add_sources([
-        'unix-system-wall-clock-ms.cc',
-        ])
-elif env['PLATFORM'] == 'win32':
-    core.add_sources([
-        'win32-system-wall-clock-ms.cc',
-        ])
-core.add_headers ([
-    'uid-manager.h',
-    'singleton.h',
-])
-core.add_inst_headers([
-    'system-wall-clock-ms.h',
-    'empty.h',
-    'callback.h',
-    'ptr.h',
-    'object.h',
-    'debug.h',
-    'assert.h',
-    'fatal-error.h',
-    'test.h',
-    'random-variable.h',
-    'rng-stream.h',
-    'default-value.h',
-    'command-line.h',
-    'type-name.h',
-    'component-manager.h',
-    ])
-
-def config_core (env, config):
-    retval = []
-    # XXX This check is primitive but it should be
-    # good enough for now.
-    if config.CheckCHeader ('stdlib.h') == 1:
-        retval.append ('#define HAVE_STDLIB_H 1')
-        retval.append ('#define HAVE_GETENV 1')
-    else:
-        retval.append ('#undef HAVE_STDLIB_H')
-        retval.append ('#undef HAVE_GETENV')
-    return retval
-core.add_config (config_core)
-
-#
-# The Simulator module
-#
-simu = build.Ns3Module('simulator', 'src/simulator')
-ns3.add(simu)
-simu.add_dep('core')
-simu.add_external_dep('m')
-simu.add_sources([
-    'high-precision.cc',
-    'time.cc',
-    'event-id.cc',
-    'scheduler.cc',
-    'scheduler-factory.cc',
-    'scheduler-list.cc',
-    'scheduler-heap.cc',
-    'scheduler-map.cc',
-    'event-impl.cc',
-    'simulator.cc',
-    ])
-simu.add_headers([
-    'scheduler-heap.h',
-    'scheduler-map.h',
-    'scheduler-list.h'
-    ])
-simu.add_inst_headers([
-    'high-precision.h',
-    'nstime.h',
-    'event-id.h',
-    'event-impl.h',
-    'simulator.h',
-    'scheduler.h',
-    'scheduler-factory.h',
-    'simulation-singleton.h',
-    ])
-high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n')
-if high_precision_as_double == 'y':
-    simu.add_inst_header ('high-precision-double.h')
-    simu.add_source ('high-precision-double.cc')
-else:
-    simu.add_inst_headers ([
-        'high-precision-128.h',
-        'cairo-wideint-private.h'
-        ])
-    simu.add_sources ([
-        'high-precision-128.cc',
-        'cairo-wideint.c',
-        ])
-
-def config_simulator (env, config):
-    retval = []
-    high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n')
-    if high_precision_as_double == 'y':
-        retval.append ('#define USE_HIGH_PRECISION_DOUBLE 1')
-    else:
-        retval.append ('#undef USE_HIGH_PRECISION_DOUBLE')
-    if config.CheckCHeader ('stdint.h') == 1:
-        retval.append ('#define HAVE_STDINT_H 1')
-    elif config.CheckCHeader ('inttypes.h') == 1:
-        retval.append ('#define HAVE_INTTYPES_H 1')
-    elif config.CheckCHeader ('sys/inttypes.h') == 1:
-        retval.append ('#define HAVE_SYS_INT_TYPES_H 1')
-    return retval
-simu.add_config (config_simulator)
-    
-#
-# The Common module
-#
-common = build.Ns3Module('common', 'src/common')
-common.add_deps(['core', 'simulator'])
-ns3.add(common)
-common.add_sources([
-    'buffer.cc',
-    'chunk.cc',
-    'header.cc',
-    'trailer.cc',
-    'packet-printer.cc',
-    'packet-metadata.cc',
-    'packet.cc',
-    'tags.cc',
-    'pcap-writer.cc',
-    'variable-tracer-test.cc',
-    'trace-context.cc',
-    'trace-resolver.cc',
-    'callback-trace-source.cc',
-    'empty-trace-resolver.cc',
-    'composite-trace-resolver.cc',
-    'trace-root.cc',
-    'data-rate.cc',
-    ])
-common.add_headers ([
-    ])
-common.add_inst_headers([
-    'buffer.h',
-    'chunk.h',
-    'header.h',
-    'trailer.h',
-    'tags.h',
-    'packet.h',
-    'packet-printer.h',
-    'packet-metadata.h',
-    'uv-trace-source.h',
-    'sv-trace-source.h',
-    'fv-trace-source.h',
-    'pcap-writer.h',
-    'callback-trace-source.h',
-    'trace-context.h',
-    'trace-resolver.h',
-    'empty-trace-resolver.h',
-    'composite-trace-resolver.h',
-    'array-trace-resolver.h',
-    'trace-root.h',
-    'terminal-trace-resolver.h',
-    'data-rate.h',
-    ])
-
-#
-# The Node module
-#
-node = build.Ns3Module ('node', 'src/node')
-ns3.add (node)
-node.add_deps (['core', 'common', 'simulator'])
-node.add_sources ([
-    'node.cc',
-    'ipv4-address.cc',
-    'net-device.cc',
-    'mac-address.cc',
-    'llc-snap-header.cc',
-    'ipv4-route.cc',
-    'queue.cc',
-    'drop-tail-queue.cc',
-    'channel.cc',
-    'node-list.cc',
-    'socket.cc',
-    'socket-factory.cc',
-    'udp.cc',
-    'ipv4.cc',
-    'application.cc',
-    ])
-node.add_inst_headers ([
-    'node.h',
-    'ipv4-address.h',
-    'net-device.h',
-    'mac-address.h',
-    'ipv4-route.h',
-    'queue.h',
-    'drop-tail-queue.h',
-    'llc-snap-header.h',
-    'channel.h',
-    'node-list.h',
-    'socket.h',
-    'socket-factory.h',
-    'udp.h',
-    'ipv4.h',
-    'application.h',
-    ])
-
-#
-# The Applications module
-#
-applications = build.Ns3Module ('applications', 'src/applications')
-ns3.add (applications)
-applications.add_deps (['node'])
-applications.add_sources ([
-    'onoff-application.cc',
-])
-applications.add_inst_headers ([
-    'onoff-application.h',
-])
-
-#
-# The Internet Node module
-#
-inode = build.Ns3Module ('internet-node', 'src/internet-node')
-ns3.add (inode)
-inode.add_deps (['node', 'routing'])
-inode.add_sources ([
-    'internet-node.cc',
-    'l3-demux.cc',
-    'l3-protocol.cc',
-    'ipv4-l4-demux.cc',
-    'ipv4-l4-protocol.cc',
-    'ipv4-header.cc',
-    'udp-header.cc',
-    'ipv4-checksum.cc',
-    'ipv4-interface.cc',
-    'ipv4-l3-protocol.cc',
-    'ipv4-end-point.cc',
-    'udp-l4-protocol.cc',
-    'arp-header.cc',
-    'arp-cache.cc',
-    'arp-ipv4-interface.cc',
-    'arp-l3-protocol.cc',
-    'ipv4-loopback-interface.cc',
-    'header-utils.cc',
-    'udp-socket.cc',
-    'ipv4-end-point-demux.cc',
-    'arp-private.cc',
-    'ipv4-impl.cc',
-    'ipv4-private.cc',
-    'ascii-trace.cc',
-    'pcap-trace.cc',
-    'udp-impl.cc',
-])
-inode.add_headers ([
-    'ipv4-checksum.h',
-    'arp-header.h',
-    'arp-cache.h',
-    'arp-l3-protocol.h',
-    'ipv4-loopback-interface.h',
-    'l3-demux.h',
-    'header-utils.h',
-    'arp-ipv4-interface.h',
-    'udp-socket.h',
-    'udp-l4-protocol.h',
-    'arp-private.h',
-    'ipv4-impl.h',
-    'ipv4-private.h',
-    'ipv4-l3-protocol.h',
-    'l3-protocol.h',
-    'ipv4-l4-protocol.h',
-    'ipv4-l4-demux.h',
-    'ipv4-end-point-demux.h',
-    'ipv4-end-point.h',
-    'ipv4-header.h',
-    'ipv4-interface.h',
-    'udp-header.h',
-    'sgi-hashmap.h',
-    'udp-impl.h',
-])
-inode.add_inst_headers ([
-    'internet-node.h',
-    'ascii-trace.h',
-    'pcap-trace.h',
-    'ipv4-header.h',
-    'udp-header.h',
-])
-
-#
-# The Point-to-point module
-#
-p2p = build.Ns3Module ('p2p', 'src/devices/p2p')
-ns3.add (p2p)
-p2p.add_deps (['node'])
-p2p.add_sources ([
-    'p2p-net-device.cc',
-    'p2p-channel.cc',
-    'p2p-topology.cc',
-    ])
-p2p.add_inst_headers ([
-    'p2p-net-device.h',
-    'p2p-channel.h',
-    'p2p-topology.h',
-    ])
-
-#
-# The Routing module
-#
-routing = build.Ns3Module('routing', 'src/routing')
-routing.add_deps(['core', 'node'])
-ns3.add(routing)
-routing.add_sources([
-    'routing-environment.cc',
-    'static-router.cc',
-    'static-route-manager.cc',
-    'static-route-manager-impl.cc',
-    'candidate-queue.cc',
-    ])
-routing.add_headers ([
-    'candidate-queue.h',
-    'static-route-manager-impl.h',
-    ])
-routing.add_inst_headers([
-    'routing-environment.h',
-    'static-router.h',
-    'static-route-manager.h',
-    ])
-
-# utils
-run_tests = build.Ns3Module('run-tests', 'utils')
-ns3.add(run_tests)
-run_tests.set_executable()
-run_tests.add_deps(['core', 'simulator', 'common', 'routing'])
-run_tests.add_source('run-tests.cc')
-
-bench_object = build.Ns3Module('bench-object', 'utils')
-ns3.add(bench_object)
-bench_object.set_executable()
-bench_object.add_deps(['core'])
-bench_object.add_source('bench-object.cc')
-
-bench_packets = build.Ns3Module('bench-packets', 'utils')
-ns3.add(bench_packets)
-bench_packets.set_executable()
-bench_packets.add_deps (['core', 'common'])
-bench_packets.add_source('bench-packets.cc')
-
-bench_simu = build.Ns3Module('bench-simulator', 'utils')
-ns3.add(bench_simu)
-bench_simu.set_executable()
-bench_simu.add_dep('simulator')
-bench_simu.add_source('bench-simulator.cc')
-
-replay_simu = build.Ns3Module('replay-simulation', 'utils')
-ns3.add(replay_simu)
-replay_simu.set_executable()
-replay_simu.add_dep('simulator')
-replay_simu.add_source('replay-simulation.cc')
-
-
-# samples
-sample_debug = build.Ns3Module('sample-debug', 'samples')
-sample_debug.set_executable()
-ns3.add(sample_debug)
-sample_debug.add_dep('core')
-sample_debug.add_source('main-debug.cc')
-sample_debug.add_source('main-debug-other.cc')
-
-sample_packet_printer = build.Ns3Module('sample-packet-printer', 'samples')
-sample_packet_printer.set_executable()
-ns3.add(sample_packet_printer)
-sample_packet_printer.add_deps (['common', 'internet-node'])
-sample_packet_printer.add_source('main-packet-printer.cc')
-
-sample_callback = build.Ns3Module('sample-callback', 'samples')
-sample_callback.set_executable()
-ns3.add(sample_callback)
-sample_callback.add_dep('core')
-sample_callback.add_source('main-callback.cc')
-
-sample_ptr = build.Ns3Module('sample-ptr', 'samples')
-sample_ptr.set_executable()
-ns3.add(sample_ptr)
-sample_ptr.add_dep('core')
-sample_ptr.add_source('main-ptr.cc')
-
-sample_trace = build.Ns3Module('sample-trace', 'samples')
-#ns3.add(sample_trace)
-sample_trace.add_dep('common')
-sample_trace.set_executable()
-sample_trace.add_source('main-trace.cc')
-
-sample_query_interface = build.Ns3Module('sample-query-interface', 'samples')
-ns3.add(sample_query_interface)
-sample_query_interface.add_dep('common')
-sample_query_interface.set_executable()
-sample_query_interface.add_source('main-query-interface.cc')
-
-sample_simu = build.Ns3Module('sample-simulator', 'samples')
-ns3.add(sample_simu)
-sample_simu.set_executable()
-sample_simu.add_dep('simulator')
-sample_simu.add_source('main-simulator.cc')
-
-sample_packet = build.Ns3Module('sample-packet', 'samples')
-ns3.add(sample_packet)
-sample_packet.set_executable()
-sample_packet.add_dep('common')
-sample_packet.add_source('main-packet.cc')
-
-sample_test = build.Ns3Module('sample-test', 'samples')
-sample_test.set_executable()
-ns3.add(sample_test)
-sample_test.add_dep('core')
-sample_test.add_source('main-test.cc')
-
-sample_simple = build.Ns3Module('sample-simple', 'samples')
-sample_simple.set_executable()
-ns3.add(sample_simple)
-sample_simple.add_deps(['core', 'simulator', 'node', 'internet-node', 'routing'])
-sample_simple.add_source('main-simple.cc')
-
-sample_sp2p = build.Ns3Module('sample-simple-p2p', 'samples')
-sample_sp2p.set_executable()
-#n3.add(sample_sp2p)
-sample_sp2p.add_deps(['core', 'simulator', 'node', 'internet-node', 'p2p'])
-sample_sp2p.add_source('main-simple-p2p.cc')
-
-sample_default_value = build.Ns3Module('sample-default-value', 'samples')
-sample_default_value.set_executable()
-ns3.add(sample_default_value)
-sample_default_value.add_deps(['core', 'simulator', 'node', 'p2p'])
-sample_default_value.add_source('main-default-value.cc')
-
-sample_object = build.Ns3Module('sample-object', 'samples')
-sample_object.set_executable()
-ns3.add(sample_object)
-sample_object.add_deps(['core'])
-sample_object.add_source('main-object.cc')
-
-sample_component_manager = build.Ns3Module('sample-component-manager', 'samples')
-sample_component_manager.set_executable()
-ns3.add(sample_component_manager)
-sample_component_manager.add_deps(['core'])
-sample_component_manager.add_source('main-component-manager.cc')
-
-# examples
-example_simple_p2p = build.Ns3Module('simple-p2p', 'examples')
-example_simple_p2p.set_executable()
-ns3.add(example_simple_p2p)
-example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications', 'routing'])
-example_simple_p2p.add_source('simple-p2p.cc')
-
-example_static_routing = build.Ns3Module('simple-static-routing', 'examples')
-example_static_routing.set_executable()
-ns3.add(example_static_routing)
-example_static_routing.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications', 'routing'])
-example_static_routing.add_source('simple-static-routing.cc')
-
-ns3.generate_dependencies()
--- a/VERSION	Tue Aug 28 11:22:01 2007 +0200
+++ b/VERSION	Tue Aug 28 12:05:35 2007 +0200
@@ -1,1 +1,1 @@
-3.0.4
+3.0.5
--- a/doc/release_steps.txt	Tue Aug 28 11:22:01 2007 +0200
+++ b/doc/release_steps.txt	Tue Aug 28 12:05:35 2007 +0200
@@ -5,23 +5,20 @@
    - revise and check in RELEASE_NOTES
    - update and check in VERSION to the latest release number
 2. make a new "architecture.pdf" document and place it in the doc/ directory
-3. add current version of waf script from subversion:
-   - svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf
-   - build waf script and put it into top of ns-3-dev
-4. cd ns-3-dev; ./waf configure; ./waf dist
-5. test tarball on release platforms (run-tests and simple-p2p)
-6. tag ns-3-dev with "release ns-3.0.X"
+3. cd ns-3-dev; ./waf configure; ./waf dist
+4. test tarball on release platforms (waf check and maybe some other scripts)
+5. tag ns-3-dev with "release ns-3.0.X"
   - hg tag "release ns-3.0.x"
   - hg push 
-7. clone the tagged ns-3-dev and place it on the repository
+6. clone the tagged ns-3-dev and place it on the repository
   - ssh code.nsnam.org; sudo; su code;
   - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x
   - cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately
-8. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server
-9. update web page
+7. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server
+8. update web page
    - add link to news.html
    - update download.html
    - update roadmap.html
    - build and update Doxygen directory on the server
    - update and upload software architecture document (PDF, HTML)
-10. announce to ns-developers, with summary of release notes
+9. announce to ns-developers, with summary of release notes
--- a/examples/csma-cd-one-subnet.cc	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
-//
-// Network topology
-//
-//       n0    n1   n2   n3
-//       |     |    |    |
-//     =====================
-//
-// - CBR/UDP flows from n0 to n1, and from n3 to n0
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-//   (i.e., DataRate of 448,000 bps)
-// - DropTail queues 
-// - Tracing of queues and packet receptions to file "csma-cd-one-subnet.tr"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cassert>
-
-#include "ns3/command-line.h"
-#include "ns3/default-value.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-#include "ns3/debug.h"
-
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-#include "ns3/ascii-trace.h"
-#include "ns3/pcap-trace.h"
-#include "ns3/internet-node.h"
-#include "ns3/csma-cd-channel.h"
-#include "ns3/csma-cd-net-device.h"
-#include "ns3/csma-cd-topology.h"
-#include "ns3/csma-cd-ipv4-topology.h"
-#include "ns3/eui48-address.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/socket.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/onoff-application.h"
-
-
-using namespace ns3;
-
-
-int main (int argc, char *argv[])
-{
-
-  // Users may find it convenient to turn on explicit debugging
-  // for selected modules; the below lines suggest how to do this
-#if 0 
-  DebugComponentEnable("CsmaCdNetDevice");
-  DebugComponentEnable("Ipv4L3Protocol");
-  DebugComponentEnable("NetDevice");
-  DebugComponentEnable("Channel");
-  DebugComponentEnable("CsmaCdChannel");
-  DebugComponentEnable("PacketSocket");
-#endif
-
-  // Set up some default values for the simulation.  Use the Bind()
-  // technique to tell the system what subclass of Queue to use,
-  // and what the queue limit is
-
-  // The below Bind command tells the queue factory which class to
-  // instantiate, when the queue factory is invoked in the topology code
-  DefaultValue::Bind ("Queue", "DropTailQueue");
-
-  // Allow the user to override any of the defaults and the above
-  // Bind()s at run-time, via command-line arguments
-  CommandLine::Parse (argc, argv);
-
-  // Here, we will explicitly create four nodes.  In more sophisticated
-  // topologies, we could configure a node factory.
-  Ptr<Node> n0 = Create<InternetNode> ();
-  Ptr<Node> n1 = Create<InternetNode> (); 
-  Ptr<Node> n2 = Create<InternetNode> (); 
-  Ptr<Node> n3 = Create<InternetNode> ();
-
-  // We create the channels first without any IP addressing information
-  Ptr<CsmaCdChannel> channel0 = 
-    CsmaCdTopology::CreateCsmaCdChannel(
-      DataRate(5000000), MilliSeconds(2));
-
-  uint32_t n0ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0, 
-                                         Eui48Address("10:54:23:54:23:50"));
-  uint32_t n1ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0,
-                                         Eui48Address("10:54:23:54:23:51"));
-  uint32_t n2ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0,
-                                         Eui48Address("10:54:23:54:23:52"));
-  uint32_t n3ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0,
-                                         Eui48Address("10:54:23:54:23:53"));
-
-  // Later, we add IP addresses.  
-  CsmaCdIpv4Topology::AddIpv4Address (
-      n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
-
-  CsmaCdIpv4Topology::AddIpv4Address (
-      n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
-
-  CsmaCdIpv4Topology::AddIpv4Address (
-      n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
-  
-  CsmaCdIpv4Topology::AddIpv4Address (
-      n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
-
-  // Create the OnOff application to send UDP datagrams of size
-  // 210 bytes at a rate of 448 Kb/s
-  // from n0 to n1
-  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
-    n0, 
-    InetSocketAddress ("10.1.1.2", 80), 
-    "Udp",
-    ConstantVariable(1), 
-    ConstantVariable(0));
-  // Start the application
-  ooff->Start(Seconds(1.0));
-  ooff->Stop (Seconds(10.0));
-
-  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
-  ooff = Create<OnOffApplication> (
-    n3, 
-    InetSocketAddress ("10.1.1.1", 80), 
-    "Udp",
-    ConstantVariable(1), 
-    ConstantVariable(0));
-  // Start the application
-  ooff->Start(Seconds(1.1));
-  ooff->Stop (Seconds(10.0));
- 
-  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
-  // Trace output will be sent to the csma-cd-one-subnet.tr file
-  AsciiTrace asciitrace ("csma-cd-one-subnet.tr");
-  asciitrace.TraceAllNetDeviceRx ();
-  asciitrace.TraceAllQueues ();
-
-  // Also configure some tcpdump traces; each interface will be traced
-  // The output files will be named 
-  // simple-point-to-point.pcap-<nodeId>-<interfaceId>
-  // and can be read by the "tcpdump -r" command (use "-tt" option to
-  // display timestamps correctly)
-  PcapTrace pcaptrace ("csma-cd-one-subnet.pcap");
-  pcaptrace.TraceAllIp ();
-
-  Simulator::Run ();
-    
-  Simulator::Destroy ();
-}
--- a/examples/csma-cd-packet-socket.cc	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
-//
-// Network topology
-//
-//       n0    n1   n2   n3
-//       |     |    |    |
-//     =====================
-//
-// - CBR/UDP flows from n0 to n1, and from n3 to n0
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-//   (i.e., DataRate of 448,000 bps)
-// - DropTail queues 
-// - Tracing of queues and packet receptions to file "csma-cd-one-subnet.tr"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cassert>
-
-#include "ns3/command-line.h"
-#include "ns3/default-value.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-#include "ns3/debug.h"
-
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-#include "ns3/ascii-trace.h"
-#include "ns3/pcap-trace.h"
-#include "ns3/internet-node.h"
-#include "ns3/csma-cd-channel.h"
-#include "ns3/csma-cd-net-device.h"
-#include "ns3/eui48-address.h"
-#include "ns3/packet-socket-address.h"
-#include "ns3/socket.h"
-#include "ns3/onoff-application.h"
-#include "ns3/queue.h"
-
-using namespace ns3;
-
-static Ptr<CsmaCdNetDevice>
-CreateCsmaCdDevice (Ptr<Node> node, Ptr<CsmaCdChannel> channel)
-{
-  Ptr<CsmaCdNetDevice> device = Create<CsmaCdNetDevice> (node);
-  device->Attach (channel);
-  Ptr<Queue> queue = Queue::CreateDefault ();
-  device->AddQueue (queue);
-  return device;
-}
-
-
-int main (int argc, char *argv[])
-{
-  CommandLine::Parse (argc, argv);
-
-  // Here, we will explicitly create four nodes.  In more sophisticated
-  // topologies, we could configure a node factory.
-  Ptr<Node> n0 = Create<Node> ();
-  Ptr<Node> n1 = Create<Node> (); 
-  Ptr<Node> n2 = Create<Node> (); 
-  Ptr<Node> n3 = Create<Node> ();
-
-  // create the shared medium used by all csma/cd devices.
-  Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (DataRate(5000000), MilliSeconds(2));
-
-  // use a helper function to connect our nodes to the shared channel.
-  Ptr<NetDevice> n0If = CreateCsmaCdDevice (n0, channel);
-  Ptr<NetDevice> n1If = CreateCsmaCdDevice (n1, channel);
-  Ptr<NetDevice> n2If = CreateCsmaCdDevice (n2, channel);
-  Ptr<NetDevice> n3If = CreateCsmaCdDevice (n3, channel);
-
-
-  // create the address which identifies n1 from n0
-  PacketSocketAddress n0ToN1;
-  n0ToN1.SetSingleDevice (n0If->GetIfIndex ());      // set outgoing interface for outgoing packets
-  n0ToN1.SetPhysicalAddress (n1If->GetAddress ()); // set destination address for outgoing packets
-  n0ToN1.SetProtocol (2);            // set arbitrary protocol for outgoing packets
-
-  // create the address which identifies n0 from n3
-  PacketSocketAddress n3ToN0;
-  n3ToN0.SetSingleDevice (n3If->GetIfIndex ());
-  n3ToN0.SetPhysicalAddress (n0If->GetAddress ());
-  n3ToN0.SetProtocol (3);
-  
-  // Create the OnOff application to send raw datagrams of size
-  // 210 bytes at a rate of 448 Kb/s
-  // from n0 to n1
-  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
-    n0, 
-    n0ToN1,
-    "Packet",
-    ConstantVariable(1), 
-    ConstantVariable(0));
-  // Start the application
-  ooff->Start(Seconds(1.0));
-  ooff->Stop (Seconds(10.0));
-
-  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
-  ooff = Create<OnOffApplication> (
-    n3, 
-    n3ToN0,
-    "Packet",
-    ConstantVariable(1), 
-    ConstantVariable(0));
-  // Start the application
-  ooff->Start(Seconds(1.1));
-  ooff->Stop (Seconds(10.0));
- 
-  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
-  // Trace output will be sent to the csma-cd-packet-socket.tr file
-  AsciiTrace asciitrace ("csma-cd-packet-socket.tr");
-  asciitrace.TraceAllNetDeviceRx ();
-  asciitrace.TraceAllQueues ();
-
-  Simulator::Run ();
-    
-  Simulator::Destroy ();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/csma-one-subnet.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,166 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Network topology
+//
+//       n0    n1   n2   n3
+//       |     |    |    |
+//     =====================
+//
+// - CBR/UDP flows from n0 to n1, and from n3 to n0
+// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
+//   (i.e., DataRate of 448,000 bps)
+// - DropTail queues 
+// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "ns3/debug.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-channel.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/csma-topology.h"
+#include "ns3/csma-ipv4-topology.h"
+#include "ns3/eui48-address.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/socket.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/onoff-application.h"
+
+
+using namespace ns3;
+
+
+int main (int argc, char *argv[])
+{
+
+  // Users may find it convenient to turn on explicit debugging
+  // for selected modules; the below lines suggest how to do this
+#if 0 
+  DebugComponentEnable("CsmaNetDevice");
+  DebugComponentEnable("Ipv4L3Protocol");
+  DebugComponentEnable("NetDevice");
+  DebugComponentEnable("Channel");
+  DebugComponentEnable("CsmaChannel");
+  DebugComponentEnable("PacketSocket");
+#endif
+
+  // Set up some default values for the simulation.  Use the Bind()
+  // technique to tell the system what subclass of Queue to use,
+  // and what the queue limit is
+
+  // The below Bind command tells the queue factory which class to
+  // instantiate, when the queue factory is invoked in the topology code
+  DefaultValue::Bind ("Queue", "DropTailQueue");
+
+  // Allow the user to override any of the defaults and the above
+  // Bind()s at run-time, via command-line arguments
+  CommandLine::Parse (argc, argv);
+
+  // Here, we will explicitly create four nodes.  In more sophisticated
+  // topologies, we could configure a node factory.
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> (); 
+  Ptr<Node> n2 = Create<InternetNode> (); 
+  Ptr<Node> n3 = Create<InternetNode> ();
+
+  // We create the channels first without any IP addressing information
+  Ptr<CsmaChannel> channel0 = 
+    CsmaTopology::CreateCsmaChannel(
+      DataRate(5000000), MilliSeconds(2));
+
+  uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, 
+                                         Eui48Address("10:54:23:54:23:50"));
+  uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0,
+                                         Eui48Address("10:54:23:54:23:51"));
+  uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0,
+                                         Eui48Address("10:54:23:54:23:52"));
+  uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0,
+                                         Eui48Address("10:54:23:54:23:53"));
+
+  // Later, we add IP addresses.  
+  CsmaIpv4Topology::AddIpv4Address (
+      n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
+
+  CsmaIpv4Topology::AddIpv4Address (
+      n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
+
+  CsmaIpv4Topology::AddIpv4Address (
+      n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
+  
+  CsmaIpv4Topology::AddIpv4Address (
+      n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
+
+  // Create the OnOff application to send UDP datagrams of size
+  // 210 bytes at a rate of 448 Kb/s
+  // from n0 to n1
+  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+    n0, 
+    InetSocketAddress ("10.1.1.2", 80), 
+    "Udp",
+    ConstantVariable(1), 
+    ConstantVariable(0));
+  // Start the application
+  ooff->Start(Seconds(1.0));
+  ooff->Stop (Seconds(10.0));
+
+  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
+  ooff = Create<OnOffApplication> (
+    n3, 
+    InetSocketAddress ("10.1.1.1", 80), 
+    "Udp",
+    ConstantVariable(1), 
+    ConstantVariable(0));
+  // Start the application
+  ooff->Start(Seconds(1.1));
+  ooff->Stop (Seconds(10.0));
+ 
+  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+  // Trace output will be sent to the csma-one-subnet.tr file
+  AsciiTrace asciitrace ("csma-one-subnet.tr");
+  asciitrace.TraceAllNetDeviceRx ();
+  asciitrace.TraceAllQueues ();
+
+  // Also configure some tcpdump traces; each interface will be traced
+  // The output files will be named 
+  // simple-point-to-point.pcap-<nodeId>-<interfaceId>
+  // and can be read by the "tcpdump -r" command (use "-tt" option to
+  // display timestamps correctly)
+  PcapTrace pcaptrace ("csma-one-subnet.pcap");
+  pcaptrace.TraceAllIp ();
+
+  Simulator::Run ();
+    
+  Simulator::Destroy ();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/csma-packet-socket.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,136 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Network topology
+//
+//       n0    n1   n2   n3
+//       |     |    |    |
+//     =====================
+//
+// - CBR/UDP flows from n0 to n1, and from n3 to n0
+// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
+//   (i.e., DataRate of 448,000 bps)
+// - DropTail queues 
+// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "ns3/debug.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-channel.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/eui48-address.h"
+#include "ns3/packet-socket-address.h"
+#include "ns3/socket.h"
+#include "ns3/onoff-application.h"
+#include "ns3/queue.h"
+
+using namespace ns3;
+
+static Ptr<CsmaNetDevice>
+CreateCsmaDevice (Ptr<Node> node, Ptr<CsmaChannel> channel)
+{
+  Ptr<CsmaNetDevice> device = Create<CsmaNetDevice> (node);
+  device->Attach (channel);
+  Ptr<Queue> queue = Queue::CreateDefault ();
+  device->AddQueue (queue);
+  return device;
+}
+
+
+int main (int argc, char *argv[])
+{
+  CommandLine::Parse (argc, argv);
+
+  // Here, we will explicitly create four nodes.  In more sophisticated
+  // topologies, we could configure a node factory.
+  Ptr<Node> n0 = Create<Node> ();
+  Ptr<Node> n1 = Create<Node> (); 
+  Ptr<Node> n2 = Create<Node> (); 
+  Ptr<Node> n3 = Create<Node> ();
+
+  // create the shared medium used by all csma devices.
+  Ptr<CsmaChannel> channel = Create<CsmaChannel> (DataRate(5000000), MilliSeconds(2));
+
+  // use a helper function to connect our nodes to the shared channel.
+  Ptr<NetDevice> n0If = CreateCsmaDevice (n0, channel);
+  Ptr<NetDevice> n1If = CreateCsmaDevice (n1, channel);
+  Ptr<NetDevice> n2If = CreateCsmaDevice (n2, channel);
+  Ptr<NetDevice> n3If = CreateCsmaDevice (n3, channel);
+
+
+  // create the address which identifies n1 from n0
+  PacketSocketAddress n0ToN1;
+  n0ToN1.SetSingleDevice (n0If->GetIfIndex ());      // set outgoing interface for outgoing packets
+  n0ToN1.SetPhysicalAddress (n1If->GetAddress ()); // set destination address for outgoing packets
+  n0ToN1.SetProtocol (2);            // set arbitrary protocol for outgoing packets
+
+  // create the address which identifies n0 from n3
+  PacketSocketAddress n3ToN0;
+  n3ToN0.SetSingleDevice (n3If->GetIfIndex ());
+  n3ToN0.SetPhysicalAddress (n0If->GetAddress ());
+  n3ToN0.SetProtocol (3);
+  
+  // Create the OnOff application to send raw datagrams of size
+  // 210 bytes at a rate of 448 Kb/s
+  // from n0 to n1
+  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+    n0, 
+    n0ToN1,
+    "Packet",
+    ConstantVariable(1), 
+    ConstantVariable(0));
+  // Start the application
+  ooff->Start(Seconds(1.0));
+  ooff->Stop (Seconds(10.0));
+
+  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
+  ooff = Create<OnOffApplication> (
+    n3, 
+    n3ToN0,
+    "Packet",
+    ConstantVariable(1), 
+    ConstantVariable(0));
+  // Start the application
+  ooff->Start(Seconds(1.1));
+  ooff->Stop (Seconds(10.0));
+ 
+  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+  // Trace output will be sent to the csma-packet-socket.tr file
+  AsciiTrace asciitrace ("csma-packet-socket.tr");
+  asciitrace.TraceAllNetDeviceRx ();
+  asciitrace.TraceAllQueues ();
+
+  Simulator::Run ();
+    
+  Simulator::Destroy ();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mixed-global-routing.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,199 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+// This script exercises global routing code in a mixed point-to-point
+// and csma/cd environment
+//
+// Network topology
+//
+//  n0
+//     \ p-p
+//      \          (shared csma/cd)
+//       n2 -------------------------n3
+//      /            |        | 
+//     / p-p        n4        n5 ---------- n6
+//   n1                             p-p
+//
+// - CBR/UDP flows from n0 to n6
+// - Tracing of queues and packet receptions to file "mixed-global-routing.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/debug.h"
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/point-to-point-channel.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/csma-channel.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/csma-topology.h"
+#include "ns3/csma-ipv4-topology.h"
+#include "ns3/eui48-address.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/socket.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/point-to-point-topology.h"
+#include "ns3/onoff-application.h"
+#include "ns3/global-route-manager.h"
+
+using namespace ns3;
+
+int main (int argc, char *argv[])
+{
+
+  // Users may find it convenient to turn on explicit debugging
+  // for selected modules; the below lines suggest how to do this
+#if 0 
+  DebugComponentEnable ("Object");
+  DebugComponentEnable ("Queue");
+  DebugComponentEnable ("DropTailQueue");
+  DebugComponentEnable ("Channel");
+  DebugComponentEnable ("PointToPointChannel");
+  DebugComponentEnable ("PointToPointNetDevice");
+  DebugComponentEnable ("GlobalRouter");
+  DebugComponentEnable ("GlobalRouteManager");
+#endif
+
+  // Set up some default values for the simulation.  Use the Bind ()
+  // technique to tell the system what subclass of Queue to use,
+  // and what the queue limit is
+
+  // The below DefaultValue::Bind command tells the queue factory which 
+  // class to instantiate, when the queue factory is invoked in the 
+  // topology code
+  DefaultValue::Bind ("Queue", "DropTailQueue");
+
+  DefaultValue::Bind ("OnOffApplicationPacketSize", "210");
+  DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s");
+
+  //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);   
+
+  // Allow the user to override any of the defaults and the above
+  // Bind ()s at run-time, via command-line arguments
+  CommandLine::Parse (argc, argv);
+
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> (); 
+  Ptr<Node> n2 = Create<InternetNode> (); 
+  Ptr<Node> n3 = Create<InternetNode> ();
+  Ptr<Node> n4 = Create<InternetNode> (); 
+  Ptr<Node> n5 = Create<InternetNode> (); 
+  Ptr<Node> n6 = Create<InternetNode> ();
+
+  // We create the channels first without any IP addressing information
+  Ptr<PointToPointChannel> channel0 = 
+    PointToPointTopology::AddPointToPointLink (
+      n0, n2, DataRate (5000000), MilliSeconds (2));
+
+  Ptr<PointToPointChannel> channel1 = 
+    PointToPointTopology::AddPointToPointLink (
+      n1, n2, DataRate (5000000), MilliSeconds (2));
+  
+  Ptr<PointToPointChannel> channel2 = 
+    PointToPointTopology::AddPointToPointLink (
+      n5, n6, DataRate (1500000), MilliSeconds (10));
+
+  // We create the channels first without any IP addressing information
+  Ptr<CsmaChannel> channelc0 = 
+    CsmaTopology::CreateCsmaChannel(
+      DataRate(5000000), MilliSeconds(2));
+
+  uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channelc0,
+                                         Eui48Address("10:54:23:54:23:50"));
+  uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channelc0,
+                                         Eui48Address("10:54:23:54:23:51"));
+  uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n4, channelc0,
+                                         Eui48Address("10:54:23:54:23:52"));
+  uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n5, channelc0,
+                                         Eui48Address("10:54:23:54:23:53"));
+
+  // Later, we add IP addresses.  
+  PointToPointTopology::AddIpv4Addresses (
+      channel0, n0, Ipv4Address ("10.1.1.1"),
+      n2, Ipv4Address ("10.1.1.2"));
+  
+  PointToPointTopology::AddIpv4Addresses (
+      channel1, n1, Ipv4Address ("10.1.2.1"),
+      n2, Ipv4Address ("10.1.2.2"));
+  
+  PointToPointTopology::AddIpv4Addresses (
+      channel2, n5, Ipv4Address ("10.1.3.1"),
+      n6, Ipv4Address ("10.1.3.2"));
+
+  CsmaIpv4Topology::AddIpv4Address (
+      n2, n2ifIndex, Ipv4Address("10.250.1.1"), Ipv4Mask("255.255.255.0"));
+
+  CsmaIpv4Topology::AddIpv4Address (
+      n3, n3ifIndex, Ipv4Address("10.250.1.2"), Ipv4Mask("255.255.255.0"));
+  
+  CsmaIpv4Topology::AddIpv4Address (
+      n4, n4ifIndex, Ipv4Address("10.250.1.3"), Ipv4Mask("255.255.255.0"));
+  
+  CsmaIpv4Topology::AddIpv4Address (
+      n5, n5ifIndex, Ipv4Address("10.250.1.4"), Ipv4Mask("255.255.255.0"));
+
+  // Create router nodes, initialize routing database and set up the routing
+  // tables in the nodes.
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  // Create the OnOff application to send UDP datagrams of size
+  // 210 bytes at a rate of 448 Kb/s
+  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+    n0, 
+    InetSocketAddress ("10.1.3.2", 80), 
+    "Udp",
+    ConstantVariable (1), 
+    ConstantVariable (0),
+    DataRate("300bps"),
+    50);
+  // Start the application
+  ooff->Start (Seconds (1.0));
+  ooff->Stop (Seconds (10.0));
+
+  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+  // Trace output will be sent to the simple-global-routing.tr file
+  AsciiTrace asciitrace ("mixed-global-routing.tr");
+  asciitrace.TraceAllQueues ();
+  asciitrace.TraceAllNetDeviceRx ();
+
+  // Also configure some tcpdump traces; each interface will be traced
+  // The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
+  // and can be read by the "tcpdump -r" command (use "-tt" option to
+  // display timestamps correctly)
+  PcapTrace pcaptrace ("mixed-global-routing.pcap");
+  pcaptrace.TraceAllIp ();
+
+  Simulator::Run ();
+    
+  Simulator::Destroy ();
+}
--- a/examples/simple-p2p.cc	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * ns-2 simple.tcl script (ported from ns-2)
- * Originally authored by Steve McCanne, 12/19/1996
- */
-
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
-//
-// Network topology
-//
-//  n0
-//     \ 5 Mb/s, 2ms
-//      \          1.5Mb/s, 10ms
-//       n2 -------------------------n3
-//      /
-//     / 5 Mb/s, 2ms
-//   n1
-//
-// - all links are p2p links with indicated one-way BW/delay
-// - CBR/UDP flows from n0 to n3, and from n3 to n1
-// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec.
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-//   (i.e., DataRate of 448,000 bps)
-// - DropTail queues 
-// - Tracing of queues and packet receptions to file "simple-p2p.tr"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cassert>
-
-#include "ns3/command-line.h"
-#include "ns3/default-value.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-#include "ns3/ascii-trace.h"
-#include "ns3/pcap-trace.h"
-#include "ns3/internet-node.h"
-#include "ns3/p2p-channel.h"
-#include "ns3/p2p-net-device.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/socket.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/p2p-topology.h"
-#include "ns3/onoff-application.h"
-
-using namespace ns3;
-
-int main (int argc, char *argv[])
-{
-
-  // Users may find it convenient to turn on explicit debugging
-  // for selected modules; the below lines suggest how to do this
-#if 0 
-  DebugComponentEnable("Object");
-  DebugComponentEnable("Queue");
-  DebugComponentEnable("DropTailQueue");
-  DebugComponentEnable("Channel");
-  DebugComponentEnable("PointToPointChannel");
-  DebugComponentEnable("PointToPointNetDevice");
-#endif
-
-  // Set up some default values for the simulation.  Use the Bind()
-  // technique to tell the system what subclass of Queue to use,
-  // and what the queue limit is
-
-  // The below Bind command tells the queue factory which class to
-  // instantiate, when the queue factory is invoked in the topology code
-  Bind ("Queue", "DropTailQueue");
-
-  Bind ("OnOffApplicationPacketSize", "210");
-  Bind ("OnOffApplicationDataRate", "448kb/s");
-
-  //Bind ("DropTailQueue::m_maxPackets", 30);   
-
-  // Allow the user to override any of the defaults and the above
-  // Bind()s at run-time, via command-line arguments
-  CommandLine::Parse (argc, argv);
-
-  // Here, we will explicitly create four nodes.  In more sophisticated
-  // topologies, we could configure a node factory.
-  Ptr<Node> n0 = Create<InternetNode> ();
-  Ptr<Node> n1 = Create<InternetNode> (); 
-  Ptr<Node> n2 = Create<InternetNode> (); 
-  Ptr<Node> n3 = Create<InternetNode> ();
-
-  // We create the channels first without any IP addressing information
-  Ptr<PointToPointChannel> channel0 = 
-    PointToPointTopology::AddPointToPointLink (
-      n0, n2, DataRate(5000000), MilliSeconds(2));
-
-  Ptr<PointToPointChannel> channel1 = 
-    PointToPointTopology::AddPointToPointLink (
-      n1, n2, DataRate(5000000), MilliSeconds(2));
-  
-  Ptr<PointToPointChannel> channel2 = 
-    PointToPointTopology::AddPointToPointLink (
-      n2, n3, DataRate(1500000), MilliSeconds(10));
-  
-  // Later, we add IP addresses.  
-  PointToPointTopology::AddIpv4Addresses (
-      channel0, n0, Ipv4Address("10.1.1.1"),
-      n2, Ipv4Address("10.1.1.2"));
-  
-  PointToPointTopology::AddIpv4Addresses (
-      channel1, n1, Ipv4Address("10.1.2.1"),
-      n2, Ipv4Address("10.1.2.2"));
-  
-  PointToPointTopology::AddIpv4Addresses (
-      channel2, n2, Ipv4Address("10.1.3.1"),
-      n3, Ipv4Address("10.1.3.2"));
-
-  // Finally, we add static routes.  These three steps (Channel and
-  // NetDevice creation, IP Address assignment, and routing) are 
-  // separated because there may be a need to postpone IP Address
-  // assignment (emulation) or modify to use dynamic routing
-  PointToPointTopology::AddIpv4Routes(n0, n2, channel0);
-  PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
-  PointToPointTopology::AddIpv4Routes(n2, n3, channel2);
-
-
-  // Create the OnOff application to send UDP datagrams of size
-  // 210 bytes at a rate of 448 Kb/s
-  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
-    n0, 
-    InetSocketAddress("10.1.3.2", 80).ConvertTo (), 
-    "Udp",
-    ConstantVariable(1), 
-    ConstantVariable(0));
-  // Start the application
-  ooff->Start(Seconds(1.0));
-  ooff->Stop (Seconds(10.0));
-
-  // Create a similar flow from n3 to n1, starting at time 1.1 seconds
-  ooff = Create<OnOffApplication> (
-    n3, 
-    InetSocketAddress("10.1.2.1", 80).ConvertTo (),
-    "Udp",
-    ConstantVariable(1), 
-    ConstantVariable(0));
-  // Start the application
-  ooff->Start(Seconds(1.1));
-  ooff->Stop (Seconds(10.0));
-
-  // Here, finish off packet routing configuration
-  // This will likely set by some global StaticRouting object in the future
-  Ptr<Ipv4> ipv4;
-  ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
-  ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
-  ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid);
-  ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
-  
-  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
-  // Trace output will be sent to the simple-p2p.tr file
-  AsciiTrace asciitrace ("simple-p2p.tr");
-  asciitrace.TraceAllQueues ();
-  asciitrace.TraceAllNetDeviceRx ();
-
-  // Also configure some tcpdump traces; each interface will be traced
-  // The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
-  // and can be read by the "tcpdump -r" command (use "-tt" option to
-  // display timestamps correctly)
-  PcapTrace pcaptrace ("simple-p2p.pcap");
-  pcaptrace.TraceAllIp ();
-
-  Simulator::Run ();
-    
-  Simulator::Destroy ();
-}
--- a/examples/simple-point-to-point.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/examples/simple-point-to-point.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -72,6 +72,7 @@
 
   // Users may find it convenient to turn on explicit debugging
   // for selected modules; the below lines suggest how to do this
+  // remember to add #include "ns3/debug.h" before enabling these
 #if 0 
   DebugComponentEnable("Object");
   DebugComponentEnable("Queue");
--- a/examples/wscript	Tue Aug 28 11:22:01 2007 +0200
+++ b/examples/wscript	Tue Aug 28 12:05:35 2007 +0200
@@ -3,15 +3,21 @@
 def build(bld):
         
     obj = bld.create_ns3_program('simple-global-routing',
-                                 ['point-to-point', 'internet-node', 'global-routing'])
+        ['point-to-point', 'internet-node', 'global-routing'])
     obj.source = 'simple-global-routing.cc'
 
-    obj = bld.create_ns3_program('simple-point-to-point', ['point-to-point', 'internet-node'])
+    obj = bld.create_ns3_program('simple-point-to-point',
+        ['point-to-point', 'internet-node'])
     obj.source = 'simple-point-to-point.cc'
 
-    obj = bld.create_ns3_program('csma-cd-one-subnet', ['csma-cd', 'internet-node'])
-    obj.source = 'csma-cd-one-subnet.cc'
+    obj = bld.create_ns3_program('csma-one-subnet',
+        ['csma', 'internet-node'])
+    obj.source = 'csma-one-subnet.cc'
 
-    obj = bld.create_ns3_program('csma-cd-packet-socket', ['csma-cd', 'internet-node'])
-    obj.source = 'csma-cd-packet-socket.cc'
+    obj = bld.create_ns3_program('csma-packet-socket',
+        ['csma', 'internet-node'])
+    obj.source = 'csma-packet-socket.cc'
 
+    obj = bld.create_ns3_program( 'mixed-global-routing',
+        ['point-to-point', 'internet-node', 'global-routing' , 'csma-cd'])
+    obj.source = 'mixed-global-routing.cc'
--- a/samples/main-simple.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/samples/main-simple.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -6,6 +6,7 @@
 #include "ns3/socket.h"
 #include "ns3/inet-socket-address.h"
 #include "ns3/nstime.h"
+#include "ns3/packet.h"
 
 using namespace ns3;
 
@@ -13,7 +14,7 @@
 GenerateTraffic (Ptr<Socket> socket, uint32_t size)
 {
   std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl;
-  socket->Send (0, size);
+  socket->Send (Packet (size));
   if (size > 0)
     {
       Simulator::Schedule (Seconds (0.5), &GenerateTraffic, socket, size - 50);
@@ -25,15 +26,15 @@
 }
 
 static void
-SocketPrinter (Ptr<Socket> socket, uint32_t size, const Address &from)
+SocketPrinter (Ptr<Socket> socket, const Packet &packet, const Address &from)
 {
-  std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl;
+  std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << packet.GetSize () << std::endl;
 }
 
 static void
 PrintTraffic (Ptr<Socket> socket)
 {
-  socket->RecvDummy (MakeCallback (&SocketPrinter));
+  socket->SetRecvCallback (MakeCallback (&SocketPrinter));
 }
 
 void
--- a/src/applications/onoff-application.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/applications/onoff-application.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -31,6 +31,7 @@
 #include "ns3/simulator.h"
 #include "ns3/socket-factory.h"
 #include "ns3/default-value.h"
+#include "ns3/packet.h"
 #include "onoff-application.h"
 
 using namespace std;
@@ -205,7 +206,7 @@
 void OnOffApplication::SendPacket()
 {
   NS_ASSERT (m_sendEvent.IsExpired ());
-  m_socket->Send(0, m_pktSize);
+  m_socket->Send(Packet (m_pktSize));
   m_totBytes += m_pktSize;
   m_lastStartTime = Simulator::Now();
   m_residualBits = 0;
--- a/src/applications/onoff-application.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/applications/onoff-application.h	Tue Aug 28 12:05:35 2007 +0200
@@ -28,13 +28,13 @@
 #include "ns3/application.h"
 #include "ns3/event-id.h"
 #include "ns3/ptr.h"
+#include "ns3/data-rate.h"
 
 namespace ns3 {
 
 class Address;
 class RandomVariable;
 class Socket;
-class DataRate;
 
 /**
  * \brief Generate traffic to a single destination according to an
--- a/src/common/packet-metadata-test.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/common/packet-metadata-test.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -230,6 +230,7 @@
   : Test ("PacketMetadata")
 {
   m_printer.SetPayloadPrinter (MakeCallback (&PacketMetadataTest::PrintPayload, this));
+  m_printer.SetSeparator ("");
 }
 
 PacketMetadataTest::~PacketMetadataTest ()
--- a/src/common/packet.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/common/packet.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -128,7 +128,7 @@
 void 
 Packet::PrintTags (std::ostream &os) const
 {
-  m_tags.Print (os);
+  m_tags.Print (os, " ");
 }
 
 void 
--- a/src/common/tags.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/common/tags.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -119,14 +119,14 @@
 }
 
 void 
-Tags::Print (std::ostream &os) const
+Tags::Print (std::ostream &os, std::string separator) const
 {
   for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) 
     {
       TagRegistry::Print (cur->m_id, cur->m_data, os);
       if (cur->m_next != 0)
         {
-          os << " ";
+          os << separator;
         }
     }
 }
@@ -347,7 +347,7 @@
       ok = false;
     }
   g_a = false;
-  tags.Print (std::cout);
+  tags.Print (std::cout, "");
   if (!g_a)
     {
       ok = false;
@@ -363,7 +363,7 @@
     }
   g_b = false;
   g_a = false;
-  tags.Print (std::cout);
+  tags.Print (std::cout, "");
   if (!g_a || !g_b)
     {
       ok = false;
@@ -372,14 +372,14 @@
   Tags other = tags;
   g_b = false;
   g_a = false;
-  other.Print (std::cout);
+  other.Print (std::cout, "");
   if (!g_a || !g_b)
     {
       ok = false;
     }
   g_b = false;
   g_a = false;
-  tags.Print (std::cout);
+  tags.Print (std::cout, "");
   if (!g_a || !g_b)
     {
       ok = false;
@@ -406,7 +406,7 @@
     }
   g_b = false;
   g_a = false;
-  other.Print (std::cout);
+  other.Print (std::cout, "");
   if (g_a || !g_b)
     {
       ok = false;
@@ -452,7 +452,7 @@
   tagZ.z = 0;
   testLastTag.Add (tagZ);
   g_z = false;
-  testLastTag.Print (std::cout);
+  testLastTag.Print (std::cout, "");
   if (!g_z)
     {
       ok = false;
--- a/src/common/tags.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/common/tags.h	Tue Aug 28 12:05:35 2007 +0200
@@ -52,7 +52,7 @@
   template <typename T>
   bool Peek (T &tag) const;
 
-  void Print (std::ostream &os) const;
+  void Print (std::ostream &os, std::string separator) const;
   uint32_t GetSerializedSize (void) const;
   void Serialize (Buffer::Iterator i, uint32_t size) const;
   uint32_t Deserialize (Buffer::Iterator i);
--- a/src/devices/csma-cd/backoff.cc	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007, Emmanuelle Laprise
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
- */
-
-#include "backoff.h"
-
-namespace ns3 {
-
-Backoff::Backoff() 
-{
-  m_slotTime = MicroSeconds(1);
-  m_minSlots = 1;
-  m_maxSlots = 1000;
-  m_ceiling = 10;
-  m_maxRetries = 1000;
-
-  ResetBackoffTime();
-}
-
-Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
-                 uint32_t ceiling, uint32_t maxRetries)
-{
-  m_slotTime = slotTime;
-  m_minSlots = minSlots;
-  m_maxSlots = maxSlots;
-  m_ceiling = ceiling;
-  m_maxRetries = maxRetries;
-}  
-
-Time
-Backoff::GetBackoffTime (void)
-{
-  Time backoff;
-  uint32_t ceiling;
-
-  if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling))
-    ceiling = m_ceiling;
-  else
-    ceiling = m_numBackoffRetries;
-
-  uint32_t minSlot = m_minSlots;
-  uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1;
-  if (maxSlot > m_maxSlots)
-    maxSlot = m_maxSlots;
-
-  uint32_t backoffSlots = 
-    (uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot);
-
-  backoff = Scalar(backoffSlots) * m_slotTime;
-  return (backoff);
-}
-
-void Backoff::ResetBackoffTime (void)
-{
-  m_numBackoffRetries = 0;
-}
-
-bool Backoff::MaxRetriesReached(void) {
-  return (m_numBackoffRetries >= m_maxRetries);
-}
-
-void Backoff::IncrNumRetries(void) {
-  m_numBackoffRetries++;
-}
-
-} // namespace ns3
--- a/src/devices/csma-cd/backoff.h	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
- * Derived from the p2p net device file
-Transmi */
-
-#ifndef BACKOFF_H
-#define BACKOFF_H
-
-#include <stdint.h>
-#include "ns3/nstime.h"
-#include "ns3/random-variable.h"
-
-namespace ns3 {
-
-  /**
-   * \brief The backoff class is used for calculating backoff times
-   * when many net devices can write to the same channel
-   *
-   */
-
-class Backoff {
-public:
-  uint32_t m_minSlots; // Minimum number of backoff slots (when
-                       // multiplied by m_slotTime, determines minimum
-                       // backoff time)
-  uint32_t m_maxSlots; // Maximim number of backoff slots (when
-                       // multiplied by m_slotTime, determines
-                       // maximum backoff time)
-  uint32_t m_ceiling;  // Caps the exponential function when the
-                       // number of retries reaches m_ceiling
-  uint32_t m_maxRetries; // Maximum number of transmission retries
-                         // before the packet is dropped.
-  Time     m_slotTime; // Length of one slot. A slot time, it usually
-                       // the packet transmission time, if the packet
-                       // size is fixed.
-
-  Backoff();
-  Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots, 
-          uint32_t ceiling, uint32_t maxRetries);
-
-  /**
-   * \return The amount of time that the net device should wait before
-   * trying to retransmit the packet
-   */
-  Time GetBackoffTime();
-  /**
-   * Indicates to the backoff object that the last packet was
-   * successfully transmitted and that the number of retries should be
-   * reset to 0.
-   */
-  void ResetBackoffTime();
-  /**
-   * \return True if the maximum number of retries has been reached
-   */
-  bool MaxRetriesReached();
-  /**
-   * Increments the number of retries by 1.
-   */
-  void IncrNumRetries();
-
-private:
-  uint32_t m_numBackoffRetries; // Number of times that the
-                                // transmitter has tried to
-                                // unsuccessfully transmit the current
-                                // packet
-};
-
-}; // namespace ns3
-
-#endif // BACKOFF_H
-
--- a/src/devices/csma-cd/csma-cd-channel.cc	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,371 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
- */
-
-#include "csma-cd-channel.h"
-#include "csma-cd-net-device.h"
-#include "ns3/packet.h"
-#include "ns3/simulator.h"
-#include "ns3/debug.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("CsmaCdChannel");
-
-namespace ns3 {
-
-CsmaCdDeviceRec::CsmaCdDeviceRec()
-{
-  active = false;
-}
-
-CsmaCdDeviceRec::CsmaCdDeviceRec(Ptr<CsmaCdNetDevice> device)
-{
-  devicePtr = device; 
-  active = true;
-}
-
-bool
-CsmaCdDeviceRec::IsActive() {
-  return active;
-}
-
-
-//
-// By default, you get a channel with the name "CsmaCd Channel" that 
-// has an "infitely" fast transmission speed and zero delay.
-CsmaCdChannel::CsmaCdChannel()
-: 
-  Channel ("CsmaCd Channel"), 
-  m_bps (DataRate(0xffffffff)),
-  m_delay (Seconds(0))
-{
-  NS_DEBUG("CsmaCdChannel::CsmaCdChannel ()");
-  Init();
-}
-
-CsmaCdChannel::CsmaCdChannel(
-  const DataRate& bps, 
-  const Time& delay)
-: 
-  Channel ("CsmaCd Channel"), 
-  m_bps (bps),
-  m_delay (delay)
-{
-  NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << Channel::GetName() 
-    << ", " << bps.GetBitRate() << ", " << delay << ")");
-  Init();
-}
-
-CsmaCdChannel::CsmaCdChannel(
-  const std::string& name,
-  const DataRate& bps, 
-  const Time& delay)
-: 
-  Channel (name),
-  m_bps (bps), 
-  m_delay (delay)
-{
-  NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << name << ", " << 
-           bps.GetBitRate() << ", " << delay << ")");
-  Init();
-}
-
-void CsmaCdChannel::Init() {
-  m_state = IDLE;
-  m_deviceList.clear();
-}
-
-int32_t
-CsmaCdChannel::Attach(Ptr<CsmaCdNetDevice> device)
-{
-  NS_DEBUG("CsmaCdChannel::Attach (" << device << ")");
-  NS_ASSERT(device != 0);
-
-  CsmaCdDeviceRec rec(device);
-  
-  m_deviceList.push_back(rec);
-  return (m_deviceList.size() - 1);
-}
-
-bool
-CsmaCdChannel::Reattach(Ptr<CsmaCdNetDevice> device)
-{
-  NS_DEBUG("CsmaCdChannel::Reattach (" << device << ")");
-  NS_ASSERT(device != 0);
-
-  std::vector<CsmaCdDeviceRec>::iterator it;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
-    {
-      if (it->devicePtr == device) 
-        {
-          if (!it->active) 
-            {
-              it->active = true;
-              return true;
-            } 
-          else 
-            {
-              return false;
-            }
-        }
-    }
-  return false;
-}
-
-bool
-CsmaCdChannel::Reattach(uint32_t deviceId)
-{
-  NS_DEBUG("CsmaCdChannel::Reattach (" << deviceId << ")");
-  if (deviceId < m_deviceList.size())
-    {
-      return false;
-    }
-
-  if (m_deviceList[deviceId].active)
-    {
-      return false;
-    } 
-  else 
-    {
-      m_deviceList[deviceId].active = true;
-      return true;
-    }
-}
-
-bool
-CsmaCdChannel::Detach(uint32_t deviceId)
-{
-  NS_DEBUG("CsmaCdChannel::Detach (" << deviceId << ")");
-
-  if (deviceId < m_deviceList.size())
-    {
-      if (!m_deviceList[deviceId].active)
-        {
-          NS_DEBUG("CsmaCdChannel::Detach Device is already detached (" 
-                   << deviceId << ")");
-          return false;
-        }
-
-      m_deviceList[deviceId].active = false;
-      if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
-        {
-          NS_DEBUG("CsmaCdChannel::Detach Device is currently"
-                   << "transmitting (" << deviceId << ")");
-          // Here we will need to place a warning in the packet
-        }
-
-      return true;
-    } 
-  else 
-    {
-      return false;
-    }
-}
-
-bool
-CsmaCdChannel::Detach(Ptr<CsmaCdNetDevice> device)
-{
-  NS_DEBUG("CsmaCdChannel::Detach (" << device << ")");
-  NS_ASSERT(device != 0);
-
-  std::vector<CsmaCdDeviceRec>::iterator it;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
-    {
-      if ((it->devicePtr == device) && (it->active)) 
-        {
-          it->active = false;
-          return true;
-        }
-    }
-  return false;
-}
-
-bool
-CsmaCdChannel::TransmitStart(Packet& p, uint32_t srcId)
-{
-  NS_DEBUG ("CsmaCdChannel::TransmitStart (" << &p << ", " << srcId 
-            << ")");
-  NS_DEBUG ("CsmaCdChannel::TransmitStart (): UID is " << 
-            p.GetUid () << ")");
-
-  if (m_state != IDLE)
-    {
-      NS_DEBUG("CsmaCdChannel::TransmitStart (): state is not IDLE");
-      return false;
-    }
-
-  if (!IsActive(srcId))
-    {
-      NS_DEBUG("CsmaCdChannel::TransmitStart (): ERROR: Seclected "
-               << "source is not currently attached to network");
-      return false;
-    }
-
-  NS_DEBUG("CsmaCdChannel::TransmitStart (): switch to TRANSMITTING");
-  m_currentPkt = p;
-  m_currentSrc = srcId;
-  m_state = TRANSMITTING;
-  return true;
-}
-
-bool
-CsmaCdChannel::IsActive(uint32_t deviceId) 
-{
-    return (m_deviceList[deviceId].active);
-}
-
-bool
-CsmaCdChannel::TransmitEnd()
-{
-  NS_DEBUG("CsmaCdChannel::TransmitEnd (" << &m_currentPkt << ", " 
-           << m_currentSrc << ")");
-  NS_DEBUG("CsmaCdChannel::TransmitEnd (): UID is " << 
-            m_currentPkt.GetUid () << ")");
-
-  NS_ASSERT(m_state == TRANSMITTING);
-  m_state = PROPAGATING;
-
-  bool retVal = true;
-
-  if (!IsActive(m_currentSrc)) {
-    NS_DEBUG("CsmaCdChannel::TransmitEnd (): ERROR: Seclected source "
-             << "was detached before the end of the transmission");
-    retVal = false;
-  }
-
-  NS_DEBUG ("CsmaCdChannel::TransmitEnd (): Schedule event in " << 
-            m_delay.GetSeconds () << "sec");
-
-  Simulator::Schedule (m_delay,
-                       &CsmaCdChannel::PropagationCompleteEvent,
-                       this);
-  return retVal;
-}
-
-void
-CsmaCdChannel::PropagationCompleteEvent()
-{
-  NS_DEBUG("CsmaCdChannel::PropagationCompleteEvent (" 
-           << &m_currentPkt << ")");
-  NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): UID is " << 
-            m_currentPkt.GetUid () << ")");
-
-  NS_ASSERT(m_state == PROPAGATING);
-
-  NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): Receive");
-  
-  std::vector<CsmaCdDeviceRec>::iterator it;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
-    {
-      if (it->IsActive())
-      {
-        it->devicePtr->Receive (m_currentPkt);
-      }
-    }
-  m_state = IDLE;
-}
-
-
-uint32_t 
-CsmaCdChannel::GetNumActDevices (void)
-{
-  int numActDevices = 0;
-  std::vector<CsmaCdDeviceRec>::iterator it;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
-    {
-      if (it->active)
-        {
-          numActDevices++;
-        }
-    }
-  return numActDevices;
-}
-
-// This is not the number of active devices. This is the total number
-// of devices even if some were detached after.
-uint32_t 
-CsmaCdChannel::GetNDevices (void) const
-{
-  return (m_deviceList.size());
-}
-
-Ptr<NetDevice>
-CsmaCdChannel::GetDevice (uint32_t i) const
-{
-  Ptr< CsmaCdNetDevice > netDevice;
-
-  netDevice = m_deviceList[i].devicePtr;
-  return netDevice;
-}
-
-int32_t
-CsmaCdChannel::GetDeviceNum (Ptr<CsmaCdNetDevice> device)
-{
-  std::vector<CsmaCdDeviceRec>::iterator it;
-  int i = 0;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
-    {
-      if (it->devicePtr == device)
-        {
-          if (it->active) 
-            {
-              return i;
-            } 
-          else 
-            {
-              return -2;
-            }
-        }
-      i++;
-    }
-  return -1;
-}
-
-bool 
-CsmaCdChannel::IsBusy (void)
-{
-  if (m_state == IDLE) 
-    {
-      return false;
-    } 
-  else 
-    {
-      return true;
-    }
-}
-
-DataRate
-CsmaCdChannel::GetDataRate (void)
-{
-  return m_bps;
-}
-
-Time
-CsmaCdChannel::GetDelay (void)
-{
-  return m_delay;
-}
-
-WireState
-CsmaCdChannel::GetState(void)
-{
-  return m_state;
-}
-
-} // namespace ns3
--- a/src/devices/csma-cd/csma-cd-channel.h	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
- */
-
-#ifndef CSMA_CD_CHANNEL_H
-#define CSMA_CD_CHANNEL_H
-
-#include "ns3/channel.h"
-#include "ns3/ptr.h"
-#include "ns3/packet.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-namespace ns3 {
-
-class CsmaCdNetDevice;
-
-  /**
-   * \brief CsmaCdNetDevice Record 
-   *
-   * Stores the information related to each net device that is
-   * connected to the channel. 
-   */
-  class CsmaCdDeviceRec {
-  public:
-    Ptr< CsmaCdNetDevice > devicePtr; /// Pointer to the net device
-    bool                       active;    /// Is net device enabled to TX/RX
-
-    CsmaCdDeviceRec();
-    CsmaCdDeviceRec(Ptr< CsmaCdNetDevice > device);
-    /*
-     * \return If the net device pointed to by the devicePtr is active
-     * and ready to RX/TX.
-     */
-    bool IsActive();                   
-  };
-
-  /**
-   * Current state of the channel
-   */ 
-  enum WireState
-    {
-      IDLE,          /**< Channel is IDLE, no packet is being
-                        transmitted */
-      TRANSMITTING,  /**< Channel is BUSY, a packet is being written
-                        by a net device */
-      PROPAGATING    /**< Channel is BUSY, packet is propagating to
-                        all attached net devices */
-    };
-
-/**
- * \brief CsmaCd Channel.
- *
- * This class represents a simple Csma/Cd channel that can be used
- * when many nodes are connected to one wire. It uses a single busy
- * flag to indicate if the channel is currently in use. It does not
- * take into account the distances between stations or the speed of
- * light to determine collisions.
- *
- * Each net device must query the state of the channel and make sure
- * that it is IDLE before writing a packet to the channel.
- *
- * When the channel is instaniated, the constructor takes parameters
- * for a single speed, in bits per second, and a speed-of-light delay
- * time as a Time object.  When a net device is attached to a channel,
- * it is assigned a device ID, this is in order to facilitate the
- * check that makes sure that a net device that is trying to send a
- * packet to the channel is really connected to this channel
- *
- */
-class CsmaCdChannel : public Channel {
-public:
-  /**
-   * \brief Create a CsmaCdChannel
-   *
-   * By default, you get a channel with the name "CsmaCd Channel" that
-   * has an "infitely" fast transmission speed and zero delay.
-   */
-  CsmaCdChannel ();
-  
-  /**
-   * \brief Create a CsmaCdChannel
-   *
-   * \param bps The bitrate of the channel
-   * \param delay Transmission delay through the channel
-   */  
-  CsmaCdChannel (const DataRate& bps, const Time& delay);
-  
-  /**
-   * \brief Create a CsmaCdChannel
-   *
-   * \param name the name of the channel for identification purposes
-   * \param bps The bitrate of the channel
-   * \param delay Transmission delay through the channel
-   */
-  CsmaCdChannel (const std::string& name,
-                     const DataRate& bps, const Time& delay);
-
-  /**
-   * \brief Attach a given netdevice to this channel
-   *
-   * \param device Device pointer to the netdevice to attach to the channel
-   * \return The assigned device number
-   */
-  int32_t Attach (Ptr<CsmaCdNetDevice> device);
-  /**
-   * \brief Detach a given netdevice from this channel
-   *
-   * The net device is marked as inactive and it is not allowed to
-   * receive or transmit packets
-   *
-   * \param device Device pointer to the netdevice to detach from the channel
-   * \return True if the device is found and attached to the channel,
-   * false if the device is not currently connected to the channel or
-   * can't be found.
-   */
-  bool Detach (Ptr<CsmaCdNetDevice> device);
-  /**
-   * \brief Detach a given netdevice from this channel
-   *
-   * The net device is marked as inactive and it is not allowed to
-   * receive or transmit packets
-   *
-   * \param deviceId The deviceID assigned to the net device when it
-   * was connected to the channel
-   * \return True if the device is found and attached to the channel,
-   * false if the device is not currently connected to the channel or
-   * can't be found.
-   */
-  bool Detach (uint32_t deviceId);
-  /**
-   * \brief Reattach a previously detached net device to the channel
-   *
-   * The net device is marked as active. It is now allowed to receive
-   * or transmit packets. The net device must have been previously
-   * attached to the channel using the attach function.
-   *
-   * \param deviceId The device ID assigned to the net device when it
-   * was connected to the channel
-   * \return True if the device is found and is not attached to the
-   * channel, false if the device is currently connected to the
-   * channel or can't be found.
-   */
-  bool Reattach(uint32_t deviceId);
-  /**
-   * \brief Reattach a previously detached net device to the channel
-   *
-   * The net device is marked as active. It is now allowed to receive
-   * or transmit packets. The net device must have been previously
-   * attached to the channel using the attach function.
-   *
-   * \param device Device pointer to the netdevice to detach from the channel
-   * \return True if the device is found and is not attached to the
-   * channel, false if the device is currently connected to the
-   * channel or can't be found.
-   */
-  bool Reattach(Ptr<CsmaCdNetDevice> device);
-  /**
-   * \brief Start transmitting a packet over the channel
-   *
-   * If the srcId belongs to a net device that is connected to the
-   * channel, packet transmission begins, and the channel becomes busy
-   * until the packet has completely reached all destinations.
-   *
-   * \param p A reference to the packet that will be transmitted over
-   * the channel
-   * \param srcId The device Id of the net device that wants to
-   * transmit on the channel.
-   * \return True if the channel is not busy and the transmitting net
-   * device is currently active.
-   */
-  bool TransmitStart (Packet& p, uint32_t srcId);
-  /**
-   * \brief Indicates that the net device has finished transmitting
-   * the packet over the channel
-   *
-   * The channel will stay busy until the packet has completely
-   * propagated to all net devices attached to the channel. The
-   * TransmitEnd function schedules the PropagationCompleteEvent which
-   * will free the channel for further transmissions. Stores the
-   * packet p as the m_currentPkt, the packet being currently
-   * transmitting.
-   *
-   * \return Returns true unless the source was detached before it
-   * completed its transmission.
-   */
-  bool TransmitEnd ();
-  /**
-   * \brief Indicates that the channel has finished propagating the
-   * current packet. The channel is released and becomes free.
-   *
-   * Calls the receive function of every active net device that is
-   * attached to the channel.
-   */
-  void PropagationCompleteEvent();
-  /**
-   * \return Returns the device number assigned to a net device by the
-   * channel
-   *
-   * \param device Device pointer to the netdevice for which the device
-   * number is needed
-   */
-  int32_t GetDeviceNum (Ptr<CsmaCdNetDevice> device);
-  /**
-   * \return Returns the state of the channel (IDLE -- free,
-   * TRANSMITTING -- busy, PROPAGATING - busy )
-   */
-  WireState GetState();
-
-  /**
-   * \brief Indicates if the channel is busy. The channel will only
-   * accept new packets for transmission if it is not busy.
-   *
-   * \return Returns true if the channel is busy and false if it is
-   * free.
-   */
-  bool IsBusy();
-  
-  /**
-   * \brief Indicates if a net device is currently attached or
-   * detached from the channel.
-   *
-   * \param deviceId The ID that was assigned to the net device when
-   * it was attached to the channel.
-   * \return Returns true if the net device is attached to the
-   * channel, false otherwise.
-   */
-  bool IsActive(uint32_t deviceId);
-  /**
-   * \return Returns the number of net devices that are currently
-   * attached to the channel.
-   */
-  uint32_t GetNumActDevices (void);
-  /**
-   * \return Returns the total number of devices including devices
-   * that have been detached from the channel.
-   */
-  virtual uint32_t GetNDevices (void) const;
-  /**
-   * \param i The deviceId of the net device for which we want the
-   * pointer.
-   * \return Returns the pointer to the net device that is associated
-   * with deviceId i.
-   */
-  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
-
-  virtual DataRate GetDataRate (void);
-  virtual Time GetDelay (void);
-
-private:
-  DataRate      m_bps;    /// Data rate of the channel
-  Time          m_delay;  /// Delay of the channel.
-
-  /**
-   * List of the net devices that have been or are currently connected
-   * to the channel.
-   *
-   * Devices are nor removed from this list, they are marked as
-   * inactive. Otherwise the assigned device IDs will not refer to the
-   * correct NetDevice. The DeviceIds are used so that it is possible
-   * to have a number to refer to an entry in the list so that the
-   * whole list does not have to be searched when making sure that a
-   * source is attached to a channel when it is transmitting data.
-   */
-  std::vector< CsmaCdDeviceRec >            m_deviceList;
-  /**
-   * Packet that is currently being transmitted on the channel (or last
-   * packet to have been transmitted on the channel if the channel is
-   * free.)
-   */
-  Packet                              m_currentPkt;
-  /**
-   * Device Id of the source that is currently transmitting on the
-   * channel. Or last source to have transmitted a packet on the
-   * channel, if the channel is currently not busy.
-   */
-  uint32_t                            m_currentSrc;
-  /**
-   * Current state of the channel
-   */
-  WireState          m_state;
-  /**
-   * Initializes the channel when it is constructed. Resets the
-   * deviceList and sets the channel state to IDLE.
-   */
-  void Init (void);
-};
-
-} // namespace ns3
-
-#endif /* CSMA_CD_CHANNEL_H */
--- a/src/devices/csma-cd/csma-cd-ipv4-topology.cc	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2007 Emmanuelle Laprise
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
-//
-
-#include <algorithm>
-#include "ns3/assert.h"
-#include "ns3/debug.h"
-#include "ns3/fatal-error.h"
-#include "ns3/nstime.h"
-#include "ns3/internet-node.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/queue.h"
-
-#include "csma-cd-channel.h"
-#include "csma-cd-net-device.h"
-#include "csma-cd-ipv4-topology.h"
-
-namespace ns3 {
-
-
-uint32_t
-CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
-                                      Ptr<CsmaCdChannel> ch,
-                                      Eui48Address addr)
-{
-  Ptr<Queue> q = Queue::CreateDefault ();
-
-  // assume full-duplex
-  Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr, 
-                                                      ns3::CsmaCdNetDevice::IP_ARP,
-                                                      true, true);
-  nd0->AddQueue(q);
-  nd0->Attach (ch);
-  return nd0->GetIfIndex ();
-}
-
-
-void
-CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
-                                         Ptr<CsmaCdChannel> ch,
-                                         Eui48Address addr)
-{
-  Ptr<Queue> q = Queue::CreateDefault ();
-
-  Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
-                                                      ns3::CsmaCdNetDevice::LLC,
-                                                      true, false);
-  nd0->AddQueue(q);
-  nd0->Attach (ch);
-
-  Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
-                                                      ns3::CsmaCdNetDevice::LLC,
-                                                      false, true);
-  nd1->AddQueue(q);
-  nd1->Attach (ch);
-}
-
-void
-CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr<Node> n1,
-                                         Ptr<CsmaCdChannel> ch,
-                                         Eui48Address addr)
-{
-  Ptr<Queue> q = Queue::CreateDefault ();
-
-  Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
-                                                      ns3::CsmaCdNetDevice::RAW,
-                                                      true, false);
-  nd0->AddQueue(q);
-  nd0->Attach (ch);
-
-  Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
-                                                      ns3::CsmaCdNetDevice::RAW,
-                                                      false, true);
-  nd1->AddQueue(q);
-  nd1->Attach (ch);
-}
-
-void
-CsmaCdIpv4Topology::AddIpv4Address(Ptr<Node> n1,
-                                       int ndNum,
-                                       const Ipv4Address& addr1,
-                                       const Ipv4Mask& netmask1)
-{
-
-  // Duplex link is assumed to be subnetted as a /30
-  // May run this unnumbered in the future?
-  Ipv4Mask netmask(netmask1);
-
-  Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
-
-  Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
-  uint32_t index1 = ip1->AddInterface (nd1);
-
-  ip1->SetAddress (index1, addr1);
-  ip1->SetNetworkMask (index1, netmask);
-  ip1->SetUp (index1);
-
-}
-
-void
-CsmaCdIpv4Topology::AddIpv4Routes (
-  Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
-{ 
-  // Assert that both are Ipv4 nodes
-  Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
-  Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
-  NS_ASSERT(ip1 != 0 && ip2 != 0);
-
-  // Get interface indexes for both nodes corresponding to the right channel
-  uint32_t index1 = 0;
-  bool found = false;
-  for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
-    {
-      if (ip1 ->GetNetDevice (i) == nd1)
-        {
-          index1 = i;
-          found = true;
-        }
-    }
-  NS_ASSERT(found);
-
-  uint32_t index2 = 0;
-  found = false;
-  for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
-    {
-      if (ip2 ->GetNetDevice (i) == nd2)
-        {
-          index2 = i;
-          found = true;
-        }
-    }
-  NS_ASSERT(found);
-
-  ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
-  ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); 
-}
-
-} // namespace ns3
- 
--- a/src/devices/csma-cd/csma-cd-ipv4-topology.h	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2007 Emmanuelle Laprise
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
-//
-
-#ifndef __CSMA_CD_IPV4_TOPOLOGY_H__
-#define __CSMA_CD_IPV4_TOPOLOGY_H__
-
-#include "ns3/ptr.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/internet-node.h"
-#include "ns3/csma-cd-net-device.h"
-
-// The topology class consists of only static methods thar are used to
-// create the topology and data flows for an ns3 simulation
-
-namespace ns3 {
-
-class CsmaCdIpv4Channel;
-class Node;
-class IPAddr;
-class DataRate;
-class Queue;
-
-/**
- * \brief A helper class to create Topologies based on the
- * InternetNodes and CsmaCdChannels. Either the
- * SimpleCsmaCdNetDevice or the LLCCsmaCdNetDevice can be used
- * when constructing these topologies.
- */
-class CsmaCdIpv4Topology {
-public:
-
-  /**
-   * \param n1 Node to be attached to the Csma/Cd channel
-   * \param ch CsmaCdChannel to which node n1 should be attached
-   * \param addr Mac address of the node
-   *
-   * Add a Csma/Cd node to a Csma/Cd channel. This function adds
-   * a EthernetCsmaCdNetDevice to the nodes so that they can
-   * connect to a CsmaCdChannel. This means that Ethernet headers
-   * and trailers will be added to the packet before sending out on
-   * the net device.
-   * 
-   * \return ifIndex of the device
-   */
-  static uint32_t AddIpv4CsmaCdNode( Ptr<Node> n1,
-                                     Ptr<CsmaCdChannel> ch,
-                                     Eui48Address addr);
-
-  /**
-   * \param n1 Node to be attached to the Csma/Cd channel
-   * \param ch CsmaCdChannel to which node n1 should be attached
-   * \param addr Mac address of the node
-   *
-   * Add a Csma/Cd node to a Csma/Cd channel. This function adds
-   * a RawCsmaCdNetDevice to the nodes so that they can connect
-   * to a CsmaCdChannel.
-   */
-  static void AddIpv4RawCsmaCdNode( Ptr<Node> n1,
-                                    Ptr<CsmaCdChannel> ch,
-                                    Eui48Address addr);
-
-  /**
-   * \param n1 Node to be attached to the Csma/Cd channel
-   * \param ch CsmaCdChannel to which node n1 should be attached
-   * \param addr Mac address of the node
-   *
-   * Add a Csma/Cd node to a Csma/Cd channel. This function adds
-   * a LlcCsmaCdNetDevice to the nodes so that they can connect
-   * to a CsmaCdChannel.
-   */
-  static void AddIpv4LlcCsmaCdNode( Ptr<Node> n1,
-                                    Ptr<CsmaCdChannel> ch,
-                                    Eui48Address addr);
-
-
-
-  /** 
-   * \param n1 Node
-   * \param ndNum NetDevice number with which to associate address
-   * \param addr1 Ipv4 Address for ndNum of n1
-   * \param network network mask for ndNum of node n1
-   * 
-   * Add an Ipv4Address to the Ipv4 interface associated with the
-   * ndNum CsmaCdIpv4NetDevices on the provided
-   * CsmaCdIpv4Channel
-   */
-  static void AddIpv4Address(Ptr<Node> n1, int ndNum, 
-                             const Ipv4Address& addr1,
-                             const Ipv4Mask& netmask1);
-
-  /**
-   * \param nd1 Node
-   * \param nd2 Node
-   * 
-   * Add an IPV4 host route between the two specified net devices
-   */
-  static void AddIpv4Routes (Ptr<NetDevice> nd1, Ptr<NetDevice> nd2);
-};
-
-} // namespace ns3
-
-#endif
-
--- a/src/devices/csma-cd/csma-cd-net-device.cc	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,576 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
- */
-
-#include <iostream>
-#include <cassert>
-#include "ns3/debug.h"
-#include "ns3/queue.h"
-#include "ns3/simulator.h"
-#include "ns3/composite-trace-resolver.h"
-#include "csma-cd-net-device.h"
-#include "csma-cd-channel.h"
-#include "ns3/ethernet-header.h"
-#include "ns3/ethernet-trailer.h"
-#include "ns3/llc-snap-header.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice");
-
-namespace ns3 {
-
-CsmaCdTraceType::CsmaCdTraceType (enum Type type)
-  : m_type (type)
-{}
-CsmaCdTraceType::CsmaCdTraceType ()
-  : m_type (RX)
-{}
-void 
-CsmaCdTraceType::Print (std::ostream &os) const
-{
-  switch (m_type) {
-  case RX:
-    os << "dev-rx";
-    break;
-  case DROP:
-    os << "dev-drop";
-    break;
-  }
-}
-uint16_t 
-CsmaCdTraceType::GetUid (void)
-{
-  static uint16_t uid = AllocateUid<CsmaCdTraceType> ("CsmaCdTraceType");
-  return uid;
-}
-std::string 
-CsmaCdTraceType::GetName (void) const
-{
-  return "CsmaCdTraceType";
-}
-
-
-CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node)
-  : NetDevice (node, Eui48Address::Allocate ()),
-    m_bps (DataRate (0xffffffff))
-{
-  NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
-  m_encapMode = IP_ARP;
-  Init(true, true);
-}
-
-CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr, 
-                                  CsmaCdEncapsulationMode encapMode) 
-  : NetDevice(node, addr), 
-    m_bps (DataRate (0xffffffff))
-{
-  NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
-  m_encapMode = encapMode;
-
-  Init(true, true);
-}
-
-CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr, 
-                                  CsmaCdEncapsulationMode encapMode,
-                                  bool sendEnable, bool receiveEnable) 
-  : NetDevice(node, addr), 
-    m_bps (DataRate (0xffffffff))
-{
-  NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
-  m_encapMode = encapMode;
-
-  Init(sendEnable, receiveEnable);
-}
-
-CsmaCdNetDevice::~CsmaCdNetDevice()
-{
-  NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()");
-  m_queue = 0;
-}
-
-void 
-CsmaCdNetDevice::DoDispose ()
-{
-  m_channel = 0;
-  NetDevice::DoDispose ();
-}
-
-//
-// Assignment operator for CsmaCdNetDevice.
-//
-// This uses the non-obvious trick of taking the source net device passed by
-// value instead of by reference.  This causes the copy constructor to be
-// invoked (where the real work is done -- see above).  All we have to do
-// here is to return the newly constructed net device.
-//
-/*
-CsmaCdNetDevice&
-CsmaCdNetDevice::operator= (const CsmaCdNetDevice nd)
-{
-  NS_DEBUG ("CsmaCdNetDevice::operator= (" << &nd << ")");
-  return *this;
-}
-*/
-
-void 
-CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
-{
-  m_txMachineState = READY;
-  m_tInterframeGap = Seconds(0);
-  m_channel = 0; 
-  m_queue = 0;
-
-  EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
-  EnableMulticast();
-  EnablePointToPoint();
-
-  SetSendEnable (sendEnable);
-  SetReceiveEnable (receiveEnable);
-}
-
-void
-CsmaCdNetDevice::SetSendEnable (bool sendEnable)
-{
-  m_sendEnable = sendEnable;
-}
-
-void
-CsmaCdNetDevice::SetReceiveEnable (bool receiveEnable)
-{
-  m_receiveEnable = receiveEnable;
-}
-bool
-CsmaCdNetDevice::IsSendEnabled (void)
-{
-  return (m_sendEnable);
-}
-
-bool
-CsmaCdNetDevice::IsReceiveEnabled (void)
-{
-  return (m_receiveEnable);
-}
-
-void 
-CsmaCdNetDevice::SetDataRate (DataRate bps)
-{
-  m_bps = bps;
-}
-
-void 
-CsmaCdNetDevice::SetInterframeGap (Time t)
-{
-  m_tInterframeGap = t;
-}
-
-void 
-CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, 
-                                      uint32_t maxSlots, uint32_t ceiling, 
-                                      uint32_t maxRetries)
-{
-  m_backoff.m_slotTime = slotTime;
-  m_backoff.m_minSlots = minSlots;
-  m_backoff.m_maxSlots = maxSlots;
-  m_backoff.m_ceiling = ceiling;
-  m_backoff.m_maxRetries = maxRetries;
-}
-void 
-CsmaCdNetDevice::AddHeader (Packet& p, Eui48Address dest,
-                            uint16_t protocolNumber)
-{
-  if (m_encapMode == RAW)
-    {
-      return;
-    }
-  EthernetHeader header (false);
-  EthernetTrailer trailer;
-  Eui48Address source = Eui48Address::ConvertFrom (GetAddress ());
-  header.SetSource(source);
-  header.SetDestination(dest);
-
-  uint16_t lengthType = 0;
-  switch (m_encapMode) 
-    {
-    case ETHERNET_V1:
-      lengthType = p.GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
-      break;
-    case IP_ARP:
-      lengthType = protocolNumber;
-      break;
-    case LLC: {
-      LlcSnapHeader llc;
-      llc.SetType (protocolNumber);
-      p.AddHeader (llc);
-    } break;
-    case RAW:
-      NS_ASSERT (false);
-      break;
-    }
-  header.SetLengthType (lengthType);
-  p.AddHeader(header);
-  trailer.CalcFcs(p);
-  p.AddTrailer(trailer);
-}
-bool 
-CsmaCdNetDevice::ProcessHeader (Packet& p, uint16_t & param)
-{
-  if (m_encapMode == RAW)
-    {
-      return true;
-    }
-  EthernetHeader header (false);
-  EthernetTrailer trailer;
-      
-  p.RemoveTrailer(trailer);
-  trailer.CheckFcs(p);
-  p.RemoveHeader(header);
-
-  if ((header.GetDestination() != GetBroadcast ()) &&
-      (header.GetDestination() != GetAddress ()))
-    {
-      return false;
-    }
-
-  switch (m_encapMode)
-    {
-    case ETHERNET_V1:
-    case IP_ARP:
-      param = header.GetLengthType();
-      break;
-    case LLC: {
-      LlcSnapHeader llc;
-      p.RemoveHeader (llc);
-      param = llc.GetType ();
-    } break;
-    case RAW:
-      NS_ASSERT (false);
-      break;
-    }
-  return true;
-}
-
-bool
-CsmaCdNetDevice::DoNeedsArp (void) const
-{
-  if ((m_encapMode == IP_ARP) || (m_encapMode == LLC))
-    {
-      return true;
-    } 
-  else 
-    {
-      return false;
-    }
-}
-
-bool
-CsmaCdNetDevice::SendTo (Packet& p, const Address& dest, uint16_t protocolNumber)
-{
-  NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")");
-  NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")");
-
-  NS_ASSERT (IsLinkUp ());
-
-  // Only transmit if send side of net device is enabled
-  if (!IsSendEnabled())
-    return false;
-
-  Eui48Address destination = Eui48Address::ConvertFrom (dest);
-  AddHeader(p, destination, protocolNumber);
-
-  // Place the packet to be sent on the send queue
-  if (m_queue->Enqueue(p) == false )
-    {
-      return false;
-    }
-  // If the device is idle, we need to start a transmission. Otherwise,
-  // the transmission will be started when the current packet finished
-  // transmission (see TransmitCompleteEvent)
-  if (m_txMachineState == READY) 
-    {
-      // Store the next packet to be transmitted
-      if (m_queue->Dequeue (m_currentPkt))
-        {
-          TransmitStart();
-        }
-    }
-  return true;
-}
-
-void
-CsmaCdNetDevice::TransmitStart ()
-{
-  NS_DEBUG ("CsmaCdNetDevice::TransmitStart (" << &m_currentPkt << ")");
-  NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): UID is " 
-            << m_currentPkt.GetUid () << ")");
-//
-// This function is called to start the process of transmitting a packet.
-// We need to tell the channel that we've started wiggling the wire and
-// schedule an event that will be executed when it's time to tell the 
-// channel that we're done wiggling the wire.
-//
-  NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF), 
-                "Must be READY to transmit. Tx state is: " 
-                << m_txMachineState);
-
-  // Only transmit if send side of net device is enabled
-  if (!IsSendEnabled())
-    return;
-
-  if (m_channel->GetState() != IDLE)
-    { // Channel busy, backoff and rechedule TransmitStart()
-      m_txMachineState = BACKOFF;
-      if (m_backoff.MaxRetriesReached())
-        { // Too many retries reached, abort transmission of packet
-          TransmitAbort();
-        } 
-      else 
-        {
-          m_backoff.IncrNumRetries();
-          Time backoffTime = m_backoff.GetBackoffTime();
-
-          NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " 
-                    << "Channel busy, backing off for " 
-                    << backoffTime.GetSeconds () << "sec");
-
-          Simulator::Schedule (backoffTime, 
-                               &CsmaCdNetDevice::TransmitStart, 
-                               this);
-        }
-    } 
-  else 
-    {
-      // Channel is free, transmit packet
-      m_txMachineState = BUSY;
-      Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
-      
-      NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
-                "Schedule TransmitCompleteEvent in " << 
-                tEvent.GetSeconds () << "sec");
-      
-      Simulator::Schedule (tEvent, 
-                           &CsmaCdNetDevice::TransmitCompleteEvent, 
-                           this);
-      if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
-        {
-          NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
-                    "Channel transmit start did not work at " << 
-                    tEvent.GetSeconds () << "sec");
-          m_txMachineState = READY;
-        } 
-      else 
-        {
-          // Transmission success, reset backoff time parameters.
-          m_backoff.ResetBackoffTime();
-        }
-    }
-}
-
-
-void
-CsmaCdNetDevice::TransmitAbort (void)
-{
-  NS_DEBUG ("CsmaCdNetDevice::TransmitAbort ()");
-
-  NS_DEBUG ("CsmaCdNetDevice::TransmitAbort (): Pkt UID is " <<
-            m_currentPkt.GetUid () << ")");
-
-  // Try to transmit a new packet
-  bool found;
-  found = m_queue->Dequeue (m_currentPkt);
-  NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
-  m_backoff.ResetBackoffTime();
-  m_txMachineState = READY;
-  TransmitStart ();
-}
-
-void
-CsmaCdNetDevice::TransmitCompleteEvent (void)
-{
-  NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent ()");
-//
-// This function is called to finish the  process of transmitting a packet.
-// We need to tell the channel that we've stopped wiggling the wire and
-// schedule an event that will be executed when it's time to re-enable
-// the transmitter after the interframe gap.
-//
-  NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
-  // Channel should be transmitting
-  NS_ASSERT(m_channel->GetState() == TRANSMITTING);
-  m_txMachineState = GAP;
-
-  NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent (): Pkt UID is " << 
-            m_currentPkt.GetUid () << ")");
-  m_channel->TransmitEnd (); 
-
-  NS_DEBUG (
-    "CsmaCdNetDevice::TransmitCompleteEvent (): " <<
-    "Schedule TransmitReadyEvent in "
-    << m_tInterframeGap.GetSeconds () << "sec");
-
-  Simulator::Schedule (m_tInterframeGap, 
-                       &CsmaCdNetDevice::TransmitReadyEvent, 
-                       this);
-}
-
-void
-CsmaCdNetDevice::TransmitReadyEvent (void)
-{
-  NS_DEBUG ("CsmaCdNetDevice::TransmitReadyEvent ()");
-//
-// This function is called to enable the transmitter after the interframe
-// gap has passed.  If there are pending transmissions, we use this opportunity
-// to start the next transmit.
-//
-  NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
-  m_txMachineState = READY;
-
-  // Get the next packet from the queue for transmitting
-  if (m_queue->IsEmpty())
-    {
-      return;
-    }
-  else
-    {
-      bool found;
-      found = m_queue->Dequeue (m_currentPkt);
-      NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
-      TransmitStart ();
-    }
-}
-
-Ptr<TraceResolver>
-CsmaCdNetDevice::GetTraceResolver (void)
-{
-  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
-  resolver->AddChild ("queue", m_queue);
-  resolver->AddSource ("rx",
-                       "receive MAC packet",
-                       m_rxTrace,
-                       CsmaCdTraceType (CsmaCdTraceType::RX));
-  resolver->AddSource ("drop",
-                       "drop MAC packet",  
-                       m_dropTrace,
-                       CsmaCdTraceType (CsmaCdTraceType::DROP));
-  resolver->SetParent (NetDevice::GetTraceResolver ());
-  return resolver;
-}
-
-bool
-CsmaCdNetDevice::Attach (Ptr<CsmaCdChannel> ch)
-{
-  NS_DEBUG ("CsmaCdNetDevice::Attach (" << &ch << ")");
-
-  m_channel = ch;
-
-  m_deviceId = m_channel->Attach(this);
-  m_bps = m_channel->GetDataRate ();
-  m_tInterframeGap = m_channel->GetDelay ();
-
-  /* 
-   * For now, this device is up whenever a channel is attached to it.
-   */
-  NotifyLinkUp ();
-  return true;
-}
-
-void
-CsmaCdNetDevice::AddQueue (Ptr<Queue> q)
-{
-  NS_DEBUG ("CsmaCdNetDevice::AddQueue (" << q << ")");
-
-  m_queue = q;
-}
-
-void
-CsmaCdNetDevice::Receive (const Packet& packet)
-{
-  EthernetHeader header (false);
-  EthernetTrailer trailer;
-  Eui48Address broadcast;
-  Eui48Address destination;
-  Packet p = packet;
-
-  NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
-
-  // Only receive if send side of net device is enabled
-  if (!IsReceiveEnabled())
-    {
-      m_dropTrace (p);
-      return;
-    }
-
-  if (m_encapMode == RAW)
-    {
-      ForwardUp (packet, 0, GetBroadcast ());
-      m_dropTrace (p);
-      return;
-    }
-  p.RemoveTrailer(trailer);
-  trailer.CheckFcs(p);
-  p.RemoveHeader(header);
-
-  broadcast = Eui48Address::ConvertFrom (GetBroadcast ());
-  destination = Eui48Address::ConvertFrom (GetAddress ());
-  if ((header.GetDestination() != broadcast) &&
-      (header.GetDestination() != destination))
-    {
-      // not for us.
-      m_dropTrace (p);
-      return;
-    }
-//
-// protocol must be initialized to avoid a compiler warning in the RAW
-// case that breaks the optimized build.
-//
-  uint16_t protocol = 0;
-
-  switch (m_encapMode)
-    {
-    case ETHERNET_V1:
-    case IP_ARP:
-      protocol = header.GetLengthType();
-      break;
-    case LLC: {
-      LlcSnapHeader llc;
-      p.RemoveHeader (llc);
-      protocol = llc.GetType ();
-    } break;
-    case RAW:
-      NS_ASSERT (false);
-      break;
-    }
-  
-  m_rxTrace (p);
-  ForwardUp (p, protocol, header.GetSource ());
-  return;
-}
-
-Ptr<Queue>
-CsmaCdNetDevice::GetQueue(void) const 
-{ 
-    return m_queue;
-}
-
-Ptr<Channel>
-CsmaCdNetDevice::DoGetChannel(void) const 
-{ 
-    return m_channel;
-}
-
-} // namespace ns3
--- a/src/devices/csma-cd/csma-cd-net-device.h	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,419 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
- * Derived from the p2p net device file
- */
-
-#ifndef CSMA_CD_NET_DEVICE_H
-#define CSMA_CD_NET_DEVICE_H
-
-#include <string.h>
-#include "ns3/node.h"
-#include "ns3/backoff.h"
-#include "ns3/address.h"
-#include "ns3/net-device.h"
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-#include "ns3/callback-trace-source.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-#include "ns3/eui48-address.h"
-
-namespace ns3 {
-
-class Queue;
-class CsmaCdChannel;
-
-class CsmaCdTraceType : public TraceContextElement
-{
-public:
-  enum Type {
-    RX, 
-    DROP
-  };
-  CsmaCdTraceType (enum Type type);
-  CsmaCdTraceType ();
-  void Print (std::ostream &os) const;
-  static uint16_t GetUid (void);
-  std::string GetName (void) const;
-private:
-  enum Type m_type;
-};
-
-/**
- * \class CsmaCdNetDevice
- * \brief A Device for a CsmaCd Network Link.
- *
- * The Csma/Cd net device class is analogous to layer 1 and 2 of the
- * TCP stack. The NetDevice takes a raw packet of bytes and creates a
- * protocol specific packet from them. The Csma/Cd net device class
- * takes this packet and adds and processes the headers/trailers that
- * are associated with EthernetV1, EthernetV2, RAW or LLC
- * protocols. The EthernetV1 packet type adds and removes Ethernet
- * destination and source addresses. The LLC packet type adds and
- * removes LLC snap headers. The raw packet type does not add or
- * remove any headers.  Each Csma/Cd net device will receive all
- * packets written to the Csma/Cd link. The ProcessHeader function can
- * be used to filter out the packets such that higher level layers
- * only receive packets that are addressed to their associated net
- * devices
- *
- */
-class CsmaCdNetDevice : public NetDevice {
-public:
-
-  /**
-   * Enumeration of the types of packets supported in the class.
-   *
-   */
-enum CsmaCdEncapsulationMode {
-  ETHERNET_V1, /**< Version one ethernet packet, length field */
-  IP_ARP,      /**< Ethernet packet encapsulates IP/ARP packet */
-  RAW,         /**< Packet that contains no headers */
-  LLC,         /**< LLC packet encapsulation */  
-};
-
-  CsmaCdNetDevice (Ptr<Node> node);
-  /**
-   * Construct a CsmaCdNetDevice
-   *
-   * This is the constructor for the CsmaCdNetDevice.  It takes as a
-   * parameter the Node to which this device is connected.  Ownership of the
-   * Node pointer is not implied and the node must not be deleted.
-   *
-   * \param node the Node to which this device is connected.
-   * \param addr The source MAC address of the net device.
-   */
-  CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr, CsmaCdEncapsulationMode pktType);
-  CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
-                   CsmaCdEncapsulationMode pktType,
-                   bool sendEnable, bool receiveEnable);
-  /**
-   * Destroy a CsmaCdNetDevice
-   *
-   * This is the destructor for the CsmaCdNetDevice.
-   */
-  virtual ~CsmaCdNetDevice();
-  /**
-   * Set the Data Rate used for transmission of packets.  The data rate is
-   * set in the Attach () method from the corresponding field in the channel
-   * to which the device is attached.  It can be overridden using this method.
-   *
-   * @see Attach ()
-   * \param bps the data rate at which this object operates
-   */
-  void SetDataRate (DataRate bps);
-  /**
-   * Set the inteframe gap used to separate packets.  The interframe gap
-   * defines the minimum space required between packets sent by this device.
-   * It is usually set in the Attach () method based on the speed of light
-   * delay of the channel to which the device is attached.  It can be 
-   * overridden using this method if desired.
-   *
-   * @see Attach ()
-   * \param t the interframe gap time
-   */
-  void SetInterframeGap (Time t);
-  /**
-   * Set the backoff parameters used to determine the wait to retry
-   * transmitting a packet when the channel is busy.
-   *
-   * @see Attach ()
-   * \param slotTime Length of a packet slot (or average packet time)
-   * \param minSlots Minimum number of slots to wait
-   * \param maxSlots Maximum number of slots to wait
-   * \param maxRetries Maximum number of retries before packet is discard
-   * \param ceiling Cap on the exponential function when calculating max slots
-   */
-  void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, 
-                        uint32_t maxRetries, uint32_t ceiling);
-  /**
-   * Attach the device to a channel.
-   *
-   * The function Attach is used to add a CsmaCdNetDevice to a
-   * CsmaCdChannel.
-   *
-   * @see SetDataRate ()
-   * @see SetInterframeGap ()
-   * \param ch a pointer to the channel to which this object is being attached.
-   */
-  bool Attach (Ptr<CsmaCdChannel> ch);
-  /**
-   * Attach a queue to the CsmaCdNetDevice.
-   *
-   * The CsmaCdNetDevice "owns" a queue.  This queue is created by the
-   * CsmaCdTopology object and implements a queueing method such as
-   * DropTail or RED.  The CsmaCdNetDevice assumes ownership of this
-   * queue and must delete it when the device is destroyed.
-   *
-   * @see CsmaCdTopology::AddCsmaCdLink ()
-   * @see Queue
-   * @see DropTailQueue
-   * \param queue a pointer to the queue for which object is assuming
-   *        ownership.
-   */
-  void AddQueue (Ptr<Queue> queue);
-  /**
-   * Receive a packet from a connected CsmaCdChannel.
-   *
-   * The CsmaCdNetDevice receives packets from its connected channel
-   * and forwards them up the protocol stack.  This is the public method
-   * used by the channel to indicate that the last bit of a packet has 
-   * arrived at the device.
-   *
-   * @see CsmaCdChannel
-   * \param p a reference to the received packet
-   */
-  void Receive (const Packet& p);
-
-  bool IsSendEnabled (void);
-  bool IsReceiveEnabled (void);
-
-  void SetSendEnable (bool);
-  void SetReceiveEnable (bool);
-
-protected:
-  virtual bool DoNeedsArp (void) const;
-  virtual void DoDispose (void);
-  /**
-   * Create a Trace Resolver for events in the net device.
-   * (NOT TESTED)
-   * @see class TraceResolver
-   */
-  virtual Ptr<TraceResolver> GetTraceResolver (void);
-
-  /**
-   * Get a copy of the attached Queue.
-   *
-   * This method is provided for any derived class that may need to get
-   * direct access to the underlying queue.
-   *
-   * \return a pointer to the queue.
-   */
-  Ptr<Queue> GetQueue (void) const; 
-  /**
-   * Get a copy of the attached Channel
-   *
-   * This method is provided for any derived class that may need to get
-   * direct access to the connected channel
-   *
-   * \return a pointer to the channel
-   */
-  virtual Ptr<Channel> DoGetChannel (void) const;
-  /**
-   * Adds the necessary headers and trailers to a packet of data in order to
-   * respect the packet type
-   *
-   * \param p Packet to which header should be added
-   * \param dest MAC destination address to which packet should be sent
-   * \param protocolNumber In some protocols, identifies the type of
-   * payload contained in this packet.
-   */
-  void AddHeader (Packet& p, Eui48Address dest, 
-                  uint16_t protocolNumber);
-  /**
-   * Removes, from a packet of data, all headers and trailers that
-   * relate to the packet type
-   *
-   * \param p Packet whose headers need to be processed
-   * \param param An integer parameter that can be set by the function
-   * to return information gathered in the header
-   * \return Returns true if the packet should be forwarded up the
-   * protocol stack.
-   */
-  bool ProcessHeader (Packet& p, uint16_t & param);
-
-private:
-  // disable copy constructor and operator =
-  CsmaCdNetDevice &operator = (const CsmaCdNetDevice &o);
-  CsmaCdNetDevice (const CsmaCdNetDevice &o);
-  /**
-   * Initializes variablea when construction object.
-   */
-  void Init (bool sendEnable, bool receiveEnable);
-  /**
-   * Send a Packet on the Csma/Cd network
-   *
-   * This method does not use a destination address since all packets
-   * are broadcast to all NetDevices attached to the channel. Packet
-   * should contain all needed headers at this time.
-   *
-   * If the device is ready to transmit, the next packet is read off
-   * of the queue and stored locally until it has been transmitted.
-   *
-   * \param p a reference to the packet to send
-   * \param dest destination address
-   * \param protocolNumber -- this parameter is not used here
-   * \return true if success, false on failure
-   */
-  virtual bool SendTo (Packet& p, const Address& dest, uint16_t protocolNumber);
-
-  /**
-   * Start Sending a Packet Down the Wire.
-   *
-   * The TransmitStart method is the method that is used internally in
-   * the CsmaCdNetDevice to begin the process of sending a packet
-   * out on the channel.  The corresponding method is called on the
-   * channel to let it know that the physical device this class
-   * represents has virually started sending signals, this causes the
-   * channel to become busy.  An event is scheduled for the time at
-   * which the bits have been completely transmitted. If the channel
-   * is busy, the method reschedules itself for a later time (within
-   * the backoff period)
-   *
-   * @see CsmaCdChannel::TransmitStart ()
-   * @see TransmitCompleteEvent ()
-   */
-  void TransmitStart ();
-  /**
-   * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
-   *
-   * The TransmitCompleteEvent method is used internally to finish the process
-   * of sending a packet out on the channel.  During execution of this method
-   * the TransmitEnd method is called on the channel to let it know that the
-   * physical device this class represents has virually finished sending 
-   * signals.  The channel uses this event to begin its speed of light delay
-   * timer after which it notifies the Net Device at the other end of the 
-   * link that the bits have arrived.  During this method, the net device 
-   * also schedules the TransmitReadyEvent at which time the transmitter 
-   * becomes ready to send the next packet.
-   *
-   * @see CsmaCdChannel::TransmitEnd ()
-   * @see TransmitReadyEvent ()
-   */
-  void TransmitCompleteEvent (void);
-  /**
-   * Cause the Transmitter to Become Ready to Send Another Packet.
-   *
-   * The TransmitReadyEvent method is used internally to re-enable the 
-   * transmit machine of the net device.  It is scheduled after a suitable
-   * interframe gap after the completion of the previous transmission.
-   * The queue is checked at this time, and if there is a packet waiting on
-   * the queue, the transmission process is begun.
-   *
-   * If a packet is in the queue, it is extracted for the queue as the
-   * next packet to be transmitted by the net device.
-   *
-   * @see TransmitStart ()
-   */
-  void TransmitReadyEvent (void);
-
-  /**
-   * Aborts the transmission of the current packet
-   *
-   * If the net device has tried to transmit a packet for more times
-   * than the maximum allowed number of retries (channel always busy)
-   * then the packet is dropped.
-   *
-   */
-  void TransmitAbort (void);
-
-  /** 
-   * Device ID returned by the attached functions. It is used by the
-   * mp-channel to identify each net device to make sure that only
-   * active net devices are writing to the channel
-   */
-  uint32_t m_deviceId; 
-
-  /**
-   * Enable net device to send packets. True by default
-   */
-  bool m_sendEnable;
-  /**
-   * Enable net device to receive packets. True by default
-   */
-  bool m_receiveEnable;
-  /**
-   * Enumeration of the states of the transmit machine of the net device.
-   */
-  enum TxMachineState
-    {
-      READY, /**< The transmitter is ready to begin transmission of a packet */
-      BUSY,  /**< The transmitter is busy transmitting a packet */
-      GAP,    /**< The transmitter is in the interframe gap time */
-      BACKOFF    /**< The transmitter is waiting for the channel to be free */
-    };
-  /**
-   * The state of the Net Device transmit state machine.
-   * @see TxMachineState
-   */
-  TxMachineState m_txMachineState;
-  
-  /**
-   * The type of packet that should be created by the AddHeader
-   * function and that should be processed by the ProcessHeader
-   * function.
-   */
-  CsmaCdEncapsulationMode m_encapMode;
-  /**
-   * The data rate that the Net Device uses to simulate packet transmission
-   * timing.
-   * @see class DataRate
-   */
-  DataRate m_bps;
-  /**
-   * The interframe gap that the Net Device uses to throttle packet
-   * transmission
-   * @see class Time
-   */
-  Time m_tInterframeGap;
-  /**
-   * Holds the backoff parameters and is used to calculate the next
-   * backoff time to use when the channel is busy and the net device
-   * is ready to transmit
-   */
-  Backoff m_backoff;
-  /**
-   * Next packet that will be transmitted (if transmitter is not
-   * currently transmitting) or packet that is currently being
-   * transmitted.
-   */
-  Packet m_currentPkt;
-  /**
-   * The CsmaCdChannel to which this CsmaCdNetDevice has been
-   * attached.
-   * @see class CsmaCdChannel
-   */
-  Ptr<CsmaCdChannel> m_channel;
-  /**
-   * The Queue which this CsmaCdNetDevice uses as a packet source.
-   * Management of this Queue has been delegated to the CsmaCdNetDevice
-   * and it has the responsibility for deletion.
-   * @see class Queue
-   * @see class DropTailQueue
-   */
-  Ptr<Queue> m_queue;
-  /**
-   * NOT TESTED
-   * The trace source for the packet reception events that the device can
-   * fire.
-   *
-   * @see class CallBackTraceSource
-   * @see class TraceResolver
-   */
-  CallbackTraceSource<Packet &> m_rxTrace;
-  CallbackTraceSource<Packet &> m_dropTrace;
-
-};
-
-}; // namespace ns3
-
-#endif // CSMA_CD_NET_DEVICE_H
-
--- a/src/devices/csma-cd/csma-cd-topology.cc	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2007 Emmanuelle Laprise
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
-//
-
-//
-// Topology helper for CsmaCd channels in ns3.
-
-#include "ns3/assert.h"
-#include "ns3/debug.h"
-#include "ns3/queue.h"
-
-#include "csma-cd-channel.h"
-#include "csma-cd-net-device.h"
-#include "csma-cd-topology.h"
-#include "ns3/socket-factory.h"
-
-namespace ns3 {
-
-Ptr<CsmaCdChannel>
-CsmaCdTopology::CreateCsmaCdChannel(
-  const DataRate& bps,
-  const Time& delay)
-{
-  Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (bps, delay);
-
-  return channel;
-}
-
-#if 0
-Ptr<CsmaCdNetDevice>
-CsmaCdTopology::AddCsmaCdEthernetNode(
-  Ptr<Node> n1,
-  Ptr<CsmaCdChannel> ch,
-  MacAddress addr)
-{
-  Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr, 
-                                                      ns3::CsmaCdNetDevice::ETHERNET_V1);
-
-  Ptr<Queue> q = Queue::CreateDefault ();
-  nd1->AddQueue(q);
-  nd1->Attach (ch);
-  
-  return nd1;
-}
-
-Ptr<PacketSocket>
-CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app, 
-                                        Ptr<CsmaCdNetDevice> ndSrc,
-                                        Ptr<CsmaCdNetDevice> ndDest)
-{
-  Ptr<PacketSocket> socket = Create<PacketSocket> ();
-  socket->Bind(ndSrc);
-  socket->Connect(ndDest->GetAddress());
-  app->Connect(socket);
-
-  return socket;
-}
-
-Ptr<PacketSocket>
-CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
-                                        Ptr<CsmaCdNetDevice> ndSrc,
-                                        MacAddress macAddr)
-{
-  Ptr<PacketSocket> socket = Create<PacketSocket> ();
-  socket->Bind(ndSrc);
-  socket->Connect(macAddr);
-  app->Connect(socket);
-
-  return socket;
-}
-
-Ptr<Socket>
-CsmaCdTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
-{
-  InterfaceId iid = InterfaceId::LookupByName (iid_name);
-
-  Ptr<SocketFactory> socketFactory =
-    n1->QueryInterface<SocketFactory> (iid);
-
-  Ptr<Socket> socket = socketFactory->CreateSocket ();
-
-  return socket;
-}
-#endif
-
-} // namespace ns3
- 
--- a/src/devices/csma-cd/csma-cd-topology.h	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2007 Emmanuelle Laprise
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
-//
-// Topology helper for multipoint channels in ns3.
-// 
-#ifndef CSMA_CD_TOPOLOGY_H
-#define CSMA_CD_TOPOLOGY_H
-
-#include "ns3/ptr.h"
-#include "ns3/csma-cd-net-device.h"
-#include "ns3/node.h"
-
-// The topology class consists of only static methods thar are used to
-// create the topology and data flows for an ns3 simulation
-
-namespace ns3 {
-
-class CsmaCdChannel;
-class Node;
-class DataRate;
-class Queue;
-
-/**
- * \brief A helper class to create CsmaCd Topologies 
- *
- * CsmaCd topologies are created based on the
- * ns3::CsmaCdNetDevice subclasses and ns3::CsmaCdChannel
- * objects.  This class uses the EthernetNetDevice and
- * PacketSocket classes in order to create logical connections between
- * net devices. The PacketSocket class generates the data and the
- * EthernetNetDevice class creates ethernet packets from the
- * data, filling in source and destination addresses. The
- * EthernetNetDevice class filters received data packets
- * according to its destination Mac addresses.
- */
-class CsmaCdTopology {
-public:
-  /** 
-   * \param dataRate Maximum transmission link rate 
-   * \param delay propagation delay between any two nodes 
-   * \return Pointer to the created CsmaCdChannel
-   * 
-   * Create a CsmaCdChannel. All nodes connected to a multipoint
-   * channels will receive all packets written to that channel
-   */
-  static Ptr<CsmaCdChannel> CreateCsmaCdChannel(
-    const DataRate& dataRate, const Time& delay);
-
-#if 0
-  /**
-   * \param n1 Node to be attached to the multipoint channel
-   * \param ch CsmaCdChannel to which node n1 should be attached 
-   * \param addr MacAddress that should be assigned to the
-   * EthernetNetDevice that will be added to the node.
-   *
-   * Add a multipoint node to a multipoint channel
-   */
-  static Ptr<CsmaCdNetDevice> AddCsmaCdEthernetNode(Ptr<Node> n1, 
-                                                    Ptr<CsmaCdChannel> ch,
-                                                    MacAddress addr);
-
-  /**
-   * \param app Application that will be sending data to the agent
-   * \param ndSrc Net Device that will be sending the packets onto the
-   * network
-   * \param ndDest Net Device to which ndSrc will be sending the packets
-   * \return A pointer to the PacketSocket
-   *
-   * Creates an PacketSocket and configure it to send packets between
-   * two net devices
-   */
-static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
-                                      Ptr<CsmaCdNetDevice> ndSrc,
-                                      Ptr<CsmaCdNetDevice> ndDest);
-
-  /**
-   * \param app Application that will be sending data to the agent
-   * \param ndSrc Net Device that will be sending the packets onto the
-   * network 
-   * \param macAddr Mac destination address for the packets send by
-   * the ndSrc net device \return a Pointer to the created
-   * PacketSocket
-   *
-   * Creates an PacketSocket and configure it to send packets from a
-   * net device to a destination MacAddress
-   */
-static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
-                                      Ptr<CsmaCdNetDevice> ndSrc,
-                                      MacAddress macAddr);
-
-  /**
-   * \param n1 Node from which socketfactory should be tested.
-   * \param iid_name Interface identifier ("Packet", in this case)
-   *
-   * This is a test function to make sure that a socket can be created
-   * by using the socketfactory interface provided in the
-   * netdevicenode.
-   */
-static  Ptr<Socket> CreatePacketSocket(Ptr<Node> n1, 
-                                       std::string iid_name);
-#endif
-
-};
-} // namespace ns3
-
-#endif
-
--- a/src/devices/csma-cd/wscript	Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-
-def build(bld):
-    obj = bld.create_ns3_module('csma-cd', ['node'])
-    obj.source = [
-        'backoff.cc',
-        'csma-cd-net-device.cc',
-        'csma-cd-channel.cc',
-        'csma-cd-topology.cc',
-        'csma-cd-ipv4-topology.cc',
-        ]
-    headers = bld.create_obj('ns3header')
-    headers.source = [
-        'backoff.h',
-        'csma-cd-net-device.h',
-        'csma-cd-channel.h',
-        'csma-cd-topology.h',
-        'csma-cd-ipv4-topology.h',
-        ]
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/backoff.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007, Emmanuelle Laprise
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include "backoff.h"
+
+namespace ns3 {
+
+Backoff::Backoff() 
+{
+  m_slotTime = MicroSeconds(1);
+  m_minSlots = 1;
+  m_maxSlots = 1000;
+  m_ceiling = 10;
+  m_maxRetries = 1000;
+
+  ResetBackoffTime();
+}
+
+Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
+                 uint32_t ceiling, uint32_t maxRetries)
+{
+  m_slotTime = slotTime;
+  m_minSlots = minSlots;
+  m_maxSlots = maxSlots;
+  m_ceiling = ceiling;
+  m_maxRetries = maxRetries;
+}  
+
+Time
+Backoff::GetBackoffTime (void)
+{
+  Time backoff;
+  uint32_t ceiling;
+
+  if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling))
+    ceiling = m_ceiling;
+  else
+    ceiling = m_numBackoffRetries;
+
+  uint32_t minSlot = m_minSlots;
+  uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1;
+  if (maxSlot > m_maxSlots)
+    maxSlot = m_maxSlots;
+
+  uint32_t backoffSlots = 
+    (uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot);
+
+  backoff = Scalar(backoffSlots) * m_slotTime;
+  return (backoff);
+}
+
+void Backoff::ResetBackoffTime (void)
+{
+  m_numBackoffRetries = 0;
+}
+
+bool Backoff::MaxRetriesReached(void) {
+  return (m_numBackoffRetries >= m_maxRetries);
+}
+
+void Backoff::IncrNumRetries(void) {
+  m_numBackoffRetries++;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/backoff.h	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
+ * Derived from the p2p net device file
+Transmi */
+
+#ifndef BACKOFF_H
+#define BACKOFF_H
+
+#include <stdint.h>
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+  /**
+   * \brief The backoff class is used for calculating backoff times
+   * when many net devices can write to the same channel
+   *
+   */
+
+class Backoff {
+public:
+  uint32_t m_minSlots; // Minimum number of backoff slots (when
+                       // multiplied by m_slotTime, determines minimum
+                       // backoff time)
+  uint32_t m_maxSlots; // Maximim number of backoff slots (when
+                       // multiplied by m_slotTime, determines
+                       // maximum backoff time)
+  uint32_t m_ceiling;  // Caps the exponential function when the
+                       // number of retries reaches m_ceiling
+  uint32_t m_maxRetries; // Maximum number of transmission retries
+                         // before the packet is dropped.
+  Time     m_slotTime; // Length of one slot. A slot time, it usually
+                       // the packet transmission time, if the packet
+                       // size is fixed.
+
+  Backoff();
+  Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots, 
+          uint32_t ceiling, uint32_t maxRetries);
+
+  /**
+   * \return The amount of time that the net device should wait before
+   * trying to retransmit the packet
+   */
+  Time GetBackoffTime();
+  /**
+   * Indicates to the backoff object that the last packet was
+   * successfully transmitted and that the number of retries should be
+   * reset to 0.
+   */
+  void ResetBackoffTime();
+  /**
+   * \return True if the maximum number of retries has been reached
+   */
+  bool MaxRetriesReached();
+  /**
+   * Increments the number of retries by 1.
+   */
+  void IncrNumRetries();
+
+private:
+  uint32_t m_numBackoffRetries; // Number of times that the
+                                // transmitter has tried to
+                                // unsuccessfully transmit the current
+                                // packet
+};
+
+}; // namespace ns3
+
+#endif // BACKOFF_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-channel.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,371 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include "csma-channel.h"
+#include "csma-net-device.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CsmaChannel");
+
+namespace ns3 {
+
+CsmaDeviceRec::CsmaDeviceRec()
+{
+  active = false;
+}
+
+CsmaDeviceRec::CsmaDeviceRec(Ptr<CsmaNetDevice> device)
+{
+  devicePtr = device; 
+  active = true;
+}
+
+bool
+CsmaDeviceRec::IsActive() {
+  return active;
+}
+
+
+//
+// By default, you get a channel with the name "Csma Channel" that 
+// has an "infitely" fast transmission speed and zero delay.
+CsmaChannel::CsmaChannel()
+: 
+  Channel ("Csma Channel"), 
+  m_bps (DataRate(0xffffffff)),
+  m_delay (Seconds(0))
+{
+  NS_DEBUG("CsmaChannel::CsmaChannel ()");
+  Init();
+}
+
+CsmaChannel::CsmaChannel(
+  const DataRate& bps, 
+  const Time& delay)
+: 
+  Channel ("Csma Channel"), 
+  m_bps (bps),
+  m_delay (delay)
+{
+  NS_DEBUG("CsmaChannel::CsmaChannel (" << Channel::GetName() 
+    << ", " << bps.GetBitRate() << ", " << delay << ")");
+  Init();
+}
+
+CsmaChannel::CsmaChannel(
+  const std::string& name,
+  const DataRate& bps, 
+  const Time& delay)
+: 
+  Channel (name),
+  m_bps (bps), 
+  m_delay (delay)
+{
+  NS_DEBUG("CsmaChannel::CsmaChannel (" << name << ", " << 
+           bps.GetBitRate() << ", " << delay << ")");
+  Init();
+}
+
+void CsmaChannel::Init() {
+  m_state = IDLE;
+  m_deviceList.clear();
+}
+
+int32_t
+CsmaChannel::Attach(Ptr<CsmaNetDevice> device)
+{
+  NS_DEBUG("CsmaChannel::Attach (" << device << ")");
+  NS_ASSERT(device != 0);
+
+  CsmaDeviceRec rec(device);
+  
+  m_deviceList.push_back(rec);
+  return (m_deviceList.size() - 1);
+}
+
+bool
+CsmaChannel::Reattach(Ptr<CsmaNetDevice> device)
+{
+  NS_DEBUG("CsmaChannel::Reattach (" << device << ")");
+  NS_ASSERT(device != 0);
+
+  std::vector<CsmaDeviceRec>::iterator it;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if (it->devicePtr == device) 
+        {
+          if (!it->active) 
+            {
+              it->active = true;
+              return true;
+            } 
+          else 
+            {
+              return false;
+            }
+        }
+    }
+  return false;
+}
+
+bool
+CsmaChannel::Reattach(uint32_t deviceId)
+{
+  NS_DEBUG("CsmaChannel::Reattach (" << deviceId << ")");
+  if (deviceId < m_deviceList.size())
+    {
+      return false;
+    }
+
+  if (m_deviceList[deviceId].active)
+    {
+      return false;
+    } 
+  else 
+    {
+      m_deviceList[deviceId].active = true;
+      return true;
+    }
+}
+
+bool
+CsmaChannel::Detach(uint32_t deviceId)
+{
+  NS_DEBUG("CsmaChannel::Detach (" << deviceId << ")");
+
+  if (deviceId < m_deviceList.size())
+    {
+      if (!m_deviceList[deviceId].active)
+        {
+          NS_DEBUG("CsmaChannel::Detach Device is already detached (" 
+                   << deviceId << ")");
+          return false;
+        }
+
+      m_deviceList[deviceId].active = false;
+      if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
+        {
+          NS_DEBUG("CsmaChannel::Detach Device is currently"
+                   << "transmitting (" << deviceId << ")");
+          // Here we will need to place a warning in the packet
+        }
+
+      return true;
+    } 
+  else 
+    {
+      return false;
+    }
+}
+
+bool
+CsmaChannel::Detach(Ptr<CsmaNetDevice> device)
+{
+  NS_DEBUG("CsmaChannel::Detach (" << device << ")");
+  NS_ASSERT(device != 0);
+
+  std::vector<CsmaDeviceRec>::iterator it;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if ((it->devicePtr == device) && (it->active)) 
+        {
+          it->active = false;
+          return true;
+        }
+    }
+  return false;
+}
+
+bool
+CsmaChannel::TransmitStart(Packet& p, uint32_t srcId)
+{
+  NS_DEBUG ("CsmaChannel::TransmitStart (" << &p << ", " << srcId 
+            << ")");
+  NS_DEBUG ("CsmaChannel::TransmitStart (): UID is " << 
+            p.GetUid () << ")");
+
+  if (m_state != IDLE)
+    {
+      NS_DEBUG("CsmaChannel::TransmitStart (): state is not IDLE");
+      return false;
+    }
+
+  if (!IsActive(srcId))
+    {
+      NS_DEBUG("CsmaChannel::TransmitStart (): ERROR: Seclected "
+               << "source is not currently attached to network");
+      return false;
+    }
+
+  NS_DEBUG("CsmaChannel::TransmitStart (): switch to TRANSMITTING");
+  m_currentPkt = p;
+  m_currentSrc = srcId;
+  m_state = TRANSMITTING;
+  return true;
+}
+
+bool
+CsmaChannel::IsActive(uint32_t deviceId) 
+{
+    return (m_deviceList[deviceId].active);
+}
+
+bool
+CsmaChannel::TransmitEnd()
+{
+  NS_DEBUG("CsmaChannel::TransmitEnd (" << &m_currentPkt << ", " 
+           << m_currentSrc << ")");
+  NS_DEBUG("CsmaChannel::TransmitEnd (): UID is " << 
+            m_currentPkt.GetUid () << ")");
+
+  NS_ASSERT(m_state == TRANSMITTING);
+  m_state = PROPAGATING;
+
+  bool retVal = true;
+
+  if (!IsActive(m_currentSrc)) {
+    NS_DEBUG("CsmaChannel::TransmitEnd (): ERROR: Seclected source "
+             << "was detached before the end of the transmission");
+    retVal = false;
+  }
+
+  NS_DEBUG ("CsmaChannel::TransmitEnd (): Schedule event in " << 
+            m_delay.GetSeconds () << "sec");
+
+  Simulator::Schedule (m_delay,
+                       &CsmaChannel::PropagationCompleteEvent,
+                       this);
+  return retVal;
+}
+
+void
+CsmaChannel::PropagationCompleteEvent()
+{
+  NS_DEBUG("CsmaChannel::PropagationCompleteEvent (" 
+           << &m_currentPkt << ")");
+  NS_DEBUG ("CsmaChannel::PropagationCompleteEvent (): UID is " << 
+            m_currentPkt.GetUid () << ")");
+
+  NS_ASSERT(m_state == PROPAGATING);
+
+  NS_DEBUG ("CsmaChannel::PropagationCompleteEvent (): Receive");
+  
+  std::vector<CsmaDeviceRec>::iterator it;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if (it->IsActive())
+      {
+        it->devicePtr->Receive (m_currentPkt);
+      }
+    }
+  m_state = IDLE;
+}
+
+
+uint32_t 
+CsmaChannel::GetNumActDevices (void)
+{
+  int numActDevices = 0;
+  std::vector<CsmaDeviceRec>::iterator it;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if (it->active)
+        {
+          numActDevices++;
+        }
+    }
+  return numActDevices;
+}
+
+// This is not the number of active devices. This is the total number
+// of devices even if some were detached after.
+uint32_t 
+CsmaChannel::GetNDevices (void) const
+{
+  return (m_deviceList.size());
+}
+
+Ptr<NetDevice>
+CsmaChannel::GetDevice (uint32_t i) const
+{
+  Ptr< CsmaNetDevice > netDevice;
+
+  netDevice = m_deviceList[i].devicePtr;
+  return netDevice;
+}
+
+int32_t
+CsmaChannel::GetDeviceNum (Ptr<CsmaNetDevice> device)
+{
+  std::vector<CsmaDeviceRec>::iterator it;
+  int i = 0;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if (it->devicePtr == device)
+        {
+          if (it->active) 
+            {
+              return i;
+            } 
+          else 
+            {
+              return -2;
+            }
+        }
+      i++;
+    }
+  return -1;
+}
+
+bool 
+CsmaChannel::IsBusy (void)
+{
+  if (m_state == IDLE) 
+    {
+      return false;
+    } 
+  else 
+    {
+      return true;
+    }
+}
+
+DataRate
+CsmaChannel::GetDataRate (void)
+{
+  return m_bps;
+}
+
+Time
+CsmaChannel::GetDelay (void)
+{
+  return m_delay;
+}
+
+WireState
+CsmaChannel::GetState(void)
+{
+  return m_state;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-channel.h	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,307 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#ifndef CSMA_CHANNEL_H
+#define CSMA_CHANNEL_H
+
+#include "ns3/channel.h"
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+namespace ns3 {
+
+class CsmaNetDevice;
+
+  /**
+   * \brief CsmaNetDevice Record 
+   *
+   * Stores the information related to each net device that is
+   * connected to the channel. 
+   */
+  class CsmaDeviceRec {
+  public:
+    Ptr< CsmaNetDevice > devicePtr; /// Pointer to the net device
+    bool                       active;    /// Is net device enabled to TX/RX
+
+    CsmaDeviceRec();
+    CsmaDeviceRec(Ptr< CsmaNetDevice > device);
+    /*
+     * \return If the net device pointed to by the devicePtr is active
+     * and ready to RX/TX.
+     */
+    bool IsActive();                   
+  };
+
+  /**
+   * Current state of the channel
+   */ 
+  enum WireState
+    {
+      IDLE,          /**< Channel is IDLE, no packet is being
+                        transmitted */
+      TRANSMITTING,  /**< Channel is BUSY, a packet is being written
+                        by a net device */
+      PROPAGATING    /**< Channel is BUSY, packet is propagating to
+                        all attached net devices */
+    };
+
+/**
+ * \brief Csma Channel.
+ *
+ * This class represents a simple Csma channel that can be used
+ * when many nodes are connected to one wire. It uses a single busy
+ * flag to indicate if the channel is currently in use. It does not
+ * take into account the distances between stations or the speed of
+ * light to determine collisions.
+ *
+ * Each net device must query the state of the channel and make sure
+ * that it is IDLE before writing a packet to the channel.
+ *
+ * When the channel is instaniated, the constructor takes parameters
+ * for a single speed, in bits per second, and a speed-of-light delay
+ * time as a Time object.  When a net device is attached to a channel,
+ * it is assigned a device ID, this is in order to facilitate the
+ * check that makes sure that a net device that is trying to send a
+ * packet to the channel is really connected to this channel
+ *
+ */
+class CsmaChannel : public Channel {
+public:
+  /**
+   * \brief Create a CsmaChannel
+   *
+   * By default, you get a channel with the name "Csma Channel" that
+   * has an "infitely" fast transmission speed and zero delay.
+   */
+  CsmaChannel ();
+  
+  /**
+   * \brief Create a CsmaChannel
+   *
+   * \param bps The bitrate of the channel
+   * \param delay Transmission delay through the channel
+   */  
+  CsmaChannel (const DataRate& bps, const Time& delay);
+  
+  /**
+   * \brief Create a CsmaChannel
+   *
+   * \param name the name of the channel for identification purposes
+   * \param bps The bitrate of the channel
+   * \param delay Transmission delay through the channel
+   */
+  CsmaChannel (const std::string& name,
+                     const DataRate& bps, const Time& delay);
+
+  /**
+   * \brief Attach a given netdevice to this channel
+   *
+   * \param device Device pointer to the netdevice to attach to the channel
+   * \return The assigned device number
+   */
+  int32_t Attach (Ptr<CsmaNetDevice> device);
+  /**
+   * \brief Detach a given netdevice from this channel
+   *
+   * The net device is marked as inactive and it is not allowed to
+   * receive or transmit packets
+   *
+   * \param device Device pointer to the netdevice to detach from the channel
+   * \return True if the device is found and attached to the channel,
+   * false if the device is not currently connected to the channel or
+   * can't be found.
+   */
+  bool Detach (Ptr<CsmaNetDevice> device);
+  /**
+   * \brief Detach a given netdevice from this channel
+   *
+   * The net device is marked as inactive and it is not allowed to
+   * receive or transmit packets
+   *
+   * \param deviceId The deviceID assigned to the net device when it
+   * was connected to the channel
+   * \return True if the device is found and attached to the channel,
+   * false if the device is not currently connected to the channel or
+   * can't be found.
+   */
+  bool Detach (uint32_t deviceId);
+  /**
+   * \brief Reattach a previously detached net device to the channel
+   *
+   * The net device is marked as active. It is now allowed to receive
+   * or transmit packets. The net device must have been previously
+   * attached to the channel using the attach function.
+   *
+   * \param deviceId The device ID assigned to the net device when it
+   * was connected to the channel
+   * \return True if the device is found and is not attached to the
+   * channel, false if the device is currently connected to the
+   * channel or can't be found.
+   */
+  bool Reattach(uint32_t deviceId);
+  /**
+   * \brief Reattach a previously detached net device to the channel
+   *
+   * The net device is marked as active. It is now allowed to receive
+   * or transmit packets. The net device must have been previously
+   * attached to the channel using the attach function.
+   *
+   * \param device Device pointer to the netdevice to detach from the channel
+   * \return True if the device is found and is not attached to the
+   * channel, false if the device is currently connected to the
+   * channel or can't be found.
+   */
+  bool Reattach(Ptr<CsmaNetDevice> device);
+  /**
+   * \brief Start transmitting a packet over the channel
+   *
+   * If the srcId belongs to a net device that is connected to the
+   * channel, packet transmission begins, and the channel becomes busy
+   * until the packet has completely reached all destinations.
+   *
+   * \param p A reference to the packet that will be transmitted over
+   * the channel
+   * \param srcId The device Id of the net device that wants to
+   * transmit on the channel.
+   * \return True if the channel is not busy and the transmitting net
+   * device is currently active.
+   */
+  bool TransmitStart (Packet& p, uint32_t srcId);
+  /**
+   * \brief Indicates that the net device has finished transmitting
+   * the packet over the channel
+   *
+   * The channel will stay busy until the packet has completely
+   * propagated to all net devices attached to the channel. The
+   * TransmitEnd function schedules the PropagationCompleteEvent which
+   * will free the channel for further transmissions. Stores the
+   * packet p as the m_currentPkt, the packet being currently
+   * transmitting.
+   *
+   * \return Returns true unless the source was detached before it
+   * completed its transmission.
+   */
+  bool TransmitEnd ();
+  /**
+   * \brief Indicates that the channel has finished propagating the
+   * current packet. The channel is released and becomes free.
+   *
+   * Calls the receive function of every active net device that is
+   * attached to the channel.
+   */
+  void PropagationCompleteEvent();
+  /**
+   * \return Returns the device number assigned to a net device by the
+   * channel
+   *
+   * \param device Device pointer to the netdevice for which the device
+   * number is needed
+   */
+  int32_t GetDeviceNum (Ptr<CsmaNetDevice> device);
+  /**
+   * \return Returns the state of the channel (IDLE -- free,
+   * TRANSMITTING -- busy, PROPAGATING - busy )
+   */
+  WireState GetState();
+
+  /**
+   * \brief Indicates if the channel is busy. The channel will only
+   * accept new packets for transmission if it is not busy.
+   *
+   * \return Returns true if the channel is busy and false if it is
+   * free.
+   */
+  bool IsBusy();
+  
+  /**
+   * \brief Indicates if a net device is currently attached or
+   * detached from the channel.
+   *
+   * \param deviceId The ID that was assigned to the net device when
+   * it was attached to the channel.
+   * \return Returns true if the net device is attached to the
+   * channel, false otherwise.
+   */
+  bool IsActive(uint32_t deviceId);
+  /**
+   * \return Returns the number of net devices that are currently
+   * attached to the channel.
+   */
+  uint32_t GetNumActDevices (void);
+  /**
+   * \return Returns the total number of devices including devices
+   * that have been detached from the channel.
+   */
+  virtual uint32_t GetNDevices (void) const;
+  /**
+   * \param i The deviceId of the net device for which we want the
+   * pointer.
+   * \return Returns the pointer to the net device that is associated
+   * with deviceId i.
+   */
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+  virtual DataRate GetDataRate (void);
+  virtual Time GetDelay (void);
+
+private:
+  DataRate      m_bps;    /// Data rate of the channel
+  Time          m_delay;  /// Delay of the channel.
+
+  /**
+   * List of the net devices that have been or are currently connected
+   * to the channel.
+   *
+   * Devices are nor removed from this list, they are marked as
+   * inactive. Otherwise the assigned device IDs will not refer to the
+   * correct NetDevice. The DeviceIds are used so that it is possible
+   * to have a number to refer to an entry in the list so that the
+   * whole list does not have to be searched when making sure that a
+   * source is attached to a channel when it is transmitting data.
+   */
+  std::vector< CsmaDeviceRec >            m_deviceList;
+  /**
+   * Packet that is currently being transmitted on the channel (or last
+   * packet to have been transmitted on the channel if the channel is
+   * free.)
+   */
+  Packet                              m_currentPkt;
+  /**
+   * Device Id of the source that is currently transmitting on the
+   * channel. Or last source to have transmitted a packet on the
+   * channel, if the channel is currently not busy.
+   */
+  uint32_t                            m_currentSrc;
+  /**
+   * Current state of the channel
+   */
+  WireState          m_state;
+  /**
+   * Initializes the channel when it is constructed. Resets the
+   * deviceList and sets the channel state to IDLE.
+   */
+  void Init (void);
+};
+
+} // namespace ns3
+
+#endif /* CSMA_CHANNEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-ipv4-topology.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+#include <algorithm>
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/fatal-error.h"
+#include "ns3/nstime.h"
+#include "ns3/internet-node.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/queue.h"
+
+#include "csma-channel.h"
+#include "csma-net-device.h"
+#include "csma-ipv4-topology.h"
+
+namespace ns3 {
+
+uint32_t
+CsmaIpv4Topology::AddIpv4CsmaNode(Ptr<Node> n1,
+                                      Ptr<CsmaChannel> ch,
+                                      Eui48Address addr)
+{
+  Ptr<Queue> q = Queue::CreateDefault ();
+
+  // assume full-duplex
+  Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr, 
+                                                      ns3::CsmaNetDevice::IP_ARP,
+                                                      true, true);
+  nd0->AddQueue(q);
+  nd0->Attach (ch);
+  return nd0->GetIfIndex ();
+}
+
+
+void
+CsmaIpv4Topology::AddIpv4LlcCsmaNode(Ptr<Node> n1,
+                                         Ptr<CsmaChannel> ch,
+                                         Eui48Address addr)
+{
+  Ptr<Queue> q = Queue::CreateDefault ();
+
+  Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
+                                                      ns3::CsmaNetDevice::LLC,
+                                                      true, false);
+  nd0->AddQueue(q);
+  nd0->Attach (ch);
+
+  Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
+                                                      ns3::CsmaNetDevice::LLC,
+                                                      false, true);
+  nd1->AddQueue(q);
+  nd1->Attach (ch);
+}
+
+void
+CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr<Node> n1,
+                                         Ptr<CsmaChannel> ch,
+                                         Eui48Address addr)
+{
+  Ptr<Queue> q = Queue::CreateDefault ();
+
+  Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
+                                                      ns3::CsmaNetDevice::RAW,
+                                                      true, false);
+  nd0->AddQueue(q);
+  nd0->Attach (ch);
+
+  Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
+                                                      ns3::CsmaNetDevice::RAW,
+                                                      false, true);
+  nd1->AddQueue(q);
+  nd1->Attach (ch);
+}
+
+void
+CsmaIpv4Topology::AddIpv4Address(Ptr<Node> n1,
+                                       int ndNum,
+                                       const Ipv4Address& addr1,
+                                       const Ipv4Mask& netmask1)
+{
+
+  // Duplex link is assumed to be subnetted as a /30
+  // May run this unnumbered in the future?
+  Ipv4Mask netmask(netmask1);
+
+  Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
+
+  Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
+  uint32_t index1 = ip1->AddInterface (nd1);
+
+  ip1->SetAddress (index1, addr1);
+  ip1->SetNetworkMask (index1, netmask);
+  ip1->SetUp (index1);
+
+}
+
+void
+CsmaIpv4Topology::AddIpv4Routes (
+  Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
+{ 
+  // Assert that both are Ipv4 nodes
+  Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+  Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+  NS_ASSERT(ip1 != 0 && ip2 != 0);
+
+  // Get interface indexes for both nodes corresponding to the right channel
+  uint32_t index1 = 0;
+  bool found = false;
+  for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
+    {
+      if (ip1 ->GetNetDevice (i) == nd1)
+        {
+          index1 = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+
+  uint32_t index2 = 0;
+  found = false;
+  for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
+    {
+      if (ip2 ->GetNetDevice (i) == nd2)
+        {
+          index2 = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+
+  ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
+  ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); 
+}
+
+} // namespace ns3
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-ipv4-topology.h	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,122 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+#ifndef __CSMA_IPV4_TOPOLOGY_H__
+#define __CSMA_IPV4_TOPOLOGY_H__
+
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-net-device.h"
+
+// The topology class consists of only static methods thar are used to
+// create the topology and data flows for an ns3 simulation
+
+namespace ns3 {
+
+class CsmaIpv4Channel;
+class Node;
+class IPAddr;
+class DataRate;
+class Queue;
+
+/**
+ * \brief A helper class to create Topologies based on the
+ * InternetNodes and CsmaChannels. Either the
+ * SimpleCsmaNetDevice or the LLCCsmaNetDevice can be used
+ * when constructing these topologies.
+ */
+class CsmaIpv4Topology {
+public:
+
+  /**
+   * \param n1 Node to be attached to the Csma channel
+   * \param ch CsmaChannel to which node n1 should be attached
+   * \param addr Mac address of the node
+   *
+   * Add a Csma node to a Csma channel. This function adds
+   * a EthernetCsmaNetDevice to the nodes so that they can
+   * connect to a CsmaChannel. This means that Ethernet headers
+   * and trailers will be added to the packet before sending out on
+   * the net device.
+   * 
+   * \return ifIndex of the device
+   */
+  static uint32_t AddIpv4CsmaNode( Ptr<Node> n1,
+                                     Ptr<CsmaChannel> ch,
+                                     Eui48Address addr);
+
+  /**
+   * \param n1 Node to be attached to the Csma channel
+   * \param ch CsmaChannel to which node n1 should be attached
+   * \param addr Mac address of the node
+   *
+   * Add a Csma node to a Csma channel. This function adds
+   * a RawCsmaNetDevice to the nodes so that they can connect
+   * to a CsmaChannel.
+   */
+  static void AddIpv4RawCsmaNode( Ptr<Node> n1,
+                                    Ptr<CsmaChannel> ch,
+                                    Eui48Address addr);
+
+  /**
+   * \param n1 Node to be attached to the Csma channel
+   * \param ch CsmaChannel to which node n1 should be attached
+   * \param addr Mac address of the node
+   *
+   * Add a Csma node to a Csma channel. This function adds
+   * a LlcCsmaNetDevice to the nodes so that they can connect
+   * to a CsmaChannel.
+   */
+  static void AddIpv4LlcCsmaNode( Ptr<Node> n1,
+                                    Ptr<CsmaChannel> ch,
+                                    Eui48Address addr);
+
+
+
+  /** 
+   * \param n1 Node
+   * \param ndNum NetDevice number with which to associate address
+   * \param addr1 Ipv4 Address for ndNum of n1
+   * \param netmask1 network mask for ndNum of node n1
+   * 
+   * Add an Ipv4Address to the Ipv4 interface associated with the
+   * ndNum CsmaIpv4NetDevices on the provided
+   * CsmaIpv4Channel
+   */
+  static void AddIpv4Address(Ptr<Node> n1, int ndNum, 
+                             const Ipv4Address& addr1,
+                             const Ipv4Mask& netmask1);
+
+  /**
+   * \param nd1 Node
+   * \param nd2 Node
+   * 
+   * Add an IPV4 host route between the two specified net devices
+   */
+  static void AddIpv4Routes (Ptr<NetDevice> nd1, Ptr<NetDevice> nd2);
+};
+
+} // namespace ns3
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-net-device.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,580 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include <iostream>
+#include <cassert>
+#include "ns3/debug.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/composite-trace-resolver.h"
+#include "csma-net-device.h"
+#include "csma-channel.h"
+#include "ns3/ethernet-header.h"
+#include "ns3/ethernet-trailer.h"
+#include "ns3/llc-snap-header.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CsmaNetDevice");
+
+namespace ns3 {
+
+CsmaTraceType::CsmaTraceType (enum Type type)
+  : m_type (type)
+{}
+CsmaTraceType::CsmaTraceType ()
+  : m_type (RX)
+{}
+void 
+CsmaTraceType::Print (std::ostream &os) const
+{
+  switch (m_type) {
+  case RX:
+    os << "dev-rx";
+    break;
+  case DROP:
+    os << "dev-drop";
+    break;
+  }
+}
+uint16_t 
+CsmaTraceType::GetUid (void)
+{
+  static uint16_t uid = AllocateUid<CsmaTraceType> ("CsmaTraceType");
+  return uid;
+}
+std::string 
+CsmaTraceType::GetName (void) const
+{
+  return "CsmaTraceType";
+}
+
+
+CsmaNetDevice::CsmaNetDevice (Ptr<Node> node)
+  : NetDevice (node, Eui48Address::Allocate ()),
+    m_bps (DataRate (0xffffffff))
+{
+  NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
+  m_encapMode = IP_ARP;
+  Init(true, true);
+}
+
+CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr, 
+                                  CsmaEncapsulationMode encapMode) 
+  : NetDevice(node, addr), 
+    m_bps (DataRate (0xffffffff))
+{
+  NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
+  m_encapMode = encapMode;
+
+  Init(true, true);
+}
+
+CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr, 
+                                  CsmaEncapsulationMode encapMode,
+                                  bool sendEnable, bool receiveEnable) 
+  : NetDevice(node, addr), 
+    m_bps (DataRate (0xffffffff))
+{
+  NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
+  m_encapMode = encapMode;
+
+  Init(sendEnable, receiveEnable);
+}
+
+CsmaNetDevice::~CsmaNetDevice()
+{
+  NS_DEBUG ("CsmaNetDevice::~CsmaNetDevice ()");
+  m_queue = 0;
+}
+
+void 
+CsmaNetDevice::DoDispose ()
+{
+  m_channel = 0;
+  NetDevice::DoDispose ();
+}
+
+//
+// Assignment operator for CsmaNetDevice.
+//
+// This uses the non-obvious trick of taking the source net device passed by
+// value instead of by reference.  This causes the copy constructor to be
+// invoked (where the real work is done -- see above).  All we have to do
+// here is to return the newly constructed net device.
+//
+/*
+CsmaNetDevice&
+CsmaNetDevice::operator= (const CsmaNetDevice nd)
+{
+  NS_DEBUG ("CsmaNetDevice::operator= (" << &nd << ")");
+  return *this;
+}
+*/
+
+void 
+CsmaNetDevice::Init(bool sendEnable, bool receiveEnable)
+{
+  m_txMachineState = READY;
+  m_tInterframeGap = Seconds(0);
+  m_channel = 0; 
+  m_queue = 0;
+
+  EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
+  EnableMulticast();
+
+  SetSendEnable (sendEnable);
+  SetReceiveEnable (receiveEnable);
+}
+
+void
+CsmaNetDevice::SetSendEnable (bool sendEnable)
+{
+  m_sendEnable = sendEnable;
+}
+
+void
+CsmaNetDevice::SetReceiveEnable (bool receiveEnable)
+{
+  m_receiveEnable = receiveEnable;
+}
+bool
+CsmaNetDevice::IsSendEnabled (void)
+{
+  return (m_sendEnable);
+}
+
+bool
+CsmaNetDevice::IsReceiveEnabled (void)
+{
+  return (m_receiveEnable);
+}
+
+void 
+CsmaNetDevice::SetDataRate (DataRate bps)
+{
+  m_bps = bps;
+}
+
+void 
+CsmaNetDevice::SetInterframeGap (Time t)
+{
+  m_tInterframeGap = t;
+}
+
+void 
+CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, 
+                                      uint32_t maxSlots, uint32_t ceiling, 
+                                      uint32_t maxRetries)
+{
+  m_backoff.m_slotTime = slotTime;
+  m_backoff.m_minSlots = minSlots;
+  m_backoff.m_maxSlots = maxSlots;
+  m_backoff.m_ceiling = ceiling;
+  m_backoff.m_maxRetries = maxRetries;
+}
+void 
+CsmaNetDevice::AddHeader (Packet& p, Eui48Address dest,
+                            uint16_t protocolNumber)
+{
+  if (m_encapMode == RAW)
+    {
+      return;
+    }
+  EthernetHeader header (false);
+  EthernetTrailer trailer;
+  Eui48Address source = Eui48Address::ConvertFrom (GetAddress ());
+  header.SetSource(source);
+  header.SetDestination(dest);
+
+  uint16_t lengthType = 0;
+  switch (m_encapMode) 
+    {
+    case ETHERNET_V1:
+      lengthType = p.GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
+      break;
+    case IP_ARP:
+      lengthType = protocolNumber;
+      break;
+    case LLC: {
+      LlcSnapHeader llc;
+      llc.SetType (protocolNumber);
+      p.AddHeader (llc);
+    } break;
+    case RAW:
+      NS_ASSERT (false);
+      break;
+    }
+  header.SetLengthType (lengthType);
+  p.AddHeader(header);
+  trailer.CalcFcs(p);
+  p.AddTrailer(trailer);
+}
+bool 
+CsmaNetDevice::ProcessHeader (Packet& p, uint16_t & param)
+{
+  if (m_encapMode == RAW)
+    {
+      return true;
+    }
+  EthernetHeader header (false);
+  EthernetTrailer trailer;
+      
+  p.RemoveTrailer(trailer);
+  trailer.CheckFcs(p);
+  p.RemoveHeader(header);
+
+  if ((header.GetDestination() != GetBroadcast ()) &&
+      (header.GetDestination() != GetAddress ()))
+    {
+      return false;
+    }
+
+  switch (m_encapMode)
+    {
+    case ETHERNET_V1:
+    case IP_ARP:
+      param = header.GetLengthType();
+      break;
+    case LLC: {
+      LlcSnapHeader llc;
+      p.RemoveHeader (llc);
+      param = llc.GetType ();
+    } break;
+    case RAW:
+      NS_ASSERT (false);
+      break;
+    }
+  return true;
+}
+
+bool
+CsmaNetDevice::DoNeedsArp (void) const
+{
+  if ((m_encapMode == IP_ARP) || (m_encapMode == LLC))
+    {
+      return true;
+    } 
+  else 
+    {
+      return false;
+    }
+}
+
+bool
+CsmaNetDevice::SendTo (
+  const Packet& packet, 
+  const Address& dest, 
+  uint16_t protocolNumber)
+{
+  Packet p = packet;
+  NS_DEBUG ("CsmaNetDevice::SendTo (" << &p << ")");
+  NS_DEBUG ("CsmaNetDevice::SendTo (): UID is " << p.GetUid () << ")");
+
+  NS_ASSERT (IsLinkUp ());
+
+  // Only transmit if send side of net device is enabled
+  if (!IsSendEnabled())
+    return false;
+
+  Eui48Address destination = Eui48Address::ConvertFrom (dest);
+  AddHeader(p, destination, protocolNumber);
+
+  // Place the packet to be sent on the send queue
+  if (m_queue->Enqueue(p) == false )
+    {
+      return false;
+    }
+  // If the device is idle, we need to start a transmission. Otherwise,
+  // the transmission will be started when the current packet finished
+  // transmission (see TransmitCompleteEvent)
+  if (m_txMachineState == READY) 
+    {
+      // Store the next packet to be transmitted
+      if (m_queue->Dequeue (m_currentPkt))
+        {
+          TransmitStart();
+        }
+    }
+  return true;
+}
+
+void
+CsmaNetDevice::TransmitStart ()
+{
+  NS_DEBUG ("CsmaNetDevice::TransmitStart (" << &m_currentPkt << ")");
+  NS_DEBUG ("CsmaNetDevice::TransmitStart (): UID is " 
+            << m_currentPkt.GetUid () << ")");
+//
+// This function is called to start the process of transmitting a packet.
+// We need to tell the channel that we've started wiggling the wire and
+// schedule an event that will be executed when it's time to tell the 
+// channel that we're done wiggling the wire.
+//
+  NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF), 
+                "Must be READY to transmit. Tx state is: " 
+                << m_txMachineState);
+
+  // Only transmit if send side of net device is enabled
+  if (!IsSendEnabled())
+    return;
+
+  if (m_channel->GetState() != IDLE)
+    { // Channel busy, backoff and rechedule TransmitStart()
+      m_txMachineState = BACKOFF;
+      if (m_backoff.MaxRetriesReached())
+        { // Too many retries reached, abort transmission of packet
+          TransmitAbort();
+        } 
+      else 
+        {
+          m_backoff.IncrNumRetries();
+          Time backoffTime = m_backoff.GetBackoffTime();
+
+          NS_DEBUG ("CsmaNetDevice::TransmitStart (): " 
+                    << "Channel busy, backing off for " 
+                    << backoffTime.GetSeconds () << "sec");
+
+          Simulator::Schedule (backoffTime, 
+                               &CsmaNetDevice::TransmitStart, 
+                               this);
+        }
+    } 
+  else 
+    {
+      // Channel is free, transmit packet
+      m_txMachineState = BUSY;
+      Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
+      
+      NS_DEBUG ("CsmaNetDevice::TransmitStart (): " <<
+                "Schedule TransmitCompleteEvent in " << 
+                tEvent.GetSeconds () << "sec");
+      
+      Simulator::Schedule (tEvent, 
+                           &CsmaNetDevice::TransmitCompleteEvent, 
+                           this);
+      if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
+        {
+          NS_DEBUG ("CsmaNetDevice::TransmitStart (): " <<
+                    "Channel transmit start did not work at " << 
+                    tEvent.GetSeconds () << "sec");
+          m_txMachineState = READY;
+        } 
+      else 
+        {
+          // Transmission success, reset backoff time parameters.
+          m_backoff.ResetBackoffTime();
+        }
+    }
+}
+
+
+void
+CsmaNetDevice::TransmitAbort (void)
+{
+  NS_DEBUG ("CsmaNetDevice::TransmitAbort ()");
+
+  NS_DEBUG ("CsmaNetDevice::TransmitAbort (): Pkt UID is " <<
+            m_currentPkt.GetUid () << ")");
+
+  // Try to transmit a new packet
+  bool found;
+  found = m_queue->Dequeue (m_currentPkt);
+  NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
+  m_backoff.ResetBackoffTime();
+  m_txMachineState = READY;
+  TransmitStart ();
+}
+
+void
+CsmaNetDevice::TransmitCompleteEvent (void)
+{
+  NS_DEBUG ("CsmaNetDevice::TransmitCompleteEvent ()");
+//
+// This function is called to finish the  process of transmitting a packet.
+// We need to tell the channel that we've stopped wiggling the wire and
+// schedule an event that will be executed when it's time to re-enable
+// the transmitter after the interframe gap.
+//
+  NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
+  // Channel should be transmitting
+  NS_ASSERT(m_channel->GetState() == TRANSMITTING);
+  m_txMachineState = GAP;
+
+  NS_DEBUG ("CsmaNetDevice::TransmitCompleteEvent (): Pkt UID is " << 
+            m_currentPkt.GetUid () << ")");
+  m_channel->TransmitEnd (); 
+
+  NS_DEBUG (
+    "CsmaNetDevice::TransmitCompleteEvent (): " <<
+    "Schedule TransmitReadyEvent in "
+    << m_tInterframeGap.GetSeconds () << "sec");
+
+  Simulator::Schedule (m_tInterframeGap, 
+                       &CsmaNetDevice::TransmitReadyEvent, 
+                       this);
+}
+
+void
+CsmaNetDevice::TransmitReadyEvent (void)
+{
+  NS_DEBUG ("CsmaNetDevice::TransmitReadyEvent ()");
+//
+// This function is called to enable the transmitter after the interframe
+// gap has passed.  If there are pending transmissions, we use this opportunity
+// to start the next transmit.
+//
+  NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
+  m_txMachineState = READY;
+
+  // Get the next packet from the queue for transmitting
+  if (m_queue->IsEmpty())
+    {
+      return;
+    }
+  else
+    {
+      bool found;
+      found = m_queue->Dequeue (m_currentPkt);
+      NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
+      TransmitStart ();
+    }
+}
+
+Ptr<TraceResolver>
+CsmaNetDevice::GetTraceResolver (void)
+{
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+  resolver->AddChild ("queue", m_queue);
+  resolver->AddSource ("rx",
+                       "receive MAC packet",
+                       m_rxTrace,
+                       CsmaTraceType (CsmaTraceType::RX));
+  resolver->AddSource ("drop",
+                       "drop MAC packet",  
+                       m_dropTrace,
+                       CsmaTraceType (CsmaTraceType::DROP));
+  resolver->SetParent (NetDevice::GetTraceResolver ());
+  return resolver;
+}
+
+bool
+CsmaNetDevice::Attach (Ptr<CsmaChannel> ch)
+{
+  NS_DEBUG ("CsmaNetDevice::Attach (" << &ch << ")");
+
+  m_channel = ch;
+
+  m_deviceId = m_channel->Attach(this);
+  m_bps = m_channel->GetDataRate ();
+  m_tInterframeGap = m_channel->GetDelay ();
+
+  /* 
+   * For now, this device is up whenever a channel is attached to it.
+   */
+  NotifyLinkUp ();
+  return true;
+}
+
+void
+CsmaNetDevice::AddQueue (Ptr<Queue> q)
+{
+  NS_DEBUG ("CsmaNetDevice::AddQueue (" << q << ")");
+
+  m_queue = q;
+}
+
+void
+CsmaNetDevice::Receive (const Packet& packet)
+{
+  EthernetHeader header (false);
+  EthernetTrailer trailer;
+  Eui48Address broadcast;
+  Eui48Address destination;
+  Packet p = packet;
+
+  NS_DEBUG ("CsmaNetDevice::Receive UID is (" << p.GetUid() << ")");
+
+  // Only receive if send side of net device is enabled
+  if (!IsReceiveEnabled())
+    {
+      m_dropTrace (p);
+      return;
+    }
+
+  if (m_encapMode == RAW)
+    {
+      ForwardUp (packet, 0, GetBroadcast ());
+      m_dropTrace (p);
+      return;
+    }
+  p.RemoveTrailer(trailer);
+  trailer.CheckFcs(p);
+  p.RemoveHeader(header);
+
+  broadcast = Eui48Address::ConvertFrom (GetBroadcast ());
+  destination = Eui48Address::ConvertFrom (GetAddress ());
+  if ((header.GetDestination() != broadcast) &&
+      (header.GetDestination() != destination))
+    {
+      // not for us.
+      m_dropTrace (p);
+      return;
+    }
+
+  m_rxTrace (p);
+//
+// protocol must be initialized to avoid a compiler warning in the RAW
+// case that breaks the optimized build.
+//
+  uint16_t protocol = 0;
+
+  switch (m_encapMode)
+    {
+    case ETHERNET_V1:
+    case IP_ARP:
+      protocol = header.GetLengthType();
+      break;
+    case LLC: {
+      LlcSnapHeader llc;
+      p.RemoveHeader (llc);
+      protocol = llc.GetType ();
+    } break;
+    case RAW:
+      NS_ASSERT (false);
+      break;
+    }
+  
+  ForwardUp (p, protocol, header.GetSource ());
+  return;
+}
+
+Ptr<Queue>
+CsmaNetDevice::GetQueue(void) const 
+{ 
+    return m_queue;
+}
+
+Ptr<Channel>
+CsmaNetDevice::DoGetChannel(void) const 
+{ 
+    return m_channel;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-net-device.h	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,434 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
+ * Derived from the p2p net device file
+ */
+
+#ifndef CSMA_NET_DEVICE_H
+#define CSMA_NET_DEVICE_H
+
+#include <string.h>
+#include "ns3/node.h"
+#include "ns3/backoff.h"
+#include "ns3/address.h"
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/callback-trace-source.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "ns3/eui48-address.h"
+
+namespace ns3 {
+
+class Queue;
+class CsmaChannel;
+
+class CsmaTraceType : public TraceContextElement
+{
+public:
+  enum Type {
+    RX, 
+    DROP
+  };
+  CsmaTraceType (enum Type type);
+  CsmaTraceType ();
+  void Print (std::ostream &os) const;
+  static uint16_t GetUid (void);
+  std::string GetName (void) const;
+private:
+  enum Type m_type;
+};
+
+/**
+ * \class CsmaNetDevice
+ * \brief A Device for a Csma Network Link.
+ *
+ * The Csma net device class is analogous to layer 1 and 2 of the
+ * TCP stack. The NetDevice takes a raw packet of bytes and creates a
+ * protocol specific packet from them. The Csma net device class
+ * takes this packet and adds and processes the headers/trailers that
+ * are associated with EthernetV1, EthernetV2, RAW or LLC
+ * protocols. The EthernetV1 packet type adds and removes Ethernet
+ * destination and source addresses. The LLC packet type adds and
+ * removes LLC snap headers. The raw packet type does not add or
+ * remove any headers.  Each Csma net device will receive all
+ * packets written to the Csma link. The ProcessHeader function can
+ * be used to filter out the packets such that higher level layers
+ * only receive packets that are addressed to their associated net
+ * devices
+ *
+ */
+class CsmaNetDevice : public NetDevice {
+public:
+
+  /**
+   * Enumeration of the types of packets supported in the class.
+   *
+   */
+enum CsmaEncapsulationMode {
+  ETHERNET_V1, /**< Version one ethernet packet, length field */
+  IP_ARP,      /**< Ethernet packet encapsulates IP/ARP packet */
+  RAW,         /**< Packet that contains no headers */
+  LLC,         /**< LLC packet encapsulation */  
+};
+
+  CsmaNetDevice (Ptr<Node> node);
+  /**
+   * Construct a CsmaNetDevice
+   *
+   * This is the constructor for the CsmaNetDevice.  It takes as a
+   * parameter the Node to which this device is connected.  Ownership of the
+   * Node pointer is not implied and the node must not be deleted.
+   *
+   * \param node the Node to which this device is connected.
+   * \param addr The source MAC address of the net device.
+   * \param pktType the type of encapsulation
+   */
+  CsmaNetDevice (Ptr<Node> node, Eui48Address addr, CsmaEncapsulationMode pktType);
+
+  /**
+   * Construct a CsmaNetDevice
+   *
+   * This is the constructor for the CsmaNetDevice.  It takes as a
+   * parameter the Node to which this device is connected.  Ownership of the
+   * Node pointer is not implied and the node must not be deleted.
+   *
+   * \param node the Node to which this device is connected.
+   * \param addr The source MAC address of the net device.
+   * \param pktType the type of encapsulation
+   * \param sendEnable whether this device is able to send
+   * \param receiveEnable whether this device is able to receive
+   */
+  CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
+                   CsmaEncapsulationMode pktType,
+                   bool sendEnable, bool receiveEnable);
+  /**
+   * Destroy a CsmaNetDevice
+   *
+   * This is the destructor for the CsmaNetDevice.
+   */
+  virtual ~CsmaNetDevice();
+  /**
+   * Set the Data Rate used for transmission of packets.  The data rate is
+   * set in the Attach () method from the corresponding field in the channel
+   * to which the device is attached.  It can be overridden using this method.
+   *
+   * @see Attach ()
+   * \param bps the data rate at which this object operates
+   */
+  void SetDataRate (DataRate bps);
+  /**
+   * Set the inteframe gap used to separate packets.  The interframe gap
+   * defines the minimum space required between packets sent by this device.
+   * It is usually set in the Attach () method based on the speed of light
+   * delay of the channel to which the device is attached.  It can be 
+   * overridden using this method if desired.
+   *
+   * @see Attach ()
+   * \param t the interframe gap time
+   */
+  void SetInterframeGap (Time t);
+  /**
+   * Set the backoff parameters used to determine the wait to retry
+   * transmitting a packet when the channel is busy.
+   *
+   * @see Attach ()
+   * \param slotTime Length of a packet slot (or average packet time)
+   * \param minSlots Minimum number of slots to wait
+   * \param maxSlots Maximum number of slots to wait
+   * \param maxRetries Maximum number of retries before packet is discard
+   * \param ceiling Cap on the exponential function when calculating max slots
+   */
+  void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, 
+                        uint32_t maxRetries, uint32_t ceiling);
+  /**
+   * Attach the device to a channel.
+   *
+   * The function Attach is used to add a CsmaNetDevice to a
+   * CsmaChannel.
+   *
+   * @see SetDataRate ()
+   * @see SetInterframeGap ()
+   * \param ch a pointer to the channel to which this object is being attached.
+   */
+  bool Attach (Ptr<CsmaChannel> ch);
+  /**
+   * Attach a queue to the CsmaNetDevice.
+   *
+   * The CsmaNetDevice "owns" a queue.  This queue is created by the
+   * CsmaTopology object and implements a queueing method such as
+   * DropTail or RED.  The CsmaNetDevice assumes ownership of this
+   * queue and must delete it when the device is destroyed.
+   *
+   * @see CsmaTopology::AddCsmaLink ()
+   * @see Queue
+   * @see DropTailQueue
+   * \param queue a pointer to the queue for which object is assuming
+   *        ownership.
+   */
+  void AddQueue (Ptr<Queue> queue);
+  /**
+   * Receive a packet from a connected CsmaChannel.
+   *
+   * The CsmaNetDevice receives packets from its connected channel
+   * and forwards them up the protocol stack.  This is the public method
+   * used by the channel to indicate that the last bit of a packet has 
+   * arrived at the device.
+   *
+   * @see CsmaChannel
+   * \param p a reference to the received packet
+   */
+  void Receive (const Packet& p);
+
+  bool IsSendEnabled (void);
+  bool IsReceiveEnabled (void);
+
+  void SetSendEnable (bool);
+  void SetReceiveEnable (bool);
+
+protected:
+  virtual bool DoNeedsArp (void) const;
+  virtual void DoDispose (void);
+  /**
+   * Create a Trace Resolver for events in the net device.
+   * (NOT TESTED)
+   * @see class TraceResolver
+   */
+  virtual Ptr<TraceResolver> GetTraceResolver (void);
+
+  /**
+   * Get a copy of the attached Queue.
+   *
+   * This method is provided for any derived class that may need to get
+   * direct access to the underlying queue.
+   *
+   * \return a pointer to the queue.
+   */
+  Ptr<Queue> GetQueue (void) const; 
+  /**
+   * Get a copy of the attached Channel
+   *
+   * This method is provided for any derived class that may need to get
+   * direct access to the connected channel
+   *
+   * \return a pointer to the channel
+   */
+  virtual Ptr<Channel> DoGetChannel (void) const;
+  /**
+   * Adds the necessary headers and trailers to a packet of data in order to
+   * respect the packet type
+   *
+   * \param p Packet to which header should be added
+   * \param dest MAC destination address to which packet should be sent
+   * \param protocolNumber In some protocols, identifies the type of
+   * payload contained in this packet.
+   */
+  void AddHeader (Packet& p, Eui48Address dest, 
+                  uint16_t protocolNumber);
+  /**
+   * Removes, from a packet of data, all headers and trailers that
+   * relate to the packet type
+   *
+   * \param p Packet whose headers need to be processed
+   * \param param An integer parameter that can be set by the function
+   * to return information gathered in the header
+   * \return Returns true if the packet should be forwarded up the
+   * protocol stack.
+   */
+  bool ProcessHeader (Packet& p, uint16_t & param);
+
+private:
+  // disable copy constructor and operator =
+  CsmaNetDevice &operator = (const CsmaNetDevice &o);
+  CsmaNetDevice (const CsmaNetDevice &o);
+  /**
+   * Initializes variablea when construction object.
+   */
+  void Init (bool sendEnable, bool receiveEnable);
+  /**
+   * Send a Packet on the Csma network
+   *
+   * This method does not use a destination address since all packets
+   * are broadcast to all NetDevices attached to the channel. Packet
+   * should contain all needed headers at this time.
+   *
+   * If the device is ready to transmit, the next packet is read off
+   * of the queue and stored locally until it has been transmitted.
+   *
+   * \param p a reference to the packet to send
+   * \param dest destination address
+   * \param protocolNumber -- this parameter is not used here
+   * \return true if success, false on failure
+   */
+  virtual bool SendTo (const Packet& p, const Address& dest, uint16_t protocolNumber);
+
+  /**
+   * Start Sending a Packet Down the Wire.
+   *
+   * The TransmitStart method is the method that is used internally in
+   * the CsmaNetDevice to begin the process of sending a packet
+   * out on the channel.  The corresponding method is called on the
+   * channel to let it know that the physical device this class
+   * represents has virually started sending signals, this causes the
+   * channel to become busy.  An event is scheduled for the time at
+   * which the bits have been completely transmitted. If the channel
+   * is busy, the method reschedules itself for a later time (within
+   * the backoff period)
+   *
+   * @see CsmaChannel::TransmitStart ()
+   * @see TransmitCompleteEvent ()
+   */
+  void TransmitStart ();
+  /**
+   * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
+   *
+   * The TransmitCompleteEvent method is used internally to finish the process
+   * of sending a packet out on the channel.  During execution of this method
+   * the TransmitEnd method is called on the channel to let it know that the
+   * physical device this class represents has virually finished sending 
+   * signals.  The channel uses this event to begin its speed of light delay
+   * timer after which it notifies the Net Device at the other end of the 
+   * link that the bits have arrived.  During this method, the net device 
+   * also schedules the TransmitReadyEvent at which time the transmitter 
+   * becomes ready to send the next packet.
+   *
+   * @see CsmaChannel::TransmitEnd ()
+   * @see TransmitReadyEvent ()
+   */
+  void TransmitCompleteEvent (void);
+  /**
+   * Cause the Transmitter to Become Ready to Send Another Packet.
+   *
+   * The TransmitReadyEvent method is used internally to re-enable the 
+   * transmit machine of the net device.  It is scheduled after a suitable
+   * interframe gap after the completion of the previous transmission.
+   * The queue is checked at this time, and if there is a packet waiting on
+   * the queue, the transmission process is begun.
+   *
+   * If a packet is in the queue, it is extracted for the queue as the
+   * next packet to be transmitted by the net device.
+   *
+   * @see TransmitStart ()
+   */
+  void TransmitReadyEvent (void);
+
+  /**
+   * Aborts the transmission of the current packet
+   *
+   * If the net device has tried to transmit a packet for more times
+   * than the maximum allowed number of retries (channel always busy)
+   * then the packet is dropped.
+   *
+   */
+  void TransmitAbort (void);
+
+  /** 
+   * Device ID returned by the attached functions. It is used by the
+   * mp-channel to identify each net device to make sure that only
+   * active net devices are writing to the channel
+   */
+  uint32_t m_deviceId; 
+
+  /**
+   * Enable net device to send packets. True by default
+   */
+  bool m_sendEnable;
+  /**
+   * Enable net device to receive packets. True by default
+   */
+  bool m_receiveEnable;
+  /**
+   * Enumeration of the states of the transmit machine of the net device.
+   */
+  enum TxMachineState
+    {
+      READY, /**< The transmitter is ready to begin transmission of a packet */
+      BUSY,  /**< The transmitter is busy transmitting a packet */
+      GAP,    /**< The transmitter is in the interframe gap time */
+      BACKOFF    /**< The transmitter is waiting for the channel to be free */
+    };
+  /**
+   * The state of the Net Device transmit state machine.
+   * @see TxMachineState
+   */
+  TxMachineState m_txMachineState;
+  
+  /**
+   * The type of packet that should be created by the AddHeader
+   * function and that should be processed by the ProcessHeader
+   * function.
+   */
+  CsmaEncapsulationMode m_encapMode;
+  /**
+   * The data rate that the Net Device uses to simulate packet transmission
+   * timing.
+   * @see class DataRate
+   */
+  DataRate m_bps;
+  /**
+   * The interframe gap that the Net Device uses to throttle packet
+   * transmission
+   * @see class Time
+   */
+  Time m_tInterframeGap;
+  /**
+   * Holds the backoff parameters and is used to calculate the next
+   * backoff time to use when the channel is busy and the net device
+   * is ready to transmit
+   */
+  Backoff m_backoff;
+  /**
+   * Next packet that will be transmitted (if transmitter is not
+   * currently transmitting) or packet that is currently being
+   * transmitted.
+   */
+  Packet m_currentPkt;
+  /**
+   * The CsmaChannel to which this CsmaNetDevice has been
+   * attached.
+   * @see class CsmaChannel
+   */
+  Ptr<CsmaChannel> m_channel;
+  /**
+   * The Queue which this CsmaNetDevice uses as a packet source.
+   * Management of this Queue has been delegated to the CsmaNetDevice
+   * and it has the responsibility for deletion.
+   * @see class Queue
+   * @see class DropTailQueue
+   */
+  Ptr<Queue> m_queue;
+  /**
+   * NOT TESTED
+   * The trace source for the packet reception events that the device can
+   * fire.
+   *
+   * @see class CallBackTraceSource
+   * @see class TraceResolver
+   */
+  CallbackTraceSource<Packet &> m_rxTrace;
+  CallbackTraceSource<Packet &> m_dropTrace;
+
+};
+
+}; // namespace ns3
+
+#endif // CSMA_NET_DEVICE_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-topology.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+//
+// Topology helper for Csma channels in ns3.
+
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/queue.h"
+
+#include "csma-channel.h"
+#include "csma-net-device.h"
+#include "csma-topology.h"
+#include "ns3/socket-factory.h"
+
+namespace ns3 {
+
+Ptr<CsmaChannel>
+CsmaTopology::CreateCsmaChannel(
+  const DataRate& bps,
+  const Time& delay)
+{
+  Ptr<CsmaChannel> channel = Create<CsmaChannel> (bps, delay);
+
+  return channel;
+}
+
+#if 0
+Ptr<CsmaNetDevice>
+CsmaTopology::AddCsmaEthernetNode(
+  Ptr<Node> n1,
+  Ptr<CsmaChannel> ch,
+  MacAddress addr)
+{
+  Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr, 
+                                                      ns3::CsmaNetDevice::ETHERNET_V1);
+
+  Ptr<Queue> q = Queue::CreateDefault ();
+  nd1->AddQueue(q);
+  nd1->Attach (ch);
+  
+  return nd1;
+}
+
+Ptr<PacketSocket>
+CsmaTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app, 
+                                        Ptr<CsmaNetDevice> ndSrc,
+                                        Ptr<CsmaNetDevice> ndDest)
+{
+  Ptr<PacketSocket> socket = Create<PacketSocket> ();
+  socket->Bind(ndSrc);
+  socket->Connect(ndDest->GetAddress());
+  app->Connect(socket);
+
+  return socket;
+}
+
+Ptr<PacketSocket>
+CsmaTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
+                                        Ptr<CsmaNetDevice> ndSrc,
+                                        MacAddress macAddr)
+{
+  Ptr<PacketSocket> socket = Create<PacketSocket> ();
+  socket->Bind(ndSrc);
+  socket->Connect(macAddr);
+  app->Connect(socket);
+
+  return socket;
+}
+
+Ptr<Socket>
+CsmaTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
+{
+  InterfaceId iid = InterfaceId::LookupByName (iid_name);
+
+  Ptr<SocketFactory> socketFactory =
+    n1->QueryInterface<SocketFactory> (iid);
+
+  Ptr<Socket> socket = socketFactory->CreateSocket ();
+
+  return socket;
+}
+#endif
+
+} // namespace ns3
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-topology.h	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,123 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+// Topology helper for multipoint channels in ns3.
+// 
+#ifndef CSMA_TOPOLOGY_H
+#define CSMA_TOPOLOGY_H
+
+#include "ns3/ptr.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/node.h"
+
+// The topology class consists of only static methods thar are used to
+// create the topology and data flows for an ns3 simulation
+
+namespace ns3 {
+
+class CsmaChannel;
+class Node;
+class DataRate;
+class Queue;
+
+/**
+ * \brief A helper class to create Csma Topologies 
+ *
+ * Csma topologies are created based on the
+ * ns3::CsmaNetDevice subclasses and ns3::CsmaChannel
+ * objects.  This class uses the EthernetNetDevice and
+ * PacketSocket classes in order to create logical connections between
+ * net devices. The PacketSocket class generates the data and the
+ * EthernetNetDevice class creates ethernet packets from the
+ * data, filling in source and destination addresses. The
+ * EthernetNetDevice class filters received data packets
+ * according to its destination Mac addresses.
+ */
+class CsmaTopology {
+public:
+  /** 
+   * \param dataRate Maximum transmission link rate 
+   * \param delay propagation delay between any two nodes 
+   * \return Pointer to the created CsmaChannel
+   * 
+   * Create a CsmaChannel. All nodes connected to a multipoint
+   * channels will receive all packets written to that channel
+   */
+  static Ptr<CsmaChannel> CreateCsmaChannel(
+    const DataRate& dataRate, const Time& delay);
+
+#if 0
+  /**
+   * \param n1 Node to be attached to the multipoint channel
+   * \param ch CsmaChannel to which node n1 should be attached 
+   * \param addr MacAddress that should be assigned to the
+   * EthernetNetDevice that will be added to the node.
+   *
+   * Add a multipoint node to a multipoint channel
+   */
+  static Ptr<CsmaNetDevice> AddCsmaEthernetNode(Ptr<Node> n1, 
+                                                    Ptr<CsmaChannel> ch,
+                                                    MacAddress addr);
+
+  /**
+   * \param app Application that will be sending data to the agent
+   * \param ndSrc Net Device that will be sending the packets onto the
+   * network
+   * \param ndDest Net Device to which ndSrc will be sending the packets
+   * \return A pointer to the PacketSocket
+   *
+   * Creates an PacketSocket and configure it to send packets between
+   * two net devices
+   */
+static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
+                                      Ptr<CsmaNetDevice> ndSrc,
+                                      Ptr<CsmaNetDevice> ndDest);
+
+  /**
+   * \param app Application that will be sending data to the agent
+   * \param ndSrc Net Device that will be sending the packets onto the
+   * network 
+   * \param macAddr Mac destination address for the packets send by
+   * the ndSrc net device \return a Pointer to the created
+   * PacketSocket
+   *
+   * Creates an PacketSocket and configure it to send packets from a
+   * net device to a destination MacAddress
+   */
+static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
+                                      Ptr<CsmaNetDevice> ndSrc,
+                                      MacAddress macAddr);
+
+  /**
+   * \param n1 Node from which socketfactory should be tested.
+   * \param iid_name Interface identifier ("Packet", in this case)
+   *
+   * This is a test function to make sure that a socket can be created
+   * by using the socketfactory interface provided in the
+   * netdevicenode.
+   */
+static  Ptr<Socket> CreatePacketSocket(Ptr<Node> n1, 
+                                       std::string iid_name);
+#endif
+
+};
+} // namespace ns3
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/wscript	Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,19 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+    obj = bld.create_ns3_module('csma', ['node'])
+    obj.source = [
+        'backoff.cc',
+        'csma-net-device.cc',
+        'csma-channel.cc',
+        'csma-topology.cc',
+        'csma-ipv4-topology.cc',
+        ]
+    headers = bld.create_obj('ns3header')
+    headers.source = [
+        'backoff.h',
+        'csma-net-device.h',
+        'csma-channel.h',
+        'csma-topology.h',
+        'csma-ipv4-topology.h',
+        ]
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -122,9 +122,10 @@
   m_tInterframeGap = t;
 }
 
-bool PointToPointNetDevice::SendTo (Packet& p, const Address& dest, 
+bool PointToPointNetDevice::SendTo (const Packet& packet, const Address& dest, 
                                     uint16_t protocolNumber)
 {
+  Packet p = packet;
   NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
   NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
 
@@ -243,8 +244,8 @@
   uint16_t protocol = 0;
   Packet packet = p;
 
+  m_rxTrace (packet);
   ProcessHeader(packet, protocol);
-  m_rxTrace (packet);
   ForwardUp (packet, protocol, GetBroadcast ());
 }
 
--- a/src/devices/point-to-point/point-to-point-net-device.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Tue Aug 28 12:05:35 2007 +0200
@@ -182,7 +182,6 @@
   virtual Ptr<Channel> DoGetChannel(void) const;
   /**
    * Set a new default data rate
-   * @param Data rate to set for new default
    */
   static void SetDefaultRate(const DataRate&);
 
@@ -219,7 +218,7 @@
    * @param protocolNumber Protocol Number used to find protocol touse
    * @returns true if success, false on failure
    */
-  virtual bool SendTo (Packet& p, const Address& dest, 
+  virtual bool SendTo (const Packet& p, const Address& dest, 
                        uint16_t protocolNumber);
   /**
    * Start Sending a Packet Down the Wire.
--- a/src/internet-node/ascii-trace.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/ascii-trace.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -25,6 +25,7 @@
 #include "ns3/node.h"
 #include "ns3/node-list.h"
 #include "ns3/packet.h"
+#include "ns3/queue.h"
 
 namespace ns3 {
 
@@ -40,8 +41,12 @@
 AsciiTrace::TraceAllQueues (void)
 {
   Packet::EnableMetadata ();
-  NodeList::Connect ("/nodes/*/devices/*/queue/*",
-                     MakeCallback (&AsciiTrace::LogDevQueue, this));
+  NodeList::Connect ("/nodes/*/devices/*/queue/enqueue",
+                      MakeCallback (&AsciiTrace::LogDevQueueEnqueue, this));
+  NodeList::Connect ("/nodes/*/devices/*/queue/dequeue",
+                      MakeCallback (&AsciiTrace::LogDevQueueDequeue, this));
+  NodeList::Connect ("/nodes/*/devices/*/queue/drop",
+                      MakeCallback (&AsciiTrace::LogDevQueueDrop, this));
 }
 void
 AsciiTrace::TraceAllNetDeviceRx (void)
@@ -52,8 +57,34 @@
 }
 
 void 
-AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet)
+AsciiTrace::LogDevQueueEnqueue (TraceContext const &context, 
+  Packet const &packet)
 {
+  m_os << "+ ";
+  m_os << Simulator::Now ().GetSeconds () << " ";
+  context.Print (m_os);
+  m_os << " pkt-uid=" << packet.GetUid () << " ";
+  packet.Print (m_os);
+  m_os << std::endl;
+}
+
+void 
+AsciiTrace::LogDevQueueDequeue (TraceContext const &context, 
+  Packet const &packet)
+{
+  m_os << "- ";
+  m_os << Simulator::Now ().GetSeconds () << " ";
+  context.Print (m_os);
+  m_os << " pkt-uid=" << packet.GetUid () << " ";
+  packet.Print (m_os);
+  m_os << std::endl;
+}
+
+void 
+AsciiTrace::LogDevQueueDrop (TraceContext const &context, 
+  Packet const &packet)
+{
+  m_os << "d ";
   m_os << Simulator::Now ().GetSeconds () << " ";
   context.Print (m_os);
   m_os << " pkt-uid=" << packet.GetUid () << " ";
@@ -63,7 +94,7 @@
 void 
 AsciiTrace::LogDevRx (TraceContext const &context, Packet &p)
 {
-  m_os << Simulator::Now ().GetSeconds () << " ";
+  m_os << "r " << Simulator::Now ().GetSeconds () << " ";
   context.Print (m_os);
   m_os << " pkt-uid=" << p.GetUid () << " ";
   p.Print (m_os);
--- a/src/internet-node/ascii-trace.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/ascii-trace.h	Tue Aug 28 12:05:35 2007 +0200
@@ -37,7 +37,9 @@
   void TraceAllQueues (void);
   void TraceAllNetDeviceRx (void);
 private:
-  void LogDevQueue (TraceContext const &context, const Packet &p);
+  void LogDevQueueEnqueue (TraceContext const &context, const Packet &p);
+  void LogDevQueueDequeue (TraceContext const &context, const Packet &p);
+  void LogDevQueueDrop (TraceContext const &context, const Packet &p);
   void LogDevRx (TraceContext const &context, Packet &p);
   std::ofstream m_os;
 };
--- a/src/internet-node/ipv4-loopback-interface.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -21,6 +21,7 @@
  */
 #include "ns3/net-device.h"
 #include "ns3/node.h"
+#include "ns3/eui48-address.h"
 #include "ipv4-loopback-interface.h"
 #include "ipv4-l3-protocol.h"
 
@@ -36,7 +37,7 @@
 Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
 {
   Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
-  ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ()->GetAddress ());
+  ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, Eui48Address ("ff:ff:ff:ff:ff:ff"));
 }
 
 }//namespace ns3
--- a/src/internet-node/udp-socket.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/udp-socket.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -57,6 +57,12 @@
   m_udp = 0;
 }
 
+enum Socket::SocketErrno
+UdpSocket::GetErrno (void) const
+{
+  return m_errno;
+}
+
 Ptr<Node>
 UdpSocket::GetNode (void) const
 {
@@ -118,11 +124,6 @@
   return FinishBind ();
 }
 
-enum Socket::SocketErrno
-UdpSocket::GetErrno (void) const
-{
-  return m_errno;
-}
 int 
 UdpSocket::ShutdownSend (void)
 {
@@ -137,73 +138,42 @@
 }
 
 int
-UdpSocket::DoClose(Callback<void, Ptr<Socket> > closeCompleted)
+UdpSocket::Close(void)
 {
-  // XXX: we should set the close state and check it in all API methods.
-  if (!closeCompleted.IsNull ())
-    {
-      closeCompleted (this);
-    }
+  NotifyCloseCompleted ();
   return 0;
 }
+
 int
-UdpSocket::DoConnect(const Address & address,
-                     Callback<void, Ptr<Socket> > connectionSucceeded,
-                     Callback<void, Ptr<Socket> > connectionFailed,
-                     Callback<void, Ptr<Socket> > halfClose)
+UdpSocket::Connect(const Address & address)
 {
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   m_defaultAddress = transport.GetIpv4 ();
   m_defaultPort = transport.GetPort ();
-  if (!connectionSucceeded.IsNull ())
-    {
-      connectionSucceeded (this);
-    }
+  NotifyConnectionSucceeded ();
   m_connected = true;
   return 0;
 }
-int
-UdpSocket::DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
-                    Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
-                    Callback<void, Ptr<Socket> > closeRequested)
-{
-  // calling accept on a udp socket is a programming error.
-  m_errno = ERROR_OPNOTSUPP;
-  return -1;
-}
 int 
-UdpSocket::DoSend (const uint8_t* buffer,
-                   uint32_t size,
-                   Callback<void, Ptr<Socket>, uint32_t> dataSent)
+UdpSocket::Send (const Packet &p)
 {
   if (!m_connected)
     {
       m_errno = ERROR_NOTCONN;
       return -1;
     }
-  Packet p;
-  if (buffer == 0)
-    {
-      p = Packet (size);
-    }
-  else
-    {
-      p = Packet (buffer, size);
-    }
-  return DoSendPacketTo (p, m_defaultAddress, m_defaultPort, dataSent);
+  return DoSendTo (p, m_defaultAddress, m_defaultPort);
 }
 int
-UdpSocket::DoSendPacketTo (const Packet &p, const Address &address,
-                           Callback<void, Ptr<Socket>, uint32_t> dataSent)
+UdpSocket::DoSendTo (const Packet &p, const Address &address)
 {
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   Ipv4Address ipv4 = transport.GetIpv4 ();
   uint16_t port = transport.GetPort ();
-  return DoSendPacketTo (p, ipv4, port, dataSent);
+  return DoSendTo (p, ipv4, port);
 }
 int
-UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address ipv4, uint16_t port,
-                           Callback<void, Ptr<Socket>, uint32_t> dataSent)
+UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port)
 {
   if (m_endPoint == 0)
     {
@@ -221,46 +191,21 @@
     }
   m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4,
 		   m_endPoint->GetLocalPort (), port);
-  if (!dataSent.IsNull ())
-    {
-      dataSent (this, p.GetSize ());
-    }
+  NotifyDataSent (p.GetSize ());
   return 0;
 }
 int 
-UdpSocket::DoSendTo(const Address &address,
-                    const uint8_t *buffer,
-                    uint32_t size,
-                    Callback<void, Ptr<Socket>, uint32_t> dataSent)
+UdpSocket::SendTo(const Address &address, const Packet &p)
 {
   if (m_connected)
     {
       m_errno = ERROR_ISCONN;
       return -1;
     }
-  Packet p;
-  if (buffer == 0)
-    {
-      p = Packet (size);
-    }
-  else
-    {
-      p = Packet (buffer, size);
-    }
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   Ipv4Address ipv4 = transport.GetIpv4 ();
   uint16_t port = transport.GetPort ();
-  return DoSendPacketTo (p, ipv4, port, dataSent);
-}
-void 
-UdpSocket::DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
-{
-  m_rxCallback = callback;
-}
-void 
-UdpSocket::DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
-{
-  m_dummyRxCallback = callback;
+  return DoSendTo (p, ipv4, port);
 }
 
 void 
@@ -273,14 +218,7 @@
   
   Address address = InetSocketAddress (ipv4, port);
   Packet p = packet;
-  if (!m_dummyRxCallback.IsNull ())
-    {
-      m_dummyRxCallback (this, p.GetSize (), address);
-    }
-  if (!m_rxCallback.IsNull ())
-    {
-      m_rxCallback (this, p.PeekData (), p.GetSize (), address);
-    }
+  NotifyDataReceived (p, address);
 }
 
 }//namespace ns3
--- a/src/internet-node/udp-socket.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/udp-socket.h	Tue Aug 28 12:05:35 2007 +0200
@@ -47,27 +47,14 @@
   virtual Ptr<Node> GetNode (void) const;
   virtual int Bind (void);
   virtual int Bind (const Address &address);
+  virtual int Close (void);
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
+  virtual int Connect(const Address &address);
+  virtual int Send (const Packet &p);
+  virtual int SendTo(const Address &address,const Packet &p);
 
 private:
-  virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted);
-  virtual int DoConnect(const Address & address,
-                        Callback<void, Ptr<Socket> > connectionSucceeded,
-                        Callback<void, Ptr<Socket> > connectionFailed,
-                        Callback<void, Ptr<Socket> > halfClose);
-  virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
-		       Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
-		       Callback<void, Ptr<Socket> > closeRequested);
-  virtual int DoSend (const uint8_t* buffer,
-                    uint32_t size,
-                    Callback<void, Ptr<Socket>, uint32_t> dataSent);
-  virtual int DoSendTo(const Address &address,
-                      const uint8_t *buffer,
-                      uint32_t size,
-                      Callback<void, Ptr<Socket>, uint32_t> dataSent);
-  virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&>);
-  virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>);
 
 private:
   friend class Udp;
@@ -75,10 +62,8 @@
   int FinishBind (void);
   void ForwardUp (const Packet &p, Ipv4Address ipv4, uint16_t port);
   void Destroy (void);
-  int DoSendPacketTo (const Packet &p, const Address &daddr,
-		      Callback<void, Ptr<Socket>, uint32_t> dataSent);
-  int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
-		      Callback<void, Ptr<Socket>, uint32_t> dataSent);
+  int DoSendTo (const Packet &p, const Address &daddr);
+  int DoSendTo (const Packet &p, Ipv4Address daddr, uint16_t dport);
 
   Ipv4EndPoint *m_endPoint;
   Ptr<Node> m_node;
--- a/src/mobility/mobility-model.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/mobility/mobility-model.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -52,9 +52,9 @@
 }
 
 double 
-MobilityModel::GetDistanceFrom (const MobilityModel &other) const
+MobilityModel::GetDistanceFrom (Ptr<const MobilityModel> other) const
 {
-  Position oPosition = other.DoGet ();
+  Position oPosition = other->DoGet ();
   Position position = DoGet ();
   return CalculateDistance (position, oPosition);
 }
--- a/src/mobility/mobility-model.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/mobility/mobility-model.h	Tue Aug 28 12:05:35 2007 +0200
@@ -57,7 +57,7 @@
    * \param position a reference to another mobility model
    * \returns the distance between the two objects. Unit is meters.
    */
-  double GetDistanceFrom (const MobilityModel &position) const;
+  double GetDistanceFrom (Ptr<const MobilityModel> position) const;
 protected:
   /**
    * Must be invoked by subclasses when the course of the
--- a/src/node/address.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/address.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -147,7 +147,7 @@
       return os;
     }
   os.setf (std::ios::hex, std::ios::basefield);
-  std::cout.fill('0');
+  os.fill('0');
   for (uint8_t i=0; i < (address.m_len-1); i++) 
     {
       os << std::setw(2) << (uint32_t)address.m_data[i] << ":";
@@ -155,7 +155,7 @@
   // Final byte not suffixed by ":"
   os << std::setw(2) << (uint32_t)address.m_data[address.m_len-1];
   os.setf (std::ios::dec, std::ios::basefield);
-  std::cout.fill(' ');
+  os.fill(' ');
   return os;
 }
 
--- a/src/node/ethernet-header.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/ethernet-header.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -19,6 +19,8 @@
  * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
  */
 
+#include <iomanip>
+#include <iostream>
 #include "ns3/assert.h"
 #include "ns3/debug.h"
 #include "ns3/header.h"
@@ -118,7 +120,8 @@
     {
       os << " preamble/sfd=" << m_preambleSfd << ",";
     }
-  os << " length/type=" << m_lengthType
+
+  os << " length/type=0x" << std::hex << m_lengthType << std::dec
      << ", source=" << m_source
      << ", destination=" << m_destination;
 }
--- a/src/node/eui48-address.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/eui48-address.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -152,7 +152,7 @@
   address.CopyTo (ad);
 
   os.setf (std::ios::hex, std::ios::basefield);
-  std::cout.fill('0');
+  os.fill('0');
   for (uint8_t i=0; i < 5; i++) 
     {
       os << std::setw(2) << (uint32_t)ad[i] << ":";
@@ -160,7 +160,7 @@
   // Final byte not suffixed by ":"
   os << std::setw(2) << (uint32_t)ad[5];
   os.setf (std::ios::dec, std::ios::basefield);
-  std::cout.fill(' ');
+  os.fill(' ');
   return os;
 }
 
--- a/src/node/eui64-address.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/eui64-address.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -155,7 +155,7 @@
   address.CopyTo (ad);
 
   os.setf (std::ios::hex, std::ios::basefield);
-  std::cout.fill('0');
+  os.fill('0');
   for (uint8_t i=0; i < 7; i++) 
     {
       os << std::setw(2) << (uint32_t)ad[i] << ":";
@@ -163,7 +163,7 @@
   // Final byte not suffixed by ":"
   os << std::setw(2) << (uint32_t)ad[7];
   os.setf (std::ios::dec, std::ios::basefield);
-  std::cout.fill(' ');
+  os.fill(' ');
   return os;
 }
 
--- a/src/node/inet-socket-address.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/inet-socket-address.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -1,3 +1,24 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
 #include "inet-socket-address.h"
 #include "ns3/assert.h"
 
@@ -72,7 +93,7 @@
   uint8_t buf[6];
   address.CopyTo (buf);
   Ipv4Address ipv4 = Ipv4Address::Deserialize (buf);
-  uint16_t port = buf[0] | (buf[1] << 8);
+  uint16_t port = buf[4] | (buf[5] << 8);
   return InetSocketAddress (ipv4, port);
 }
 uint8_t 
--- a/src/node/inet-socket-address.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/inet-socket-address.h	Tue Aug 28 12:05:35 2007 +0200
@@ -1,5 +1,26 @@
-#ifndef IPV4_TRANSPORT_ADDRESS_H
-#define IPV4_TRANSPORT_ADDRESS_H
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef INET_SOCKET_ADDRESS_H
+#define INET_SOCKET_ADDRESS_H
 
 #include "address.h"
 #include "ipv4-address.h"
@@ -93,4 +114,4 @@
 } // namespace ns3
 
 
-#endif /* IPV4_TRANSPORT_ADDRESS_H */
+#endif /* INET_SOCKET_ADDRESS_H */
--- a/src/node/ipv4-address.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/ipv4-address.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -171,8 +171,11 @@
 bool 
 Ipv4Address::IsMulticast (void) const
 {
-  // XXX
-  return false;
+//
+// Multicast addresses are defined as ranging from 224.0.0.0 through 
+// 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
+//
+  return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
 }
 
 uint32_t
--- a/src/node/net-device.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/net-device.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -172,7 +172,7 @@
 
 // Receive packet from above
 bool 
-NetDevice::Send(Packet& p, const Address& dest, uint16_t protocolNumber)
+NetDevice::Send(const Packet& p, const Address& dest, uint16_t protocolNumber)
 {
   if (m_isUp)
     {
@@ -192,7 +192,7 @@
 
 // Receive packets from below
 bool
-NetDevice::ForwardUp(const Packet& p, uint32_t param, const Address &from)
+NetDevice::ForwardUp(const Packet& p, uint16_t param, const Address &from)
 {
   bool retval = false;
 
--- a/src/node/net-device.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/net-device.h	Tue Aug 28 12:05:35 2007 +0200
@@ -150,7 +150,7 @@
    * 
    * \return whether the Send operation succeeded 
    */
-  bool Send(Packet& p, const Address& dest, uint16_t protocolNumber);
+  bool Send(const Packet& p, const Address& dest, uint16_t protocolNumber);
   /**
    * \returns the node base class which contains this network
    *          interface.
@@ -243,7 +243,7 @@
    * forwards it to the higher layers by calling this method
    * which is responsible for passing it up to the Rx callback.
    */
-  bool ForwardUp (const Packet& p, uint32_t param, const Address &address);
+  bool ForwardUp (const Packet& p, uint16_t param, const Address &address);
 
 
   /**
@@ -266,7 +266,7 @@
    * method.  When the link is Up, this method is invoked to ask 
    * subclasses to forward packets. Subclasses MUST override this method.
    */
-  virtual bool SendTo (Packet& p, const Address &dest, uint16_t protocolNumber) = 0;
+  virtual bool SendTo (const Packet& p, const Address &dest, uint16_t protocolNumber) = 0;
   /**
    * \returns true if this NetDevice needs the higher-layers
    *          to perform ARP over it, false otherwise.
--- a/src/node/packet-socket.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/packet-socket.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -52,13 +52,18 @@
   m_device = 0;
 }
 
+enum Socket::SocketErrno
+PacketSocket::GetErrno (void) const
+{
+  return m_errno;
+}
+
 Ptr<Node>
 PacketSocket::GetNode (void) const
 {
   return m_node;
 }
 
-
 int
 PacketSocket::Bind (void)
 {
@@ -111,11 +116,6 @@
   return 0;
 }
 
-enum Socket::SocketErrno
-PacketSocket::GetErrno (void) const
-{
-  return m_errno;
-}
 int
 PacketSocket::ShutdownSend (void)
 {
@@ -139,26 +139,20 @@
   return 0;
 }
 int
-PacketSocket::DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted)
+PacketSocket::Close(void)
 {
   if (m_state == STATE_CLOSED)
     {
       m_errno = ERROR_BADF;
       return -1;
     }
-  if (!closeCompleted.IsNull ())
-    {
-      closeCompleted (this);
-    }
   m_state = STATE_CLOSED;
+  NotifyCloseCompleted ();
   return 0;
 }
 
 int
-PacketSocket::DoConnect(const Address &ad,
-                        ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
-                        ns3::Callback<void, Ptr<Socket> > connectionFailed,
-                        ns3::Callback<void, Ptr<Socket> > halfClose)
+PacketSocket::Connect(const Address &ad)
 {
   PacketSocketAddress address;
   if (m_state == STATE_CLOSED)
@@ -184,33 +178,15 @@
     }
   m_destAddr = ad;
   m_state = STATE_CONNECTED;
-  if (!connectionSucceeded.IsNull ())
-    {
-      connectionSucceeded (this);
-    }
+  NotifyConnectionSucceeded ();
   return 0;
  error:
-  if (!connectionFailed.IsNull ())
-    {
-      connectionFailed (this);
-    }
+  NotifyConnectionFailed ();
   return -1;
 }
 
 int
-PacketSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
-                       ns3::Callback<void, Ptr<Socket>, const Address &> newConnectionCreated,
-                       ns3::Callback<void, Ptr<Socket> > closeRequested)
-{
-  // calling accept on a packet socket is a programming error.
-  m_errno = ERROR_OPNOTSUPP;
-  return -1;
-}
-
-int
-PacketSocket::DoSend (const uint8_t* buffer,
-                      uint32_t size,
-                      ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
+PacketSocket::Send (const Packet &p)
 {
   if (m_state == STATE_OPEN ||
       m_state == STATE_BOUND)
@@ -218,14 +194,11 @@
       m_errno = ERROR_NOTCONN;
       return -1;
     }
-  return DoSendTo (m_destAddr, buffer, size, dataSent);
+  return SendTo (m_destAddr, p);
 }
 
 int
-PacketSocket::DoSendTo(const Address &address,
-                       const uint8_t *buffer,
-                       uint32_t size,
-                       Callback<void, Ptr<Socket>, uint32_t> dataSent)
+PacketSocket::SendTo(const Address &address, const Packet &p)
 {
   PacketSocketAddress ad;
   if (m_state == STATE_CLOSED)
@@ -250,16 +223,6 @@
       return -1;
     }
   ad = PacketSocketAddress::ConvertFrom (address);
-
-  Packet p;
-  if (buffer == 0)
-    {
-      p = Packet (size);
-    }
-  else
-    {
-      p = Packet (buffer, size);
-    }
   
   bool error = false;
   Address dest = ad.GetPhysicalAddress ();
@@ -282,9 +245,9 @@
             }
         }
     }
-  if (!error && !dataSent.IsNull ())
+  if (!error)
     {
-      dataSent (this, p.GetSize ());
+      NotifyDataSent (p.GetSize ());
     }
 
   if (error)
@@ -299,18 +262,6 @@
 }
 
 void 
-PacketSocket::DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address &> callback)
-{
-  m_rxCallback = callback;
-}
-
-void 
-PacketSocket::DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t, const Address &> callback)
-{
-  m_dummyRxCallback = callback;
-}
-
-void 
 PacketSocket::ForwardUp (Ptr<NetDevice> device, const Packet &packet, 
                          uint16_t protocol, const Address &from)
 {
@@ -328,14 +279,7 @@
 
   NS_DEBUG ("PacketSocket::ForwardUp: UID is " << packet.GetUid()
             << " PacketSocket " << this);
-  if (!m_dummyRxCallback.IsNull ())
-    {
-      m_dummyRxCallback (this, p.GetSize (), address);
-    }
-  if (!m_rxCallback.IsNull ())
-    {
-      m_rxCallback (this, p.PeekData (), p.GetSize (), address);
-    }
+  NotifyDataReceived (p, address);
 }
 
 }//namespace ns3
--- a/src/node/packet-socket.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/packet-socket.h	Tue Aug 28 12:05:35 2007 +0200
@@ -78,27 +78,15 @@
   virtual Ptr<Node> GetNode (void) const;
   virtual int Bind (void);
   virtual int Bind (const Address & address);
+  virtual int Close (void);
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
+  virtual int Connect(const Address &address);
+  virtual int Send (const Packet &p);
+  virtual int SendTo(const Address &address,const Packet &p);
+
 
 private:
-  virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted);
-  virtual int DoConnect(const Address & address,
-                        Callback<void, Ptr<Socket> > connectionSucceeded,
-                        Callback<void, Ptr<Socket> > connectionFailed,
-                        Callback<void, Ptr<Socket> > halfClose);
-  virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
-                       Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
-                       Callback<void, Ptr<Socket> > closeRequested);
-  virtual int DoSend (const uint8_t* buffer,
-                      uint32_t size,
-                      Callback<void, Ptr<Socket>, uint32_t> dataSent);
-  virtual int DoSendTo(const Address &address,
-                       const uint8_t *buffer,
-                       uint32_t size,
-                       Callback<void, Ptr<Socket>, uint32_t> dataSent);
-  virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receive);
-  virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>);
 
 private:
   void Init (void);
@@ -114,8 +102,6 @@
     STATE_CLOSED
   };
   Ptr<Node> m_node;
-  Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
-  Callback<void,Ptr<Socket>,uint8_t const*,uint32_t, const Address &> m_rxCallback;
   enum SocketErrno m_errno;
   bool m_shutdownSend;
   bool m_shutdownRecv;
--- a/src/node/socket.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/socket.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -1,79 +1,144 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation
+ *               2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: George F. Riley<riley@ece.gatech.edu>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
 #include "socket.h"
+#include "ns3/packet.h"
 
 namespace ns3 {
 
 Socket::~Socket ()
 {}
 
-int
-Socket::Close(Callback<void, Ptr<Socket> > closeCompleted)
+void 
+Socket::SetCloseCallback (Callback<void,Ptr<Socket> > closeCompleted)
+{
+  m_closeCompleted = closeCompleted;
+}
+void 
+Socket::SetConnectCallback (Callback<void, Ptr<Socket> > connectionSucceeded,
+			    Callback<void, Ptr<Socket> > connectionFailed,
+			    Callback<void, Ptr<Socket> > halfClose)
 {
-  return DoClose (closeCompleted);
+  m_connectionSucceeded = connectionSucceeded;
+  m_connectionFailed = connectionFailed;
+  m_halfClose = halfClose;
+}
+void 
+Socket::SetAcceptCallback (Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
+			   Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
+			   Callback<void, Ptr<Socket> > closeRequested)
+{
+  m_connectionRequest = connectionRequest;
+  m_newConnectionCreated = newConnectionCreated;
+  m_closeRequested = closeRequested;
+}
+void 
+Socket::SetSendCallback (Callback<void, Ptr<Socket>, uint32_t> dataSent)
+{
+  m_dataSent = dataSent;
+}
+void 
+Socket::SetRecvCallback (Callback<void, Ptr<Socket>, const Packet &,const Address&> receivedData)
+{
+  m_receivedData = receivedData;
 }
 
-int
-Socket::Connect(const Address & address,
-               Callback<void, Ptr<Socket> > connectionSucceeded,
-               Callback<void, Ptr<Socket> > connectionFailed,
-               Callback<void, Ptr<Socket> > halfClose)
+void 
+Socket::NotifyCloseCompleted (void)
 {
-  return DoConnect (address, connectionSucceeded, connectionFailed, halfClose);
-}
-int
-Socket::Accept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
-	       Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
-	       Callback<void, Ptr<Socket> > closeRequested)
-{
-  return DoAccept (connectionRequest, newConnectionCreated, closeRequested);
+  if (!m_closeCompleted.IsNull ())
+    {
+      m_closeCompleted (this);
+    }
 }
-int 
-Socket::Send (const uint8_t* buffer,
-	      uint32_t size,
-	      Callback<void, Ptr<Socket>, uint32_t> dataSent)
+void 
+Socket::NotifyConnectionSucceeded (void)
 {
-  return DoSend (buffer, size, dataSent);
+  if (!m_connectionSucceeded.IsNull ())
+    {
+      m_connectionSucceeded (this);
+    }
 }
-int 
-Socket::SendTo(const Address &address,
-	       const uint8_t *buffer,
-	       uint32_t size,
-	       Callback<void, Ptr<Socket>, uint32_t> dataSent)
+void 
+Socket::NotifyConnectionFailed (void)
 {
-  return DoSendTo (address, buffer, size, dataSent);
+  if (!m_connectionFailed.IsNull ())
+    {
+      m_connectionFailed (this);
+    }
 }
 void 
-Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
+Socket::NotifyHalfClose (void)
+{
+  if (!m_halfClose.IsNull ())
+    {
+      m_halfClose (this);
+    }
+}
+bool 
+Socket::NotifyConnectionRequest (const Address &from)
 {
-  DoRecv (callback);
+  if (!m_connectionRequest.IsNull ())
+    {
+      return m_connectionRequest (this, from);
+    }
+  else
+    {
+      // refuse all incomming connections by default.
+      return false;
+    }
 }
 void 
-Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
+Socket::NotifyNewConnectionCreated (Ptr<Socket> socket, const Address &from)
+{
+  if (!m_newConnectionCreated.IsNull ())
+    {
+      m_newConnectionCreated (socket, from);
+    }
+}
+void 
+Socket::NotifyCloseRequested (void)
 {
-  DoRecvDummy (callback);
+  if (!m_closeRequested.IsNull ())
+    {
+      m_closeRequested (this);
+    }
+}
+void 
+Socket::NotifyDataSent (uint32_t size)
+{
+  if (!m_dataSent.IsNull ())
+    {
+      m_dataSent (this, size);
+    }
+}
+void 
+Socket::NotifyDataReceived (const Packet &p, const Address &from)
+{
+  if (!m_receivedData.IsNull ())
+    {
+      m_receivedData (this, p, from);
+    }
 }
 
 
-bool 
-Socket::RefuseAllConnections (Ptr<Socket> socket, const Address& address)
-{
-  return false;
-}
-void 
-Socket::DummyCallbackVoidSocket (Ptr<Socket> socket)
-{}
-void
-Socket::DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t)
-{}
-void 
-Socket::DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &)
-{}
-void 
-Socket::DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t,
-						  const Address &)
-{}
-void 
-Socket::DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &)
-{}
-
 
 }//namespace ns3
--- a/src/node/socket.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/socket.h	Tue Aug 28 12:05:35 2007 +0200
@@ -1,22 +1,24 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation
+ *               2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: George F. Riley<riley@ece.gatech.edu>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
 
 #ifndef __SOCKET_H__
 #define __SOCKET_H__
@@ -30,6 +32,7 @@
 namespace ns3 {
 
 class Node;
+class Packet;
 
 /**
  * \brief Define a Socket API based on the BSD Socket API.
@@ -70,6 +73,55 @@
    */
   virtual Ptr<Node> GetNode (void) const = 0;
 
+  /**
+   * \param closeCompleted Callback invoked when the close operation is
+   *        completed.
+   */
+  void SetCloseCallback (Callback<void,Ptr<Socket> > closeCompleted);
+
+  /**
+   * \param connectionSucceeded this callback is invoked when the connection request
+   *        initiated by the user is successfully completed. The callback is passed
+   *        back a pointer to the same socket object.
+   * \param connectionFailed this callback is invoked when the connection request
+   *        initiated by the user is unsuccessfully completed. The callback is passed
+   *        back a pointer to the same socket object. 
+   * \param halfClose XXX When exactly is this callback invoked ? If it invoked when the
+   *        other side closes the connection ? Or when I call Close ?
+   */
+  void SetConnectCallback (Callback<void, Ptr<Socket> > connectionSucceeded,
+                          Callback<void, Ptr<Socket> > connectionFailed,
+                          Callback<void, Ptr<Socket> > halfClose);
+  /**
+   * \brief Accept connection requests from remote hosts
+   * \param connectionRequest Callback for connection request from peer. 
+   *        This user callback is passed a pointer to this socket, the 
+   *        ip address and the port number of the connection originator. 
+   *        This callback must return true to accept the incoming connection,
+   *        false otherwise. If the connection is accepted, the 
+   *        "newConnectionCreated" callback will be invoked later to give access
+   *        to the user to the socket created to match this new connection. If the
+   *        user does not explicitely specify this callback, all incoming 
+   *        connections will be refused.
+   * \param newConnectionCreated Callback for new connection: when a new
+   *        is accepted, it is created and the corresponding socket is passed
+   *        back to the user through this callback. This user callback is passed
+   *        a pointer to the new socket, and the ip address and port number
+   *        of the connection originator.
+   * \param closeRequested Callback for connection close request from peer.
+   *        XXX: when is this callback invoked ?
+   */
+  void SetAcceptCallback (Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
+                                 Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
+                                 Callback<void, Ptr<Socket> > closeRequested);
+  void SetSendCallback (Callback<void, Ptr<Socket>, uint32_t> dataSent);
+  /**
+   * \brief Receive data
+   * \param receivedData Invoked whenever new data is received.
+   *
+   */
+  void SetRecvCallback (Callback<void, Ptr<Socket>, const Packet &,const Address&> receivedData);
+
   /** 
    * \param address the address to try to allocate
    * \returns 0 on success, -1 on failure.
@@ -85,16 +137,13 @@
    */
   virtual int Bind () = 0;
 
-
   /** 
    * \brief Close a socket.
-   * \param closeCompleted Callback invoked when the close operation is
-   *        completed.
    *
    * After the Close call, the socket is no longer valid, and cannot
    * safely be used for subsequent operations.
    */
-  int Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
+  virtual int Close(void) = 0;
 
   /**
    * \returns zero on success, -1 on failure.
@@ -115,120 +164,46 @@
   /**
    * \brief Initiate a connection to a remote host
    * \param address Address of remote.
-   * \param connectionSucceeded this callback is invoked when the connection request
-   *        initiated by the user is successfully completed. The callback is passed
-   *        back a pointer to the same socket object.
-   * \param connectionFailed this callback is invoked when the connection request
-   *        initiated by the user is unsuccessfully completed. The callback is passed
-   *        back a pointer to the same socket object. 
-   * \param halfClose XXX When exactly is this callback invoked ? If it invoked when the
-   *        other side closes the connection ? Or when I call Close ?
    */
-  int Connect(const Address &address,
-              Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
-              Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
-              Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
+  virtual int Connect(const Address &address) = 0;
     
   /**
-   * \brief Accept connection requests from remote hosts
-   * \param connectionRequest Callback for connection request from peer. 
-   *        This user callback is passed a pointer to this socket, the 
-   *        ip address and the port number of the connection originator. 
-   *        This callback must return true to accept the incoming connection,
-   *        false otherwise. If the connection is accepted, the 
-   *        "newConnectionCreated" callback will be invoked later to give access
-   *        to the user to the socket created to match this new connection. If the
-   *        user does not explicitely specify this callback, all incoming 
-   *        connections will be refused.
-   * \param newConnectionCreated Callback for new connection: when a new
-   *        is accepted, it is created and the corresponding socket is passed
-   *        back to the user through this callback. This user callback is passed
-   *        a pointer to the new socket, and the ip address and port number
-   *        of the connection originator.
-   * \param closeRequested Callback for connection close request from peer.
-   *        XXX: when is this callback invoked ?
-   */
-  int Accept(Callback<bool, Ptr<Socket>, const Address &> connectionRequest = 
-             MakeCallback(&Socket::RefuseAllConnections),
-             Callback<void, Ptr<Socket>, const Address&> newConnectionCreated = 
-             MakeCallback (&Socket::DummyCallbackVoidSocketAddress),
-             Callback<void, Ptr<Socket> > closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
-
-  /**
    * \brief Send data (or dummy data) to the remote host
-   * \param buffer Data to send (nil if dummy data).
-   * \param size Number of bytes to send.
-   * \param dataSent Data sent callback.
+   * \param p packet to send
    * \returns -1 in case of error or the number of bytes copied in the 
    *          internal buffer and accepted for transmission.
    */
-  int Send (const uint8_t* buffer,
-            uint32_t size,
-            Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
+  virtual int Send (const Packet &p) = 0;
   
   /**
    * \brief Send data to a specified peer.
    * \param address IP Address of remote host
-   * \param buffer Data to send (nil if dummy data).
-   * \param size Number of bytes to send.
-   * \param dataSent Data sent callback.
+   * \param p packet to send
    * \returns -1 in case of error or the number of bytes copied in the 
    *          internal buffer and accepted for transmission.
    */
-  int SendTo(const Address &address,
-             const uint8_t *buffer,
-             uint32_t size,
-             Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
-  
-  /**
-   * \brief Receive data
-   * \param receivedData Invoked whenever new data is received.
-   *
-   * If you wish to transport only dummy packets, this method is not a very
-   * efficient way to receive these dummy packets: it will trigger a memory
-   * allocation to hold the dummy memory into a buffer which can be passed
-   * to the user. Instead, consider using the RecvDummy method.
-   */
-  void Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receivedData = 
-            MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Address));
-  
-  /**
-   * \brief Receive data
-   * \param receivedData Invoked whenever new data is received.
-   *
-   * This method is included because it is vastly more efficient than the 
-   * Recv method when you use dummy payload.
-   */
-  void RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> receivedData =
-                 MakeCallback (&Socket::DummyCallbackVoidSocketUi32Address));
+  virtual int SendTo(const Address &address,const Packet &p) = 0;
 
-private:
-  virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
-  virtual int DoConnect(const Address & address,
-                        Callback<void, Ptr<Socket> > connectionSucceeded,
-                        Callback<void, Ptr<Socket> > connectionFailed,
-                        Callback<void, Ptr<Socket> > halfClose) = 0;
-  virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
-                       Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
-                       Callback<void, Ptr<Socket> > closeRequested) = 0;
-  virtual int DoSend (const uint8_t* buffer,
-                      uint32_t size,
-                      Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
-  virtual int DoSendTo(const Address &address,
-                       const uint8_t *buffer,
-                       uint32_t size,
-                       Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
-  virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receive) = 0;
-  virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>) = 0;
+protected:
+  void NotifyCloseCompleted (void);
+  void NotifyConnectionSucceeded (void);
+  void NotifyConnectionFailed (void);
+  void NotifyHalfClose (void);
+  bool NotifyConnectionRequest (const Address &from);
+  void NotifyNewConnectionCreated (Ptr<Socket> socket, const Address &from);
+  void NotifyCloseRequested (void);
+  void NotifyDataSent (uint32_t size);
+  void NotifyDataReceived (const Packet &p, const Address &from);
 
-
-  static bool RefuseAllConnections (Ptr<Socket> socket, const Address& address);
-  static void DummyCallbackVoidSocket (Ptr<Socket> socket);
-  static void DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t);
-  static void DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &);
-  static void DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t, 
-                                                                const Address &);
-  static void DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &);
+  Callback<void,Ptr<Socket> >    m_closeCompleted;
+  Callback<void, Ptr<Socket> >   m_connectionSucceeded;
+  Callback<void, Ptr<Socket> >   m_connectionFailed;
+  Callback<void, Ptr<Socket> >   m_halfClose;
+  Callback<void, Ptr<Socket> >   m_closeRequested;
+  Callback<bool, Ptr<Socket>, const Address &>   m_connectionRequest;
+  Callback<void, Ptr<Socket>, const Address&>    m_newConnectionCreated;
+  Callback<void, Ptr<Socket>, uint32_t>          m_dataSent;
+  Callback<void, Ptr<Socket>, const Packet &,const Address&> m_receivedData;
 };
 
 } //namespace ns3
--- a/src/routing/global-routing/global-route-manager-impl.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/routing/global-routing/global-route-manager-impl.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -48,8 +48,7 @@
 {
 }
 
-SPFVertex::SPFVertex (GlobalRouterLSA* lsa) : 
-  m_vertexType (VertexRouter), 
+SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) : 
   m_vertexId (lsa->GetLinkStateId ()),
   m_lsa (lsa),
   m_distanceFromRoot (SPF_INFINITY), 
@@ -58,6 +57,16 @@
   m_parent (0),
   m_children ()
 {
+  if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA) 
+    {
+      NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexRouter");
+      m_vertexType = SPFVertex::VertexRouter;
+    }
+  else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA) 
+    { 
+      NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexNetwork");
+      m_vertexType = SPFVertex::VertexNetwork;
+    }
 }
 
 SPFVertex::~SPFVertex ()
@@ -99,12 +108,12 @@
 }
 
   void 
-SPFVertex::SetLSA (GlobalRouterLSA* lsa)
+SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
 {
   m_lsa = lsa;
 }
 
-  GlobalRouterLSA* 
+  GlobalRoutingLSA* 
 SPFVertex::GetLSA (void) const
 {
   return m_lsa;
@@ -210,7 +219,7 @@
   for (i= m_database.begin (); i!= m_database.end (); i++)
     {
       NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ():free LSA");
-      GlobalRouterLSA* temp = i->second;
+      GlobalRoutingLSA* temp = i->second;
       delete temp;
     }
   NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ():  clear map");
@@ -225,19 +234,19 @@
   LSDBMap_t::iterator i;
   for (i= m_database.begin (); i!= m_database.end (); i++)
     {
-      GlobalRouterLSA* temp = i->second;
-      temp->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED);
+      GlobalRoutingLSA* temp = i->second;
+      temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
     }
 }
 
   void
-GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRouterLSA* lsa)
+GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
 {
   NS_DEBUG ("GlobalRouteManagerLSDB::Insert ()");
   m_database.insert (LSDBPair_t (addr, lsa));
 }
 
-  GlobalRouterLSA*
+  GlobalRoutingLSA*
 GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
 {
   NS_DEBUG ("GlobalRouteManagerLSDB::GetLSA ()");
@@ -255,6 +264,31 @@
   return 0;
 }
 
+  GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
+{
+  NS_DEBUG ("GlobalRouteManagerLSDB::GetLSAByLinkData ()");
+//
+// Look up an LSA by its address.
+//
+  LSDBMap_t::const_iterator i;
+  for (i= m_database.begin (); i!= m_database.end (); i++)
+    {
+      GlobalRoutingLSA* temp = i->second;
+// Iterate among temp's Link Records
+      for (uint32_t j = 0; j < temp->GetNLinkRecords (); j++)
+        {
+          GlobalRoutingLinkRecord *lr = temp->GetLinkRecord (j);
+          if ( lr->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork &&
+               lr->GetLinkData () == addr)
+            {
+              return temp;
+            }
+        }
+    }
+  return 0;
+}
+
 // ---------------------------------------------------------------------------
 //
 // GlobalRouteManagerImpl Implementation
@@ -359,13 +393,12 @@
 
       for (uint32_t j = 0; j < numLSAs; ++j)
         {
-          GlobalRouterLSA* lsa = new GlobalRouterLSA ();
+          GlobalRoutingLSA* lsa = new GlobalRoutingLSA ();
 //
 // This is the call to actually fetch a Link State Advertisement from the 
 // router.
 //
           rtr->GetLSA (j, *lsa);
-          NS_DEBUG ("LSA " << j);
           NS_DEBUG (*lsa);
 //
 // Write the newly discovered link state advertisement to the database.
@@ -453,52 +486,86 @@
 GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
 {
   SPFVertex* w = 0;
-  GlobalRouterLSA* w_lsa = 0;
+  GlobalRoutingLSA* w_lsa = 0;
+  GlobalRoutingLinkRecord *l = 0;
   uint32_t distance = 0;
+  uint32_t numRecordsInVertex = 0;
 
   NS_DEBUG ("GlobalRouteManagerImpl::SPFNext ()");
-//
-// Always true for now, since all our LSAs are RouterLSAs.
-//
-  if (v->GetVertexType () == SPFVertex::VertexRouter) 
+
+// V points to a Router-LSA or Network-LSA
+// Loop over the links in router LSA or attached routers in Network LSA
+  if (v->GetVertexType () == SPFVertex::VertexRouter)
     {
-      if (true)
+      numRecordsInVertex = v->GetLSA ()->GetNLinkRecords (); 
+    }
+  if (v->GetVertexType () == SPFVertex::VertexNetwork)
+    {
+      numRecordsInVertex = v->GetLSA ()->GetNAttachedRouters (); 
+    }
+
+  for (uint32_t i = 0; i < numRecordsInVertex; i++)
+    {
+// Get w_lsa:  In case of V is Router-LSA
+      if (v->GetVertexType () == SPFVertex::VertexRouter) 
         {
           NS_DEBUG ("SPFNext: Examining " << v->GetVertexId () << "'s " <<
             v->GetLSA ()->GetNLinkRecords () << " link records");
 //
-// Walk the list of link records in the link state advertisement associated 
-// with the "current" router (represented by vertex <v>).
-//
-          for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
-            {
-//
 // (a) If this is a link to a stub network, examine the next link in V's LSA.
 // Links to stub networks will be considered in the second stage of the
 // shortest path calculation.
 //
-              GlobalRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
-              if (l->GetLinkType () == GlobalRouterLinkRecord::StubNetwork)
-                {
-                  NS_DEBUG ("SPFNext: Found a Stub record to " << 
-                    l->GetLinkId ());
-                  continue;
-                }
+          l = v->GetLSA ()->GetLinkRecord (i);
+          if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
+            {
+              NS_DEBUG ("SPFNext: Found a Stub record to " << 
+                l->GetLinkId ());
+              continue;
+            }
 //
 // (b) Otherwise, W is a transit vertex (router or transit network).  Look up
 // the vertex W's LSA (router-LSA or network-LSA) in Area A's link state
 // database. 
 //
-              if (l->GetLinkType () == GlobalRouterLinkRecord::PointToPoint)
-                {
+          if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+            {
 //
 // Lookup the link state advertisement of the new link -- we call it <w> in
 // the link state database.
 //
-                  w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
-                  NS_ASSERT (w_lsa);
-                  NS_DEBUG ("SPFNext:  Found a P2P record from " << 
-                    v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+              w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+              NS_ASSERT (w_lsa);
+              NS_DEBUG ("SPFNext:  Found a P2P record from " << 
+                v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+            }
+          else if (l->GetLinkType () == 
+            GlobalRoutingLinkRecord::TransitNetwork)
+            {
+              w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+              NS_ASSERT (w_lsa);
+              NS_DEBUG ("SPFNext:  Found a Transit record from " << 
+                v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+            }
+          else 
+            {
+              NS_ASSERT_MSG (0, "illegal Link Type");
+            }
+        }
+// Get w_lsa:  In case of V is Network-LSA
+      if (v->GetVertexType () == SPFVertex::VertexNetwork) 
+        {
+          w_lsa = m_lsdb->GetLSAByLinkData 
+            (v->GetLSA ()->GetAttachedRouter (i)); 
+          if (!w_lsa)
+            {
+              continue;
+            }
+          NS_DEBUG ("SPFNext:  Found a Network LSA from " << 
+            v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+        }
+
+// Note:  w_lsa at this point may be either RouterLSA or NetworkLSA
 //
 // (c) If vertex W is already on the shortest-path tree, examine the next
 // link in the LSA.
@@ -506,57 +573,56 @@
 // If the link is to a router that is already in the shortest path first tree
 // then we have it covered -- ignore it.
 //
-                  if (w_lsa->GetStatus () == 
-                      GlobalRouterLSA::LSA_SPF_IN_SPFTREE) 
-                    {
-                      NS_DEBUG ("SPFNext: Skipping->  LSA "<< 
-                        w_lsa->GetLinkStateId () << " already in SPF tree");
-                      continue;
-                    }
-//
-// The link is to a router we haven't dealt with yet.
+      if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE) 
+        {
+          NS_DEBUG ("SPFNext: Skipping->  LSA "<< 
+            w_lsa->GetLinkStateId () << " already in SPF tree");
+          continue;
+        }
 //
 // (d) Calculate the link state cost D of the resulting path from the root to 
 // vertex W.  D is equal to the sum of the link state cost of the (already 
 // calculated) shortest path to vertex V and the advertised cost of the link
 // between vertices V and W.  
 //
-                  distance = v->GetDistanceFromRoot () + l->GetMetric ();
-
-                  NS_DEBUG ("SPFNext: Considering w_lsa " << 
-                    w_lsa->GetLinkStateId ());
+      if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
+        {
+          distance = v->GetDistanceFromRoot () + l->GetMetric ();
+        }
+      else
+        {
+          distance = v->GetDistanceFromRoot ();
+        }
 
-                  if (w_lsa->GetStatus () == 
-                      GlobalRouterLSA::LSA_SPF_NOT_EXPLORED)
-                    {
-//
-// If we haven't yet considered the link represented by <w> we have to create 
-// a new SPFVertex to represent it.
-//
-                        w = new SPFVertex (w_lsa);
-//
+      NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->GetLinkStateId ());
+
+// Is there already vertex w in candidate list?
+      if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
+        {
+
+// prepare vertex w
+          w = new SPFVertex (w_lsa);
+// Calculate nexthop to w
 // We need to figure out how to actually get to the new router represented
 // by <w>.  This will (among other things) find the next hop address to send
 // packets destined for this network to, and also find the outbound interface
 // used to forward the packets.
 //
-                      if (SPFNexthopCalculation (v, w, l, distance))
-                        {
-                          w_lsa->SetStatus (
-                            GlobalRouterLSA::LSA_SPF_CANDIDATE);
+          if (SPFNexthopCalculation (v, w, l, distance))
+            {
+              w_lsa->SetStatus (GlobalRoutingLSA::LSA_SPF_CANDIDATE);
 //
 // Push this new vertex onto the priority queue (ordered by distance from the
 // root node).
 //
-                          candidate.Push (w);
-                          NS_DEBUG ("SPFNext:  Pushing " << 
-                            w->GetVertexId () << ", parent vertexId: " << 
-                                    v->GetVertexId ());
-                        }
-                    }
-                } else if (w_lsa->GetStatus () == 
-                           GlobalRouterLSA::LSA_SPF_CANDIDATE)
-                    {
+              candidate.Push (w);
+              NS_DEBUG ("SPFNext:  Pushing " << 
+                w->GetVertexId () << ", parent vertexId: " << 
+                v->GetVertexId ());
+            }
+        }
+      else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
+        {
 //
 // We have already considered the link represented by <w>.  What wse have to
 // do now is to decide if this new router represents a route with a shorter
@@ -564,23 +630,23 @@
 //
 // So, locate the vertex in the candidate queue and take a look at the 
 // distance.
-                      w = candidate.Find (w_lsa->GetLinkStateId ());
-                      if (w->GetDistanceFromRoot () < distance)
-                        {
+          w = candidate.Find (w_lsa->GetLinkStateId ());
+          if (w->GetDistanceFromRoot () < distance)
+            {
 //
 // This is not a shorter path, so don't do anything.
 //
-                          continue;
-                        }
-                      else if (w->GetDistanceFromRoot () == distance)
-                        {
+              continue;
+            }
+          else if (w->GetDistanceFromRoot () == distance)
+            {
 //
 // This path is one with an equal cost.  Do nothing for now -- we're not doing
 // equal-cost multipath cases yet.
 //
-                        }
-                      else
-                        {
+            }
+          else
+            {
 // 
 // this path represents a new, lower-cost path to <w> (the vertex we found in
 // the current link record of the link state advertisement of the current root
@@ -589,27 +655,26 @@
 // N.B. the nexthop_calculation is conditional, if it finds a valid nexthop
 // it will call spf_add_parents, which will flush the old parents
 //
-                          if (SPFNexthopCalculation (v, w, l, distance))
-                            {
+              if (SPFNexthopCalculation (v, w, l, distance))
+                {
 //
 // If we've changed the cost to get to the vertex represented by <w>, we 
 // must reorder the priority queue keyed to that cost.
 //
-                              candidate.Reorder ();
-                            }
-                        }    
-                    }  // point-to-point
-            } // for loop
-        } 
-    }
+                  candidate.Reorder ();
+                }
+            } // new lower cost path found   
+        } // end W is already on the candidate list
+    } // end loop over the links in V's LSA
 }
 
 //
 // This method is derived from quagga ospf_next_hop_calculation() 16.1.1.  
 //
-// Calculate the next hop IP address and the outgoing interface required to
-// get packets from the root through <v> (parent) to vertex <w> (destination),
-// over a given distance.
+// Calculate nexthop from root through V (parent) to vertex W (destination)
+// with given distance from root->W.
+//
+// As appropriate, set w's parent, distance, and nexthop information
 //
 // For now, this is greatly simplified from the quagga code
 //                  
@@ -617,10 +682,19 @@
 GlobalRouteManagerImpl::SPFNexthopCalculation (
   SPFVertex* v, 
   SPFVertex* w,
-  GlobalRouterLinkRecord* l,
+  GlobalRoutingLinkRecord* l,
   uint32_t distance)
 {
   NS_DEBUG ("GlobalRouteManagerImpl::SPFNexthopCalculation ()");
+
+// If w is a NetworkVertex, l should be null
+/*
+  if (w->GetVertexType () == SPFVertex::VertexNetwork && l)
+    {
+        NS_ASSERT_MSG(0, "Error:  SPFNexthopCalculation parameter problem");
+    }
+*/
+
 //
 // The vertex m_spfroot is a distinguished vertex representing the node at
 // the root of the calculations.  That is, it is the node for which we are
@@ -669,7 +743,8 @@
 // return the link record describing the link from <w> to <v>.  Think of it as
 // SPFGetLink.
 //
-          GlobalRouterLinkRecord *linkRemote = 0;
+          NS_ASSERT(l);
+          GlobalRoutingLinkRecord *linkRemote = 0;
           linkRemote = SPFGetNextLink (w, v, linkRemote);
 // 
 // At this point, <l> is the Global Router Link Record describing the point-
@@ -695,6 +770,56 @@
             v->GetVertexId () << " to " << w->GetVertexId () << 
             " goes through next hop " << w->GetNextHop () <<
             " via outgoing interface " << w->GetOutgoingInterfaceId ());
+        }  // end W is a router vertes
+      else 
+        {
+          NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork);
+// W is a directly connected network; no next hop is required
+          GlobalRoutingLSA* w_lsa = w->GetLSA ();
+          NS_ASSERT (w_lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA);
+// Find outgoing interface ID for this network
+          w->SetOutgoingInterfaceId (
+            FindOutgoingInterfaceId (w_lsa->GetLinkStateId (), 
+            w_lsa->GetNetworkLSANetworkMask () ));
+          w->SetDistanceFromRoot (distance);
+          w->SetParent (v);
+          NS_DEBUG ("SPFNexthopCalculation: Next hop from " << 
+            v->GetVertexId () << " to network " << w->GetVertexId () << 
+            " via outgoing interface " << w->GetOutgoingInterfaceId ());
+          return 1;
+        }
+    } // end v is the root
+  else if (v->GetVertexType () == SPFVertex::VertexNetwork) 
+    {
+// See if any of v's parents are the root
+      if (v->GetParent () == m_spfroot)
+        {
+// 16.1.1 para 5. ...the parent vertex is a network that
+// directly connects the calculating router to the destination
+// router.  The list of next hops is then determined by
+// examining the destination's router-LSA...
+          NS_ASSERT (w->GetVertexType () == SPFVertex::VertexRouter);
+          GlobalRoutingLinkRecord *linkRemote = 0;
+          while ((linkRemote = SPFGetNextLink (w, v, linkRemote)))
+            {
+/* ...For each link in the router-LSA that points back to the
+ * parent network, the link's Link Data field provides the IP
+ * address of a next hop router.  The outgoing interface to
+ * use can then be derived from the next hop IP address (or 
+ * it can be inherited from the parent network).
+ */
+                w->SetNextHop(linkRemote->GetLinkData ());
+                w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ());
+                NS_DEBUG ("SPFNexthopCalculation: Next hop from " << 
+                  v->GetVertexId () << " to " << w->GetVertexId () << 
+                  " goes through next hop " << w->GetNextHop () <<
+                  " via outgoing interface " << w->GetOutgoingInterfaceId ());
+            }
+        }
+      else 
+        {
+          w->SetNextHop (v->GetNextHop ());
+          w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ());
         }
     }
   else 
@@ -736,19 +861,17 @@
 // to <w>.  If prev_link is not NULL, we return a Global Router Link Record
 // representing a possible *second* link from <v> to <w>.
 //
-// BUGBUG FIXME:  This seems to be a bug.  Shouldn't this function look for
-// any link records after pre_link and not just after the first?
-//
-  GlobalRouterLinkRecord* 
+  GlobalRoutingLinkRecord* 
 GlobalRouteManagerImpl::SPFGetNextLink (
   SPFVertex* v,
   SPFVertex* w,
-  GlobalRouterLinkRecord* prev_link) 
+  GlobalRoutingLinkRecord* prev_link) 
 {
   NS_DEBUG ("GlobalRouteManagerImpl::SPFGetNextLink ()");
 
   bool skip = true;
-  GlobalRouterLinkRecord* l;
+  bool found_prev_link = false;
+  GlobalRoutingLinkRecord* l;
 //
 // If prev_link is 0, we are really looking for the first link, not the next 
 // link.
@@ -756,6 +879,7 @@
   if (prev_link == 0)
     {
       skip = false;
+      found_prev_link = true;
     }
 //  
 // Iterate through the Global Router Link Records advertised by the vertex
@@ -765,10 +889,6 @@
   for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
     {
       l = v->GetLSA ()->GetLinkRecord (i);
-      if (l->GetLinkType () != GlobalRouterLinkRecord::PointToPoint)
-        {
-          continue;
-        }
 //
 // The link ID of a link record representing a point-to-point link is set to
 // the router ID of the neighboring router -- the router to which the link
@@ -777,8 +897,16 @@
 // We're just checking to see if the link <l> is actually the link from <v> to
 // <w>.
 //
-      if (l->GetLinkId () == w->GetVertexId ()) {
-        NS_DEBUG ("SPFGetNextLink: Found matching link l:  linkId = " <<
+      if (l->GetLinkId () == w->GetVertexId ()) 
+        {
+          if (!found_prev_link)
+            {
+              NS_DEBUG ("SPFGetNextLink: Skipping links before prev_link found");
+              found_prev_link = true;
+              continue;
+            }
+        
+          NS_DEBUG ("SPFGetNextLink: Found matching link l:  linkId = " <<
           l->GetLinkId () << " linkData = " << l->GetLinkData ());
 //
 // If skip is false, don't (not too surprisingly) skip the link found -- it's 
@@ -849,7 +977,7 @@
 //
   m_spfroot= v;
   v->SetDistanceFromRoot (0);
-  v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE);
+  v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
 
   for (;;)
     {
@@ -894,7 +1022,7 @@
 // Update the status field of the vertex to indicate that it is in the SPF
 // tree.
 //
-      v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE);
+      v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
 //
 // The current vertex has a parent pointer.  By calling this rather oddly 
 // named method (blame quagga) we add the current vertex to the list of 
@@ -932,7 +1060,18 @@
 // through its point-to-point links, adding a *host* route to the local IP
 // address (at the <v> side) for each of those links.
 //
-      SPFIntraAddRouter (v);
+      if (v->GetVertexType () == SPFVertex::VertexRouter)
+        {
+          SPFIntraAddRouter (v);
+        }
+      else if (v->GetVertexType () == SPFVertex::VertexNetwork)
+        {
+          SPFIntraAddTransit (v);
+        }
+      else
+        {
+          NS_ASSERT_MSG(0, "illegal SPFVertex type");
+        }
 //
 // RFC2328 16.1. (5). 
 //
@@ -1026,6 +1165,80 @@
 }
 
 //
+// XXX This should probably be a method on Ipv4
+//
+// Return the interface index corresponding to a given IP address
+//
+  uint32_t
+GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
+{
+//
+// We have an IP address <a> and a vertex ID of the root of the SPF tree.  
+// The question is what interface index does this address correspond to.
+// The answer is a little complicated since we have to find a pointer to
+// the node corresponding to the vertex ID, find the Ipv4 interface on that
+// node in order to iterate the interfaces and find the one corresponding to
+// the address in question.
+//
+  Ipv4Address routerId = m_spfroot->GetVertexId ();
+//
+// Walk the list of nodes in the system looking for the one corresponding to
+// the node at the root of the SPF tree.  This is the node for which we are
+// building the routing table.
+//
+  std::vector<Ptr<Node> >::iterator i = NodeList::Begin (); 
+  for (; i != NodeList::End (); i++)
+    {
+      Ptr<Node> node = *i;
+
+      Ptr<GlobalRouter> rtr = 
+        node->QueryInterface<GlobalRouter> (GlobalRouter::iid);
+//
+// If the node doesn't have a GlobalRouter interface it can't be the one
+// we're interested in.
+//
+      if (rtr == 0)
+        {
+          continue;
+        }
+
+      if (rtr->GetRouterId () == routerId)
+        {
+//
+// This is the node we're building the routing table for.  We're going to need
+// the Ipv4 interface to look for the ipv4 interface index.  Since this node
+// is participating in routing IP version 4 packets, it certainly must have 
+// an Ipv4 interface.
+//
+          Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
+          NS_ASSERT_MSG (ipv4, 
+            "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
+            "QI for <Ipv4> interface failed");
+//
+// Look through the interfaces on this node for one that has the IP address
+// we're looking for.  If we find one, return the corresponding interface
+// index.
+//
+          for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
+            {
+              if (ipv4->GetAddress (i).CombineMask(amask) == 
+                  a.CombineMask(amask) )
+                {
+                  NS_DEBUG (
+                    "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
+                    "Interface match for " << a);
+                  return i;
+                }
+            }
+        }
+    }
+//
+// Couldn't find it.
+//
+  return 0;
+}
+
+//
 // This method is derived from quagga ospf_intra_add_router ()
 //
 // This is where we are actually going to add the host routes to the routing
@@ -1109,7 +1322,7 @@
 // Link Records corresponding to links off of that vertex / node.  We're going
 // to be interested in the records corresponding to point-to-point links.
 //
-          GlobalRouterLSA *lsa = v->GetLSA ();
+          GlobalRoutingLSA *lsa = v->GetLSA ();
           NS_ASSERT_MSG (lsa, 
             "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
             "Expected valid LSA in SPFVertex* v");
@@ -1128,8 +1341,8 @@
 //
 // We are only concerned about point-to-point links
 //
-              GlobalRouterLinkRecord *lr = lsa->GetLinkRecord (j);
-              if (lr->GetLinkType () != GlobalRouterLinkRecord::PointToPoint)
+              GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j);
+              if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
                 {
                   continue;
                 }
@@ -1162,6 +1375,91 @@
         }
     }
 }
+  void
+GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
+{
+  NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit ()");
+
+  NS_ASSERT_MSG (m_spfroot, 
+    "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
+//
+// The root of the Shortest Path First tree is the router to which we are 
+// going to write the actual routing table entries.  The vertex corresponding
+// to this router has a vertex ID which is the router ID of that node.  We're
+// going to use this ID to discover which node it is that we're actually going
+// to update.
+//
+  Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+  NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+    "Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex.  This is the one we're going to write
+// the routing information to.
+//
+  std::vector<Ptr<Node> >::iterator i = NodeList::Begin (); 
+  for (; i != NodeList::End (); i++)
+    {
+      Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to QI for that interface.  If there's no GlobalRouter interface, the node
+// in question cannot be the router we want, so we continue.
+// 
+      Ptr<GlobalRouter> rtr = 
+        node->QueryInterface<GlobalRouter> (GlobalRouter::iid);
+
+      if (rtr == 0)
+        {
+          NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+            "No GlobalRouter interface on node " << node->GetId ());
+          continue;
+        }
+//
+// If the router ID of the current node is equal to the router ID of the 
+// root of the SPF tree, then this node is the one for which we need to 
+// write the routing tables.
+//
+      NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+        "Considering router " << rtr->GetRouterId ());
+
+      if (rtr->GetRouterId () == routerId)
+        {
+          NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+            "setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface.  We need to QI
+// for that interface.  If the node is acting as an IP version 4 router, it
+// should absolutely have an Ipv4 interface.
+//
+          Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
+          NS_ASSERT_MSG (ipv4, 
+            "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+            "QI for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to.  The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node.  We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+          GlobalRoutingLSA *lsa = v->GetLSA ();
+          NS_ASSERT_MSG (lsa, 
+            "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+            "Expected valid LSA in SPFVertex* v");
+          Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
+          Ipv4Address tempip = lsa->GetLinkStateId ();
+          tempip = tempip.CombineMask (tempmask);
+          ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (),
+            v->GetOutgoingInterfaceId ());
+          NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddNetwork (): "
+            " Node " << node->GetId () <<
+            " add network route to " << tempip <<
+            " using next hop " << v->GetNextHop () <<
+            " via interface " << v->GetOutgoingInterfaceId ());
+        }
+    } 
+}
 
 // Derived from quagga ospf_vertex_add_parents ()
 //
@@ -1254,81 +1552,84 @@
   //  link2:  10.1.3.1/30, 10.1.3.2/30
   //
   // Router 0
-  GlobalRouterLinkRecord* lr0 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::PointToPoint, 
+  GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint, 
     "0.0.0.2",  // router ID 0.0.0.2
     "10.1.1.1", // local ID
     1);         // metric
 
-  GlobalRouterLinkRecord* lr1 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::StubNetwork,
+  GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
     "10.1.1.1",
     "255.255.255.252",
     1);
 
-  GlobalRouterLSA* lsa0 = new GlobalRouterLSA ();
+  GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA ();
+  lsa0->SetLSType (GlobalRoutingLSA::RouterLSA);
   lsa0->SetLinkStateId ("0.0.0.0");
   lsa0->SetAdvertisingRouter ("0.0.0.0");
   lsa0->AddLinkRecord (lr0);
   lsa0->AddLinkRecord (lr1);
 
   // Router 1
-  GlobalRouterLinkRecord* lr2 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::PointToPoint,
+  GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
     "0.0.0.2",
     "10.1.2.1",
     1);
 
-  GlobalRouterLinkRecord* lr3 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::StubNetwork,
+  GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
     "10.1.2.1",
     "255.255.255.252",
     1);
 
-  GlobalRouterLSA* lsa1 = new GlobalRouterLSA ();
+  GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA ();
+  lsa1->SetLSType (GlobalRoutingLSA::RouterLSA);
   lsa1->SetLinkStateId ("0.0.0.1");
   lsa1->SetAdvertisingRouter ("0.0.0.1");
   lsa1->AddLinkRecord (lr2);
   lsa1->AddLinkRecord (lr3);
   
   // Router 2 
-  GlobalRouterLinkRecord* lr4 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::PointToPoint,
+  GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
     "0.0.0.0",
     "10.1.1.2",
     1);
 
-  GlobalRouterLinkRecord* lr5 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::StubNetwork,
+  GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
     "10.1.1.2",
     "255.255.255.252",
     1);
 
-  GlobalRouterLinkRecord* lr6 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::PointToPoint,
+  GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
     "0.0.0.1",
     "10.1.2.2",
     1);
 
-  GlobalRouterLinkRecord* lr7 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::StubNetwork,
+  GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
     "10.1.2.2",
     "255.255.255.252",
     1);
 
-  GlobalRouterLinkRecord* lr8 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::PointToPoint,
+  GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
     "0.0.0.3",
     "10.1.3.2",
     1);
 
-  GlobalRouterLinkRecord* lr9 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::StubNetwork,
+  GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
     "10.1.3.2",
     "255.255.255.252",
     1);
 
-  GlobalRouterLSA* lsa2 = new GlobalRouterLSA ();
+  GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA ();
+  lsa2->SetLSType (GlobalRoutingLSA::RouterLSA);
   lsa2->SetLinkStateId ("0.0.0.2");
   lsa2->SetAdvertisingRouter ("0.0.0.2");
   lsa2->AddLinkRecord (lr4);
@@ -1339,19 +1640,20 @@
   lsa2->AddLinkRecord (lr9);
 
   // Router 3
-  GlobalRouterLinkRecord* lr10 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::PointToPoint,
+  GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::PointToPoint,
     "0.0.0.2",
     "10.1.2.1",
     1);
 
-  GlobalRouterLinkRecord* lr11 = new GlobalRouterLinkRecord (
-    GlobalRouterLinkRecord::StubNetwork,
+  GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord (
+    GlobalRoutingLinkRecord::StubNetwork,
     "10.1.2.1",
     "255.255.255.252",
     1);
 
-  GlobalRouterLSA* lsa3 = new GlobalRouterLSA ();
+  GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA ();
+  lsa3->SetLSType (GlobalRoutingLSA::RouterLSA);
   lsa3->SetLinkStateId ("0.0.0.3");
   lsa3->SetAdvertisingRouter ("0.0.0.3");
   lsa3->AddLinkRecord (lr10);
--- a/src/routing/global-routing/global-route-manager-impl.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/routing/global-routing/global-route-manager-impl.h	Tue Aug 28 12:05:35 2007 +0200
@@ -102,10 +102,10 @@
  *
  * @see SPFVertex::SPFVertex ()
  * @see VertexType
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
  * @param lsa The Link State Advertisement used for finding initial values.
  */
-  SPFVertex(GlobalRouterLSA* lsa);
+  SPFVertex(GlobalRoutingLSA* lsa);
 
 /**
  * @brief Destroy an SPFVertex (Shortest Path First Vertex).
@@ -181,12 +181,12 @@
  * @internal
  *
  * @see GlobalRouter
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
  * @see GlobalRouter::DiscoverLSAs ()
- * @returns A pointer to the GlobalRouterLSA found by the router represented
+ * @returns A pointer to the GlobalRoutingLSA found by the router represented
  * by this SPFVertex object.
  */
-  GlobalRouterLSA* GetLSA (void) const;
+  GlobalRoutingLSA* GetLSA (void) const;
 
 /**
  * @brief Set the Global Router Link State Advertisement returned by the 
@@ -196,13 +196,13 @@
  *
  * @see SPFVertex::GetLSA ()
  * @see GlobalRouter
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
  * @see GlobalRouter::DiscoverLSAs ()
  * @warning Ownership of the LSA is transferred to the "this" SPFVertex.  You
  * must not delete the LSA after calling this method.
- * @param lsa A pointer to the GlobalRouterLSA.
+ * @param lsa A pointer to the GlobalRoutingLSA.
  */
-  void SetLSA (GlobalRouterLSA* lsa);
+  void SetLSA (GlobalRoutingLSA* lsa);
 
 /**
  * @brief Get the distance from the root vertex to "this" SPFVertex object.
@@ -283,8 +283,8 @@
  * SPFVertex."
  *
  * @see GlobalRouter
- * @see GlobalRouterLSA
- * @see GlobalRouterLinkRecord
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
  * @returns The interface index to use when forwarding packets to the host
  * or network represented by "this" SPFVertex.
  */
@@ -325,8 +325,8 @@
  * by "this" SPFVertex.
  *
  * @see GlobalRouter
- * @see GlobalRouterLSA
- * @see GlobalRouterLinkRecord
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
  * @param id The interface index to use when forwarding packets to the host or
  * network represented by "this" SPFVertex.
  */
@@ -368,8 +368,8 @@
  * by 'this' SPFVertex."
  *
  * @see GlobalRouter
- * @see GlobalRouterLSA
- * @see GlobalRouterLinkRecord
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
  * @returns The IP address to use when forwarding packets to the host
  * or network represented by "this" SPFVertex.
  */
@@ -411,8 +411,8 @@
  * host represented by 'this' SPFVertex."
  *
  * @see GlobalRouter
- * @see GlobalRouterLSA
- * @see GlobalRouterLinkRecord
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
  * @param nextHop The IP address to use when forwarding packets to the host
  * or network represented by "this" SPFVertex.
  */
@@ -543,7 +543,7 @@
 private:
   VertexType m_vertexType;
   Ipv4Address m_vertexId;
-  GlobalRouterLSA* m_lsa;
+  GlobalRoutingLSA* m_lsa;
   uint32_t m_distanceFromRoot;
   uint32_t m_rootOif;
   Ipv4Address m_nextHop;
@@ -604,33 +604,47 @@
  * State Database.
  * @internal
  *
- * The IPV4 address and the GlobalRouterLSA given as parameters are converted
+ * The IPV4 address and the GlobalRoutingLSA given as parameters are converted
  * to an STL pair and are inserted into the database map.
  *
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
  * @see Ipv4Address
  * @param addr The IP address associated with the LSA.  Typically the Router 
  * ID.
  * @param lsa A pointer to the Link State Advertisement for the router.
  */
-  void Insert(Ipv4Address addr, GlobalRouterLSA* lsa);
+  void Insert(Ipv4Address addr, GlobalRoutingLSA* lsa);
 
 /**
  * @brief Look up the Link State Advertisement associated with the given
- * IP Address.
+ * link state ID (address).
  * @internal
  *
  * The database map is searched for the given IPV4 address and corresponding
- * GlobalRouterLSA is returned.
+ * GlobalRoutingLSA is returned.
  *
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
  * @see Ipv4Address
  * @param addr The IP address associated with the LSA.  Typically the Router 
  * ID.
  * @returns A pointer to the Link State Advertisement for the router specified
  * by the IP address addr.
  */
-  GlobalRouterLSA* GetLSA (Ipv4Address addr) const;
+  GlobalRoutingLSA* GetLSA (Ipv4Address addr) const;
+/**
+ * @brief Look up the Link State Advertisement associated with the given
+ * link state ID (address).  This is a variation of the GetLSA call
+ * to allow the LSA to be found by matching addr with the LinkData field
+ * of the TransitNetwork link record.
+ * @internal
+ *
+ * @see GetLSA
+ * @param addr The IP address associated with the LSA.  Typically the Router 
+ * @returns A pointer to the Link State Advertisement for the router specified
+ * by the IP address addr.
+ * ID.
+ */
+  GlobalRoutingLSA* GetLSAByLinkData (Ipv4Address addr) const;
 
 /**
  * @brief Set all LSA flags to an initialized state, for SPF computation
@@ -641,14 +655,14 @@
  * prior to each SPF calculation to reset the state of the SPFVertex structures
  * that will reference the LSAs during the calculation.
  *
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
  * @see SPFVertex
  */
   void Initialize ();
 
 private:
-  typedef std::map<Ipv4Address, GlobalRouterLSA*> LSDBMap_t;
-  typedef std::pair<Ipv4Address, GlobalRouterLSA*> LSDBPair_t;
+  typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
+  typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
 
   LSDBMap_t m_database;
 /**
@@ -734,12 +748,14 @@
   void SPFCalculate (Ipv4Address root);
   void SPFNext (SPFVertex*, CandidateQueue&);
   int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, 
-    GlobalRouterLinkRecord* l, uint32_t distance);
+    GlobalRoutingLinkRecord* l, uint32_t distance);
   void SPFVertexAddParent (SPFVertex* v);
-  GlobalRouterLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w, 
-    GlobalRouterLinkRecord* prev_link);
+  GlobalRoutingLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w, 
+    GlobalRoutingLinkRecord* prev_link);
   void SPFIntraAddRouter (SPFVertex* v);
+  void SPFIntraAddTransit (SPFVertex* v);
   uint32_t FindOutgoingInterfaceId (Ipv4Address a);
+  uint32_t FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask);
 };
 
 } // namespace ns3
--- a/src/routing/global-routing/global-router-interface.cc	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/routing/global-routing/global-router-interface.cc	Tue Aug 28 12:05:35 2007 +0200
@@ -28,21 +28,21 @@
 
 // ---------------------------------------------------------------------------
 //
-// GlobalRouterLinkRecord Implementation
+// GlobalRoutingLinkRecord Implementation
 //
 // ---------------------------------------------------------------------------
 
-GlobalRouterLinkRecord::GlobalRouterLinkRecord ()
+GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()
 :
   m_linkId ("0.0.0.0"),
   m_linkData ("0.0.0.0"),
   m_linkType (Unknown),
   m_metric (0)
 {
-  NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()");
 }
 
-GlobalRouterLinkRecord::GlobalRouterLinkRecord (
+GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
   LinkType    linkType, 
   Ipv4Address linkId, 
   Ipv4Address linkData, 
@@ -53,116 +53,126 @@
   m_linkType (linkType),
   m_metric (metric)
 {
-  NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord (" <<
+  NS_DEBUG("GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (" <<
     linkType << ", " << linkId << ", " << linkData << ", " << metric << ")");
 }
 
-GlobalRouterLinkRecord::~GlobalRouterLinkRecord ()
+GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()
 {
-  NS_DEBUG("GlobalRouterLinkRecord::~GlobalRouterLinkRecord ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()");
 }
 
   Ipv4Address
-GlobalRouterLinkRecord::GetLinkId (void) const
+GlobalRoutingLinkRecord::GetLinkId (void) const
 {
-  NS_DEBUG("GlobalRouterLinkRecord::GetLinkId ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::GetLinkId ()");
   return m_linkId;
 }
 
   void
-GlobalRouterLinkRecord::SetLinkId (Ipv4Address addr)
+GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr)
 {
-  NS_DEBUG("GlobalRouterLinkRecord::SetLinkId ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::SetLinkId ()");
   m_linkId = addr;
 }
 
   Ipv4Address
-GlobalRouterLinkRecord::GetLinkData (void) const
+GlobalRoutingLinkRecord::GetLinkData (void) const
 {
-  NS_DEBUG("GlobalRouterLinkRecord::GetLinkData ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::GetLinkData ()");
   return m_linkData;
 }
 
   void
-GlobalRouterLinkRecord::SetLinkData (Ipv4Address addr)
+GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr)
 {
-  NS_DEBUG("GlobalRouterLinkRecord::SetLinkData ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::SetLinkData ()");
   m_linkData = addr;
 }
 
-  GlobalRouterLinkRecord::LinkType
-GlobalRouterLinkRecord::GetLinkType (void) const
+  GlobalRoutingLinkRecord::LinkType
+GlobalRoutingLinkRecord::GetLinkType (void) const
 {
-  NS_DEBUG("GlobalRouterLinkRecord::GetLinkType ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::GetLinkType ()");
   return m_linkType;
 }
 
   void
-GlobalRouterLinkRecord::SetLinkType (
-  GlobalRouterLinkRecord::LinkType linkType)
+GlobalRoutingLinkRecord::SetLinkType (
+  GlobalRoutingLinkRecord::LinkType linkType)
 {
-  NS_DEBUG("GlobalRouterLinkRecord::SetLinkType ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::SetLinkType ()");
   m_linkType = linkType;
 }
 
   uint32_t
-GlobalRouterLinkRecord::GetMetric (void) const
+GlobalRoutingLinkRecord::GetMetric (void) const
 {
-  NS_DEBUG("GlobalRouterLinkRecord::GetMetric ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::GetMetric ()");
   return m_metric;
 }
 
   void
-GlobalRouterLinkRecord::SetMetric (uint32_t metric)
+GlobalRoutingLinkRecord::SetMetric (uint32_t metric)
 {
-  NS_DEBUG("GlobalRouterLinkRecord::SetMetric ()");
+  NS_DEBUG("GlobalRoutingLinkRecord::SetMetric ()");
   m_metric = metric;
 }
 
 // ---------------------------------------------------------------------------
 //
-// GlobalRouterLSA Implementation
+// GlobalRoutingLSA Implementation
 //
 // ---------------------------------------------------------------------------
 
-GlobalRouterLSA::GlobalRouterLSA()
+GlobalRoutingLSA::GlobalRoutingLSA()
   : 
+  m_lsType (GlobalRoutingLSA::Unknown),
   m_linkStateId("0.0.0.0"),
   m_advertisingRtr("0.0.0.0"),
   m_linkRecords(),
-  m_status(GlobalRouterLSA::LSA_SPF_NOT_EXPLORED)
+  m_networkLSANetworkMask("0.0.0.0"),
+  m_attachedRouters(),
+  m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
 {
-  NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA ()");
+  NS_DEBUG("GlobalRoutingLSA::GlobalRoutingLSA ()");
 }
 
-GlobalRouterLSA::GlobalRouterLSA (
-  GlobalRouterLSA::SPFStatus status,
+GlobalRoutingLSA::GlobalRoutingLSA (
+  GlobalRoutingLSA::SPFStatus status,
   Ipv4Address linkStateId, 
   Ipv4Address advertisingRtr)
 :
+  m_lsType (GlobalRoutingLSA::Unknown),
   m_linkStateId(linkStateId),
   m_advertisingRtr(advertisingRtr),
   m_linkRecords(),
+  m_networkLSANetworkMask("0.0.0.0"),
+  m_attachedRouters(),
   m_status(status)
 {
-  NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA (" << status << ", " <<
+  NS_DEBUG("GlobalRoutingLSA::GlobalRoutingLSA (" << status << ", " <<
     linkStateId << ", " << advertisingRtr << ")");
 }
 
-GlobalRouterLSA::GlobalRouterLSA (GlobalRouterLSA& lsa)
-  : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr),
+GlobalRoutingLSA::GlobalRoutingLSA (GlobalRoutingLSA& lsa)
+  : m_lsType(lsa.m_lsType), m_linkStateId(lsa.m_linkStateId), 
+    m_advertisingRtr(lsa.m_advertisingRtr), 
+    m_networkLSANetworkMask(lsa.m_networkLSANetworkMask), 
     m_status(lsa.m_status)
 {
   NS_ASSERT_MSG(IsEmpty(), 
-    "GlobalRouterLSA::GlobalRouterLSA (): Non-empty LSA in constructor");
+    "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
   CopyLinkRecords (lsa);
 }
 
-  GlobalRouterLSA&
-GlobalRouterLSA::operator= (const GlobalRouterLSA& lsa)
+  GlobalRoutingLSA&
+GlobalRoutingLSA::operator= (const GlobalRoutingLSA& lsa)
 {
+  m_lsType = lsa.m_lsType;
   m_linkStateId = lsa.m_linkStateId;
   m_advertisingRtr = lsa.m_advertisingRtr;
+  m_networkLSANetworkMask = lsa.m_networkLSANetworkMask, 
   m_status = lsa.m_status;
 
   ClearLinkRecords ();
@@ -171,14 +181,14 @@
 }
 
   void
-GlobalRouterLSA::CopyLinkRecords (const GlobalRouterLSA& lsa)
+GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
 {
   for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
        i != lsa.m_linkRecords.end (); 
        i++)
     {
-      GlobalRouterLinkRecord *pSrc = *i;
-      GlobalRouterLinkRecord *pDst = new GlobalRouterLinkRecord;
+      GlobalRoutingLinkRecord *pSrc = *i;
+      GlobalRoutingLinkRecord *pDst = new GlobalRoutingLinkRecord;
 
       pDst->SetLinkType (pSrc->GetLinkType ());
       pDst->SetLinkId (pSrc->GetLinkId ());
@@ -187,48 +197,50 @@
       m_linkRecords.push_back(pDst);
       pDst = 0;
     }
+
+   m_attachedRouters = lsa.m_attachedRouters;
 }
 
-GlobalRouterLSA::~GlobalRouterLSA()
+GlobalRoutingLSA::~GlobalRoutingLSA()
 {
-  NS_DEBUG("GlobalRouterLSA::~GlobalRouterLSA ()");
+  NS_DEBUG("GlobalRoutingLSA::~GlobalRoutingLSA ()");
   ClearLinkRecords ();
 }
 
   void
-GlobalRouterLSA::ClearLinkRecords(void)
+GlobalRoutingLSA::ClearLinkRecords(void)
 {
   for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
         i != m_linkRecords.end (); 
         i++)
     {
-      NS_DEBUG("GlobalRouterLSA::ClearLinkRecords ():  free link record");
+      NS_DEBUG("GlobalRoutingLSA::ClearLinkRecords ():  free link record");
 
-      GlobalRouterLinkRecord *p = *i;
+      GlobalRoutingLinkRecord *p = *i;
       delete p;
       p = 0;
 
       *i = 0;
     }
-  NS_DEBUG("GlobalRouterLSA::ClearLinkRecords():  clear list");
+  NS_DEBUG("GlobalRoutingLSA::ClearLinkRecords():  clear list");
   m_linkRecords.clear();
 }
 
   uint32_t
-GlobalRouterLSA::AddLinkRecord (GlobalRouterLinkRecord* lr)
+GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr)
 {
   m_linkRecords.push_back (lr);
   return m_linkRecords.size ();
 }
 
   uint32_t
-GlobalRouterLSA::GetNLinkRecords (void) const
+GlobalRoutingLSA::GetNLinkRecords (void) const
 {
   return m_linkRecords.size ();
 }
 
-  GlobalRouterLinkRecord *
-GlobalRouterLSA::GetLinkRecord (uint32_t n) const
+  GlobalRoutingLinkRecord *
+GlobalRoutingLSA::GetLinkRecord (uint32_t n) const
 {
   uint32_t j = 0;
   for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
@@ -240,70 +252,146 @@
           return *i;
         }
     }
-  NS_ASSERT_MSG(false, "GlobalRouterLSA::GetLinkRecord (): invalid index");
+  NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetLinkRecord (): invalid index");
   return 0;
 }
 
   bool
-GlobalRouterLSA::IsEmpty (void) const
+GlobalRoutingLSA::IsEmpty (void) const
 {
   return m_linkRecords.size () == 0;
 }
 
+  GlobalRoutingLSA::LSType
+GlobalRoutingLSA::GetLSType (void) const
+{
+  return m_lsType;
+}
+
+  void 
+GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ) 
+{
+  m_lsType = typ;
+}
+
   Ipv4Address
-GlobalRouterLSA::GetLinkStateId (void) const
+GlobalRoutingLSA::GetLinkStateId (void) const
 {
   return m_linkStateId;
 }
 
   void
-GlobalRouterLSA::SetLinkStateId (Ipv4Address addr)
+GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr)
 {
   m_linkStateId = addr;
 }
 
   Ipv4Address
-GlobalRouterLSA::GetAdvertisingRouter (void) const
+GlobalRoutingLSA::GetAdvertisingRouter (void) const
 {
   return m_advertisingRtr;
 }
 
   void
-GlobalRouterLSA::SetAdvertisingRouter (Ipv4Address addr)
+GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr)
 {
   m_advertisingRtr = addr;
 }
 
-  GlobalRouterLSA::SPFStatus
-GlobalRouterLSA::GetStatus (void) const
+  void 
+GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask)
+{
+  m_networkLSANetworkMask = mask;
+}
+
+  Ipv4Mask 
+GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const
+{
+  return m_networkLSANetworkMask;
+}
+
+  GlobalRoutingLSA::SPFStatus
+GlobalRoutingLSA::GetStatus (void) const
 {
   return m_status;
 }
 
+  uint32_t 
+GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr)
+{
+  m_attachedRouters.push_back (addr);
+  return m_attachedRouters.size ();
+}
+
+  uint32_t 
+GlobalRoutingLSA::GetNAttachedRouters (void) const
+{
+  return m_attachedRouters.size (); 
+}
+
+  Ipv4Address 
+GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const
+{
+  uint32_t j = 0;
+  for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
+        i != m_attachedRouters.end (); 
+        i++, j++)
+    {
+      if (j == n) 
+        {
+          return *i;
+        }
+    }
+  NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index");
+  return Ipv4Address("0.0.0.0");
+}
+
   void
-GlobalRouterLSA::SetStatus (GlobalRouterLSA::SPFStatus status)
+GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status)
 {
   m_status = status;
 }
 
   void 
-GlobalRouterLSA::Print (std::ostream &os) const
+GlobalRoutingLSA::Print (std::ostream &os) const
 {
-  os << "m_linkStateId = " << m_linkStateId << std::endl <<
+  os << "m_lsType = " << m_lsType << std::endl <<
+        "m_linkStateId = " << m_linkStateId << std::endl <<
         "m_advertisingRtr = " << m_advertisingRtr << std::endl;
 
-  for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
-        i != m_linkRecords.end (); 
-        i++)
+  if (m_lsType == GlobalRoutingLSA::RouterLSA) 
+    {
+      for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
+            i != m_linkRecords.end (); 
+            i++)
+        {
+          GlobalRoutingLinkRecord *p = *i;
+          os << "----------" << std::endl;
+          os << "m_linkId = " << p->GetLinkId () << std::endl;
+          os << "m_linkData = " << p->GetLinkData () << std::endl;
+        }
+    }
+  else if (m_lsType == GlobalRoutingLSA::NetworkLSA) 
     {
-      GlobalRouterLinkRecord *p = *i;
       os << "----------" << std::endl;
-      os << "m_linkId = " << p->GetLinkId () << std::endl;
-      os << "m_linkData = " << p->GetLinkData () << std::endl;
+      os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask 
+         << std::endl;
+      for ( ListOfAttachedRouters_t::const_iterator i = 
+            m_attachedRouters.begin ();
+            i != m_attachedRouters.end (); 
+            i++)
+        {
+          Ipv4Address p = *i;
+          os << "attachedRouter = " << p << std::endl;
+        }
+    }
+  else 
+    {
+      NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
     }
 }
 
-std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa)
+std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
 {
   lsa.Print (os);
   return os;
@@ -350,7 +438,7 @@
     {
       NS_DEBUG("GlobalRouter::ClearLSAs ():  free LSA");
 
-      GlobalRouterLSA *p = *i;
+      GlobalRoutingLSA *p = *i;
       delete p;
       p = 0;
 
@@ -373,11 +461,16 @@
   uint32_t 
 GlobalRouter::DiscoverLSAs (void)
 {
-  NS_DEBUG("GlobalRouter::DiscoverLSAs ()");
+  NS_DEBUG("GlobalRouter::DiscoverLSAs () for node " << m_node->GetId () );
   NS_ASSERT_MSG(m_node, 
     "GlobalRouter::DiscoverLSAs (): <Node> interface not set");
 
   ClearLSAs ();
+
+// While building the router-LSA, keep a list of those NetDevices for
+// which I am the designated router and need to later build a NetworkLSA
+  std::list<Ptr<NetDevice> > listOfDRInterfaces;
+
 //
 // We're aggregated to a node.  We need to ask the node for a pointer to its
 // Ipv4 interface.  This is where the information regarding the attached 
@@ -387,118 +480,252 @@
   NS_ASSERT_MSG(ipv4Local, 
     "GlobalRouter::DiscoverLSAs (): QI for <Ipv4> interface failed");
 //
-// We are, for now at least, only going to report RouterLSAs in this method.
-// What this means is that there is going to be one advertisement with some
-// number of link records.  This means that GetNumLSAs will actually always
-// return exactly one.
+// Each node originates a Router-LSA
 //
-  GlobalRouterLSA *pLSA = new GlobalRouterLSA;
+  GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+  pLSA->SetLSType (GlobalRoutingLSA::RouterLSA);
   pLSA->SetLinkStateId (m_routerId);
   pLSA->SetAdvertisingRouter (m_routerId);
-  pLSA->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED);
+  pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
 //
 // We need to ask the node for the number of net devices attached. This isn't
 // necessarily equal to the number of links to adjacent nodes (other routers)
 // as the number of devices may include those for stub networks (e.g., 
-// ethernets, etc.).  So we have to walk through the list of net devices and
-// pay attention to those that are directly connected to another router through
-// a point-to-point channel.
+// ethernets, etc.).  
 //
   uint32_t numDevices = m_node->GetNDevices();
   NS_DEBUG("GlobalRouter::DiscoverLSAs (): numDevices = " << numDevices);
-//
-// Loop through the devices looking for those connected to a point-to-point
-// channel.
-//
   for (uint32_t i = 0; i < numDevices; ++i)
     {
       Ptr<NetDevice> ndLocal = m_node->GetDevice(i);
 
-      if (!ndLocal->IsPointToPoint ())
+      if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
         {
-          NS_DEBUG("GlobalRouter::DiscoverLSAs (): non-point-to-point device");
-          continue;
+          NS_DEBUG("GlobalRouter::DiscoverLSAs (): broadcast link");
+          GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+//
+// We need to determine whether we are on a transit or stub network
+// If we find at least one more router on this channel, we are a transit
+//
+//
+// Now, we have to find the Ipv4 interface whose netdevice is the one we 
+// just found.  This is still the IP on the local side of the channel.  There 
+// is a function to do this used down in the guts of the stack, but it's not 
+// exported so we had to whip up an equivalent.
+//
+          uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
+          Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+          Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+          NS_DEBUG("Working with local address " << addrLocal);
+//
+// Now, we're going to walk over to the remote net device on the other end of 
+// the point-to-point channel we now know we have.  This is where our adjacent 
+// router (to use OSPF lingo) is running.  
+//
+          Ptr<Channel> ch = ndLocal->GetChannel();
+          uint32_t nDevices = ch->GetNDevices();
+          if (nDevices == 1)
+            {
+              // This is a stub broadcast interface
+              NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA stub broadcast link");
+              // XXX in future, need to consider if >1 includes other routers
+              plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+              // Link ID is IP network number of attached network
+              plr->SetLinkId (addrLocal.CombineMask(maskLocal));
+              // Link Data is network mask; convert to Ipv4Address
+              Ipv4Address maskLocalAddr;
+              maskLocalAddr.Set(maskLocal.GetHostOrder ());
+              plr->SetLinkData (maskLocalAddr);
+              // Cost is interface's configured output cost (NOTYET)
+              plr->SetMetric (1);
+              pLSA->AddLinkRecord(plr);
+              plr = 0;
+              continue;
+            }
+          else
+            {
+              NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA Broadcast link");
+              // multiple routers on a broadcast interface
+              // lowest IP address is designated router
+              plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
+              // Link ID is IP interface address of designated router
+              Ipv4Address desigRtr = 
+                FindDesignatedRouterForLink (m_node, ndLocal);
+              if (desigRtr == addrLocal) 
+                {
+                  listOfDRInterfaces.push_back (ndLocal);
+                  NS_DEBUG("GlobalRouter::DiscoverLSAs (): " << 
+                    m_node->GetId () << " is a DR");
+                }
+              plr->SetLinkId (desigRtr);
+              // Link Data is router's own IP address
+              plr->SetLinkData (addrLocal);
+              // Cost is interface's configured output cost (NOTYET)
+              plr->SetMetric (1);
+              pLSA->AddLinkRecord (plr);
+              plr = 0;
+              continue;
+            }
         }
-
-      NS_DEBUG("GlobalRouter::DiscoverLSAs (): Point-to-point device");
+      else if (ndLocal->IsPointToPoint () )
+        {
+          NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA Point-to-point device");
 //
 // Now, we have to find the Ipv4 interface whose netdevice is the one we 
 // just found.  This is still the IP on the local side of the channel.  There 
 // is a function to do this used down in the guts of the stack, but it's not 
 // exported so we had to whip up an equivalent.
 //
-      uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
+          uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
 //
 // Now that we have the Ipv4 interface index, we can get the address and mask
 // we need.
 //
-      Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
-      Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
-      NS_DEBUG("Working with local address " << addrLocal);
+          Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+          Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+          NS_DEBUG("Working with local address " << addrLocal);
 //
 // Now, we're going to walk over to the remote net device on the other end of 
 // the point-to-point channel we now know we have.  This is where our adjacent 
 // router (to use OSPF lingo) is running.  
 //
-      Ptr<Channel> ch = ndLocal->GetChannel();
-      Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
+          Ptr<Channel> ch = ndLocal->GetChannel();
+          Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
 //
 // The adjacent net device is aggregated to a node.  We need to ask that net 
 // device for its node, then ask that node for its Ipv4 interface.
 //
-      Ptr<Node> nodeRemote = ndRemote->GetNode();
-      Ptr<Ipv4> ipv4Remote = nodeRemote->QueryInterface<Ipv4> (Ipv4::iid);
-      NS_ASSERT_MSG(ipv4Remote, 
-        "GlobalRouter::DiscoverLSAs (): QI for remote <Ipv4> failed");
+          Ptr<Node> nodeRemote = ndRemote->GetNode();
+          Ptr<Ipv4> ipv4Remote = nodeRemote->QueryInterface<Ipv4> (Ipv4::iid);
+          NS_ASSERT_MSG(ipv4Remote, 
+            "GlobalRouter::DiscoverLSAs (): QI for remote <Ipv4> failed");
 //
 // Per the OSPF spec, we're going to need the remote router ID, so we might as
 // well get it now.
 //
-      Ptr<GlobalRouter> srRemote = 
-        nodeRemote->QueryInterface<GlobalRouter> (GlobalRouter::iid);
-      NS_ASSERT_MSG(srRemote, 
-        "GlobalRouter::DiscoverLSAs (): QI for remote <GlobalRouter> failed");
-      Ipv4Address rtrIdRemote = srRemote->GetRouterId();
-      NS_DEBUG("Working with remote router " << rtrIdRemote);
+          Ptr<GlobalRouter> srRemote = 
+            nodeRemote->QueryInterface<GlobalRouter> (GlobalRouter::iid);
+          NS_ASSERT_MSG(srRemote, 
+            "GlobalRouter::DiscoverLSAs():QI for remote <GlobalRouter> failed");
+          Ipv4Address rtrIdRemote = srRemote->GetRouterId();
+          NS_DEBUG("Working with remote router " << rtrIdRemote);
 //
 // Now, just like we did above, we need to get the IP interface index for the 
 // net device on the other end of the point-to-point channel.
 //
-      uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote);
+          uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote);
 //
 // Now that we have the Ipv4 interface, we can get the (remote) address and
 // mask we need.
 //
-      Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote);
-      Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote);
-      NS_DEBUG("Working with remote address " << addrRemote);
+          Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote);
+          Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote);
+          NS_DEBUG("Working with remote address " << addrRemote);
 //
 // Now we can fill out the link records for this link.  There are always two
 // link records; the first is a point-to-point record describing the link and
 // the second is a stub network record with the network number.
 //
-      GlobalRouterLinkRecord *plr = new GlobalRouterLinkRecord;
-      plr->SetLinkType (GlobalRouterLinkRecord::PointToPoint);
-      plr->SetLinkId (rtrIdRemote);
-      plr->SetLinkData (addrLocal);
-      pLSA->AddLinkRecord(plr);
-      plr = 0;
+          GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+          plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
+          plr->SetLinkId (rtrIdRemote);
+          plr->SetLinkData (addrLocal);
+          pLSA->AddLinkRecord (plr);
+          plr = 0;
 
-      plr = new GlobalRouterLinkRecord;
-      plr->SetLinkType (GlobalRouterLinkRecord::StubNetwork);
-      plr->SetLinkId (addrRemote);
-      plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder()));  // Frown
-      pLSA->AddLinkRecord(plr);
-      plr = 0;
+          plr = new GlobalRoutingLinkRecord;
+          plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+          plr->SetLinkId (addrRemote);
+          plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder()));  // Frown
+          pLSA->AddLinkRecord (plr);
+          plr = 0;
+        }
+      else
+        {
+          NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type");
+        }
+
     }
 //
 // The LSA goes on a list of LSAs in case we want to begin exporting other
 // kinds of advertisements (than Router LSAs).
   m_LSAs.push_back (pLSA);
   NS_DEBUG(*pLSA);
+
+
+// Now, determine whether we need to build a NetworkLSA
+  if (listOfDRInterfaces.size () > 0)
+    {
+      for (std::list<Ptr<NetDevice> >::iterator i = listOfDRInterfaces.begin ();
+        i != listOfDRInterfaces.end (); i++)
+        {
+// Build one NetworkLSA for each interface that is a DR
+          Ptr<NetDevice> ndLocal = *i;
+          uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
+          Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+          Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+
+          GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+          pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA);
+          pLSA->SetLinkStateId (addrLocal);
+          pLSA->SetAdvertisingRouter (m_routerId);
+          pLSA->SetNetworkLSANetworkMask (maskLocal);
+          pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+// Build list of AttachedRouters
+          Ptr<Channel> ch = ndLocal->GetChannel();
+          uint32_t nDevices = ch->GetNDevices();
+          NS_ASSERT (nDevices);
+          for (uint32_t i = 0; i < nDevices; i++)
+            {
+              Ptr<NetDevice> tempNd = ch->GetDevice (i);
+              NS_ASSERT (tempNd);
+              Ptr<Node> tempNode = tempNd->GetNode ();
+              uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd);
+              Ptr<Ipv4> tempIpv4 = tempNode->QueryInterface<Ipv4> (Ipv4::iid);
+              NS_ASSERT (tempIpv4);
+              Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
+              pLSA->AddAttachedRouter (tempAddr);
+            }
+          m_LSAs.push_back (pLSA);
+          NS_DEBUG(*pLSA);
+        }
+    }
+
   return m_LSAs.size ();
 }
 
+  Ipv4Address
+GlobalRouter::FindDesignatedRouterForLink (Ptr<Node> node, 
+  Ptr<NetDevice> ndLocal) const
+{
+  uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal);
+  Ptr<Ipv4> ipv4Local = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+  NS_ASSERT (ipv4Local);
+  Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+  Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+
+  Ptr<Channel> ch = ndLocal->GetChannel();
+  uint32_t nDevices = ch->GetNDevices();
+  NS_ASSERT (nDevices);
+  Ipv4Address lowest = addrLocal;
+  // iterate all NetDevices and return the lowest numbered IP address 
+  for (uint32_t i = 0; i < nDevices; i++)
+    {
+      Ptr<NetDevice> tempNd = ch->GetDevice (i);
+      NS_ASSERT (tempNd);
+      Ptr<Node> tempNode = tempNd->GetNode ();
+      uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd);
+      Ptr<Ipv4> tempIpv4 = tempNode->QueryInterface<Ipv4> (Ipv4::iid);
+      NS_ASSERT (tempIpv4);
+      Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
+      if (tempAddr < addrLocal)
+        {
+          addrLocal = tempAddr;
+        }
+    }
+  return addrLocal;
+}
+
   uint32_t 
 GlobalRouter::GetNumLSAs (void) const
 {
@@ -510,7 +737,7 @@
 // Get the nth link state advertisement from this router.
 //
   bool
-GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const
+GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
 {
   NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA");
 //
@@ -525,7 +752,7 @@
     {
       if (j == n)
         {
-          GlobalRouterLSA *p = *i;
+          GlobalRoutingLSA *p = *i;
           lsa = *p;
           return true;
         }
--- a/src/routing/global-routing/global-router-interface.h	Tue Aug 28 11:22:01 2007 +0200
+++ b/src/routing/global-routing/global-router-interface.h	Tue Aug 28 12:05:35 2007 +0200
@@ -31,16 +31,16 @@
 /**
  * @brief A single link record for a link state advertisement.
  *
- * The GlobalRouterLinkRecord is modeled after the OSPF link record field of
+ * The GlobalRoutingLinkRecord is modeled after the OSPF link record field of
  * a Link State Advertisement.  Right now we will only see two types of link
  * records corresponding to a stub network and a point-to-point link (channel).
  */
-class GlobalRouterLinkRecord
+class GlobalRoutingLinkRecord
 {
 public:
 /**
  * @enum LinkType
- * @brief Enumeration of the possible types of Global Router Link Records.
+ * @brief Enumeration of the possible types of Global Routing Link Records.
  *
  * These values are defined in the OSPF spec.  We currently only use 
  * PointToPoint and StubNetwork types.
@@ -54,16 +54,16 @@
   };
 
 /**
- * @brief Construct an empty ("uninitialized") Global Router Link Record.
+ * @brief Construct an empty ("uninitialized") Global Routing Link Record.
  *
  * The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0";
  * The Link Type is set to Unknown;
  * The metric is set to 0.
  */
-  GlobalRouterLinkRecord ();
+  GlobalRoutingLinkRecord ();
 
 /**
- * Construct an initialized Global Router Link Record.
+ * Construct an initialized Global Routing Link Record.
  *
  * @param linkType The type of link record to construct.
  * @param linkId The link ID for the record.
@@ -73,21 +73,21 @@
  * @see SetLinkId
  * @see SetLinkData
  */
-  GlobalRouterLinkRecord (
+  GlobalRoutingLinkRecord (
     LinkType    linkType, 
     Ipv4Address linkId, 
     Ipv4Address linkData, 
     uint32_t    metric);
 
 /**
- * @brief Destroy a Global Router Link Record.
+ * @brief Destroy a Global Routing Link Record.
  *
  * Currently does nothing.  Here as a placeholder only.
  */
-  ~GlobalRouterLinkRecord ();
+  ~GlobalRoutingLinkRecord ();
 
 /**
- * Get the Link ID field of the Global Router Link Record.
+ * Get the Link ID field of the Global Routing Link Record.
  *
  * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID
  * of the neighboring router.
@@ -100,7 +100,7 @@
   Ipv4Address GetLinkId(void) const;
 
 /**
- * @brief Set the Link ID field of the Global Router Link Record.
+ * @brief Set the Link ID field of the Global Routing Link Record.
  *
  * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID
  * of the neighboring router.
@@ -113,7 +113,7 @@
   void SetLinkId(Ipv4Address addr);
 
 /**
- * @brief Get the Link Data field of the Global Router Link Record.
+ * @brief Get the Link Data field of the Global Routing Link Record.
  *
  * For an OSPF type 1 link (PointToPoint) the Link Data will be the IP
  * address of the node of the local side of the link.
@@ -126,7 +126,7 @@
   Ipv4Address GetLinkData(void) const;
 
 /**
- * @brief Set the Link Data field of the Global Router Link Record.
+ * @brief Set the Link Data field of the Global Routing Link Record.
  *
  * For an OSPF type 1 link (PointToPoint) the Link Data must be the IP
  * address of the node of the local side of the link.
@@ -139,29 +139,29 @@
   void SetLinkData(Ipv4Address addr);
 
 /**
- * @brief Get the Link Type field of the Global Router Link Record.
+ * @brief Get the Link Type field of the Global Routing Link Record.
  *
  * The Link Type describes the kind of link a given record represents.  The
  * values are defined by OSPF.
  *
  * @see LinkType
- * @returns The LinkType of the current Global Router Link Record.
+ * @returns The LinkType of the current Global Routing Link Record.
  */
   LinkType GetLinkType(void) const;
 
 /**
- * @brief Set the Link Type field of the Global Router Link Record.
+ * @brief Set the Link Type field of the Global Routing Link Record.
  *
  * The Link Type describes the kind of link a given record represents.  The
  * values are defined by OSPF.
  *
  * @see LinkType
- * @param linkType The new LinkType for the current Global Router Link Record.
+ * @param linkType The new LinkType for the current Global Routing Link Record.
  */
   void SetLinkType(LinkType linkType);
 
 /**
- * @brief Get the Metric Data field of the Global Router Link Record.
+ * @brief Get the Metric Data field of the Global Routing Link Record.
  *
  * The metric is an abstract cost associated with forwarding a packet across
  * a link.  A sum of metrics must have a well-defined meaning.  That is, you
@@ -169,12 +169,12 @@
  * two hops relate to the cost of sending a packet); rather you should use
  * something like delay.
  *
- * @returns The metric field of the Global Router Link Record.
+ * @returns The metric field of the Global Routing Link Record.
  */
   uint32_t GetMetric(void) const;
 
 /**
- * @brief Set the Metric Data field of the Global Router Link Record.
+ * @brief Set the Metric Data field of the Global Routing Link Record.
  *
  * The metric is an abstract cost associated with forwarding a packet across
  * a link.  A sum of metrics must have a well-defined meaning.  That is, you
@@ -182,7 +182,7 @@
  * two hops relate to the cost of sending a packet); rather you should use
  * something like delay.
  *
- * @param metric The new metric for the current Global Router Link Record.
+ * @param metric The new metric for the current Global Routing Link Record.
  */
   void SetMetric(uint32_t metric);
 
@@ -211,7 +211,7 @@
   Ipv4Address m_linkData;    // for links to RouterLSA, 
 
 /**
- * The type of the Global Router Link Record.  Defined in the OSPF spec.  
+ * The type of the Global Routing Link Record.  Defined in the OSPF spec.  
  * We currently only use PointToPoint and StubNetwork types.
  */
   LinkType m_linkType;
@@ -236,12 +236,24 @@
  * combined with a list of Link Records.  Since it's global, there's
  * no need for age or sequence number.  See RFC 2328, Appendix A.
  */
-class GlobalRouterLSA
+class GlobalRoutingLSA
 {
 public:
 /**
+ * @enum LSType
+ * @brief corresponds to LS type field of RFC 2328 OSPF LSA header
+ */
+  enum LSType {
+    Unknown = 0,        /**< Uninitialized Type */
+    RouterLSA,
+    NetworkLSA,
+    SummaryLSA,
+    SummaryLSA_ASBR,
+    ASExternalLSAs
+  };
+/**
  * @enum SPFStatus
- * @brief Enumeration of the possible values of the status flag in the Router 
+ * @brief Enumeration of the possible values of the status flag in the Routing 
  * Link State Advertisements.
  */
   enum SPFStatus {
@@ -249,17 +261,16 @@
     LSA_SPF_CANDIDATE,		/**< Vertex is in the SPF candidate queue */
     LSA_SPF_IN_SPFTREE		/**< Vertex is in the SPF tree */
   };
-
 /**
- * @brief Create a blank Global Router Link State Advertisement.  
+ * @brief Create a blank Global Routing Link State Advertisement.  
  *
  * On completion Ipv4Address variables initialized to 0.0.0.0 and the 
  * list of Link State Records is empty.
  */
-  GlobalRouterLSA();
+  GlobalRoutingLSA();
 
 /**
- * @brief Create an initialized Global Router Link State Advertisement.  
+ * @brief Create an initialized Global Routing Link State Advertisement.  
  *
  * On completion the list of Link State Records is empty.
  *
@@ -267,42 +278,42 @@
  * @param linkStateId The Ipv4Address for the link state ID field.
  * @param advertisingRtr The Ipv4Address for the advertising router field.
  */
-  GlobalRouterLSA(SPFStatus status, Ipv4Address linkStateId, 
+  GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId, 
     Ipv4Address advertisingRtr);
 
 /**
- * @brief Copy constructor for a Global Router Link State Advertisement.
+ * @brief Copy constructor for a Global Routing Link State Advertisement.
  *
  * Takes a piece of memory and constructs a semantically identical copy of
  * the given LSA.
  *
  * @param lsa The existing LSA to be used as the source.
  */
-  GlobalRouterLSA (GlobalRouterLSA& lsa);
+  GlobalRoutingLSA (GlobalRoutingLSA& lsa);
 
 /**
- * @brief Destroy an existing Global Router Link State Advertisement.
+ * @brief Destroy an existing Global Routing Link State Advertisement.
  *
- * Any Global Router Link Records present in the list are freed.
+ * Any Global Routing Link Records present in the list are freed.
  */
-  ~GlobalRouterLSA();
+  ~GlobalRoutingLSA();
 
 /**
- * @brief Assignment operator for a Global Router Link State Advertisement.
+ * @brief Assignment operator for a Global Routing Link State Advertisement.
  *
- * Takes an existing Global Router Link State Advertisement and overwrites
+ * Takes an existing Global Routing Link State Advertisement and overwrites
  * it to make a semantically identical copy of a given prototype LSA.
  *
- * If there are any Global Router Link Records present in the existing 
+ * If there are any Global Routing Link Records present in the existing 
  * LSA, they are freed before the assignment happens.
  *
  * @param lsa The existing LSA to be used as the source.
  * @returns Reference to the overwritten LSA.
  */
-  GlobalRouterLSA& operator= (const GlobalRouterLSA& lsa);
+  GlobalRoutingLSA& operator= (const GlobalRoutingLSA& lsa);
 
 /**
- * @brief Copy any Global Router Link Records in a given Global Router Link
+ * @brief Copy any Global Routing Link Records in a given Global Routing Link
  * State Advertisement to the current LSA.  
  * 
  * Existing Link Records are not deleted -- this is a concatenation of Link 
@@ -311,57 +322,66 @@
  * @see ClearLinkRecords ()
  * @param lsa The LSA to copy the Link Records from.
  */
-  void CopyLinkRecords (const GlobalRouterLSA& lsa);
+  void CopyLinkRecords (const GlobalRoutingLSA& lsa);
 
 /**
- * @brief Add a given Global Router Link Record to the LSA.
+ * @brief Add a given Global Routing Link Record to the LSA.
  *
- * @param lr The Global Router Link Record to be added.
+ * @param lr The Global Routing Link Record to be added.
  * @returns The number of link records in the list.
  */
-  uint32_t AddLinkRecord (GlobalRouterLinkRecord* lr);
+  uint32_t AddLinkRecord (GlobalRoutingLinkRecord* lr);
 
 /**
- * @brief Return the number of Global Router Link Records in the LSA.
+ * @brief Return the number of Global Routing Link Records in the LSA.
  *
  * @returns The number of link records in the list.
  */
   uint32_t GetNLinkRecords (void) const;
 
 /**
- * @brief Return a pointer to the specified Global Router Link Record.
+ * @brief Return a pointer to the specified Global Routing Link Record.
  *
  * @param n The LSA number desired.
  * @returns The number of link records in the list.
  */
-  GlobalRouterLinkRecord* GetLinkRecord (uint32_t n) const;
+  GlobalRoutingLinkRecord* GetLinkRecord (uint32_t n) const;
 
 /**
- * @brief Release all of the Global Router Link Records present in the Global
- * Router Link State Advertisement and make the list of link records empty.
+ * @brief Release all of the Global Routing Link Records present in the Global
+ * Routing Link State Advertisement and make the list of link records empty.
  */
   void ClearLinkRecords(void);
 
 /**
- * @brief Check to see if the list of Global Router Link Records present in the
- * Global Router Link State Advertisement is empty.
+ * @brief Check to see if the list of Global Routing Link Records present in the
+ * Global Routing Link State Advertisement is empty.
  *
  * @returns True if the list is empty, false otherwise.
  */
   bool IsEmpty(void) const;
 
 /**
- * @brief Print the contents of the Global Router Link State Advertisement and
- * any Global Router Link Records present in the list.  Quite verbose.
+ * @brief Print the contents of the Global Routing Link State Advertisement and
+ * any Global Routing Link Records present in the list.  Quite verbose.
  */
   void Print (std::ostream &os) const;
 
 /**
+ * @brief Return the LSType field of the LSA 
+ */
+  LSType GetLSType (void) const;
+/**
+ * @brief Set the LS type field of the LSA
+ */
+  void SetLSType (LSType typ);
+
+/**
  * @brief Get the Link State ID as defined by the OSPF spec.  We always set it
  * to the router ID of the router making the advertisement.
  *
  * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
  * @returns The Ipv4Address stored as the link state ID.
  */
   Ipv4Address GetLinkStateId (void) const;
@@ -371,7 +391,7 @@
  * to the router ID of the router making the advertisement.
  *
  * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
  */
   void SetLinkStateId (Ipv4Address addr);
 
@@ -380,7 +400,7 @@
  * set it to the router ID of the router making the advertisement.
  *
  * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
  * @returns The Ipv4Address stored as the advetising router.
  */
   Ipv4Address GetAdvertisingRouter (void) const;
@@ -390,11 +410,48 @@
  * set it to the router ID of the router making the advertisement.
  *
  * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
  */
   void SetAdvertisingRouter (Ipv4Address  rtr);
 
 /**
+ * @brief For a Network LSA, set the Network Mask field that precedes
+ * the list of attached routers.
+ */
+  void SetNetworkLSANetworkMask (Ipv4Mask mask);
+
+/**
+ * @brief For a Network LSA, get the Network Mask field that precedes
+ * the list of attached routers.
+ * 
+ * @returns the NetworkLSANetworkMask 
+ */
+  Ipv4Mask GetNetworkLS