How to extend ns-3 for your research

Having been busy with coursework lately, I hadn’t gone through our users’ list in a while. Wading through a week’s worth of posts today, it seems to me like a good deal of questions are from users who are trying to get started with extending ns-3. This is indeed quite expected; as a research tool, ns-3 is most useful only when built upon. These extensions usually take one of the following forms:

  1. a tweak to an existing protocol to make it simulate some specific scenario (try searching for “attacks” on our users list),
  2. adding some functionality X to an existing module, (for instance, RRC messages support for LTE)
  3. or writing an entirely new module from scratch.

Before you do *anything* with ns-3, go through the tutorials first.

Now, for cases 1 and 2 mentioned above, the *only* way to proceed is:

  1. Go through the literature about what you’re trying to implement — “What do I want to achieve?”
  2. Understand the scope and limitations of the ns-3 module you’re trying to deal with (go through the model documentation at least) — “Does ns-3 have the necessary base for me to build on top of?”
  3. If the answer to the above is “yes”, then start reading through the respective module’s code to figure out where you’ll need to insert your modifications. — “Where does my extension/tweak fit within the existing source code?”
  4. Implement.
  5. Profit.

Case 3, on the other hand, requires a lot more work:

  1. Go through the literature about what you’re trying to implement — “What do I want to achieve?”
  2. Understand how your module would fit within ns-3. This is usually the tricky part. To this end, it’s very important to understand how packets flow through a node within ns-3. This figure from our manual is usually the only thing you’ll need to know to get started.
  3. At this point, I’ll make things easier for myself and assume that you’re going to implement something that fits into the above mentioned architecture (rather than trying to modify the architecture itself). The first step is as simple as deriving from the right class. This gives you the virtual methods you need to implement in order to maintain a particular component’s semantics. So if you’re trying to write a new application, derive from ns3::Application. If it’s a new routing protocol, derive from ns3::Ipv4RoutingProtocol or ns3::Ipv6RoutingProtocol. If it’s a new NetDevice, derive from ns3::NetDevice. The easiest thing to do is to find another example of the component type you’re trying to develop and reflect its basic structure.
  4. Now to get started writing your new module, have a look at Gustavo Carnerio’s script (inside src/)  which generates a skeleton for your new module. This includes the necessary sub-folders for the module, and also the all important wscript file. For most use cases, it would suffice to peek into some other module’s wscript file to get an idea of what to do. If you’re going to need some fancy external libraries, you’ll need to go through the waf documentation a bit. Look into src/click/wscript to get an idea of how to do external linking.
  5. Now once you start developing your new simulation model, you’ll need to attach this object to a node to get it to do something. This mode of attachment varies from component to component. Some objects are ‘aggregated’ to the node, some are added to a list of similar components (like applications being added to a node’s ‘ApplicationList’) and so forth. The best places to look in order to understand this are the helpers for each module. So for instance, if you want to figure out how to add your routing protocol to a node, look at src/olsr/helper/ to get an idea.
  6. Lastly, you’ll need to write simulation scripts to see your module in action. Copying off and editing existing example scripts from the examples/ folder or the src/*/examples/ folders should suffice for most cases.
  7. If you’re going to propose this new module for merge, look at our contributing code page. Keep in mind that we won’t merge code which doesn’t have any documentation, or tests (validation or unit tests, as is applicable).
  8. Merge. 🙂

26 thoughts on “How to extend ns-3 for your research

  1. Shashank

    Wonderful !! I am sure newbies who are interested to extend their research would find this very helpful as it would give them an idea to kick start. 🙂

    1. Shobana Shankar

      hi… I want to extend NS3 to add a new wifi channel model for 60GHz i.e to support for IEEE802.11ad. Can anyone help me with that?

      1. lalithsuresh Post author

        Look through the model documentation to see how the WiFi code is structured, so that you’ll know where to insert your modifications. The code itself resides in src/wifi/model/. I suggest asking for some guidance on ns-developers once you’ve done your homework. 🙂

      2. Shobana

        heyy…thanks a lot for that as I’m a newbie in NS3. i did a detailed study of what I would be required to do… and I think I only need to add an extra function in the class in order to model path loss in 60GHz channel. Can you please tell me if I would need to change anything in wscript or is there anything that would be interconnected with this addition of a new function??
        Thanks a lot…

      3. lalithsuresh Post author

        The wscript files only serve to inform the build system about which files to compile, what libraries to use and so forth. Unless you’re performing some external linkage, you don’t need to touch the wscript file for your particular case.

      4. Shobana

        I added my class to the, and the build was successfull. But when i run the code it says assert failed and TypeId not found. Do I need to add my new class(or a refernce to it) somewhere else also?

        Thanks a lot..

      5. Shobana

        sorry…. there was some small mistake which I found out… Problem solved….


  2. mrbalador


    i worked before with ns-2 but now i change my simulator but i have problem with ns-3
    i have read the tutorial but is not so clear in some part like tracing system.

    do you have any suggestion for continuing in ns-3.
    about writing scenario and getting result from output.

    1. lalithsuresh Post author

      The tracing system requires a steep learning curve, but you’ll find yourself using it a lot once you start getting used to it. Especially when it comes to extracting results.

      About writing scenario files, I suggest starting with an existing example script always, and modifying it incrementally till you get what you want. Have a look within examples/ and src//examples/ and experiment a bit with the existing simulation scripts to get a feel of things.

  3. mrbalador

    ok. i know that the best thing is starting with scenario but
    i want to simulate WSNs which example do you think is better for my simulation?
    after simulation how should i extract the result because it’s different for ns-2 of course for start?

  4. Larissa


    I’ve already created my new module, and it’s building without error, but when I run ./waf I get this errors:

    ./ undefined reference to `ns3::DispatchModule::DoGetMacAddr()’
    ./ undefined reference to `ns3::DispatchModule::DoGetCognitiveInterface()’
    ./ undefined reference to `ns3::DispatchModule::GetFlagAck()’
    ./ undefined reference to `ns3::DispatchModule::Send()’
    ./ undefined reference to `ns3::DispatchModule::GetMainAddress()’
    ./ undefined reference to `ns3::DispatchModule::SetCognitiveInterface(ns3::Ptr)’
    ./ undefined reference to `ns3::DispatchModule::DoPopQueue()’

    Could you please help me?

    Thank you,

    1. lalithsuresh Post author

      Did you implement these methods? As in, it seems like you’ve specified the signatures for these methods in a .h file, and haven’t implemented them (in a .cc file, typically).

      1. lalithsuresh Post author

        Are you sure the .cc file is specified correctly in the wscript file?

        Also, try “./waf distclean”, then configure and re-build.

  5. Larissa

    This is how my wscript looks:

    def build(bld):
    module = bld.create_ns3_module(‘dispatch-module’, [‘core’,’internet’,’wifi’])
    module.source = [

    headers = bld.new_task_gen(features=[‘ns3header’])
    headers.module = ‘dispatch-module’
    headers.source = [

    I tried the ./waf distclean command but I still get the same error.

    1. lalithsuresh Post author

      Can you verify if the signatures for the method definitions match that of the method implementations (return types and parameter types, order etc.)?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s