Vous êtes sur la page 1sur 8

Cisco IOU:Connect IOU with real or external networks EtherealMind

Page 1 of 8

Home Advertise Network ZEN Who Am I ? Writing and Authoring Contact Markdown Reference Reference What Does Ethereal Mind Mean ? Blog Ethics and Disclosure Disclaimer Just Three EtherealMind Network Design, Analysis, Review. Blessay Featured Blog Response Thought for My Day Musing Opinion Posters Design OpenFlow Dictionary Network Diagrams Operation Basics Tech Notes Network ZEN OSX You are here: Home / Blog / Cisco IOU:Connect IOU with real or external networks

Cisco IOU:Connect IOU With Real or External Networks


17th April 2011 By Greg Ferro 5 Comments This is a reblog from the original article at Connect IOU with real networks or dynamips

From Internetworkpro
This guide provides explanations to a script called iou2net.pl (script is at the end of the article), which allows you to attach IOU instances to real network (interfaces). In its functionality, its similar to what the ioulive tool does. For more information about IOU or ioulive, ask your Cisco SE/AM that provided you with your copy of IOU, or check out the [IOU FAQ from evilrouters.net][3]. Why another script that does nearly the same thing as ioulive? While playing around with IOU, i tried to come up with a way to attach IOU instances to dynamips directly. I managed to get this working for single instances, but came to the conclusion that its best to integrate such functionality in dynagen directly. Unfortunately, Im not a good programmer and have no experience with python, nor the time to dig through the dynagen sources and extend the code. This script is a byproduct of this work, where i tried to document the packet format that IOU uses to communicate between instances.

Installation
The program is written in perl and can be copied directly from the source listing (end of the article) to a file. Make the file executeable with
chmod +x ./iou2net.pl

Dependencies
iou2net depends on some perl modules. Most of them should come with your default perl distribution. Best case, the extra installation of Net::Pcap should do the trick to satisfy dependencies. On Ubuntu and Debian systems, this is provided with the libnet-pcap-perl package. Of course, beside the perl package, you need libpcap too (not sure if -dev is required).
sudo apt-get install libnet-pcap-perl libpcap0.8

For systems that dont pack the perl module, use CPAN to install it:
perl -MCPAN -e 'install Net::Pcap'

Now try to start the script, it should start without any module warnings, printing the help screen:
./iou2net.pl

Usage

Print to PDF without this message by purchasing novaPDF (http://www.novapdf.com/) http://etherealmind.com/cisco-iou-external-real-network-remote/

06/01/2013

Cisco IOU:Connect IOU with real or external networks EtherealMind

Page 2 of 8

iou2net will forward frames between a IOU instance and a (real) network adapter. IOU needs a special mapping in its NETMAP file. The interface of the IOU instance you want to forward from has to be listed as a source entry, with a @ suffix at the end. The destination of the mapping will be a pseudo IOU instance number, with a pseudo interface number. iou2net.pl will use this pseudo IOU instance ID to connect to the real IOU instance, and do its frame relaying. Example NETMAP file:
10:1/1 10:1/2 10:1/0@iou-test 11:1/0 12:1/0 20:0/0@iou-test

The first two mappings are normal connections between IOU instances at the same host (R10, 1/1 R11, 1/0 and R10, 1/2 R12, 1/0). The last one connects interface 1/0 of R10 to pseudo router (instance) 20, interface 0/0. You can choose any ID (<1024), as long as its not used by any real IOU instance. Specify this ID with the option -p when launching the script. Dont use this arbitrary ID for anything else in your mappings/topology. iou2net will need to read through this NETMAP file, to determine the correct mapping. By default, it looks in the current directory for the file NETMAP. If you want to use a file in a different directory (and/or with a different name), use the -n option. Last, you must specify the network interface where the frames should be forwarded to/received from. iou2net.pl will put this interface into promiscuous mode, therefore you must have superuser privileges when starting the script.
$ sudo ./iou2net.pl -i eth0 -p 20 Forwarding frames between interface eth0 and IOU instance 10, int 1/0 press ^C to exit

Limitations
This is only tested with Linux so far. Im sure it will run at other modern Unices, too. From perl perspective, porting this to windows is a possible, yet a pointless approach, because there is no IO_W_ (afaik). For the NETMAP mapping line that is related with iou2net.pl pseudo ID, you must use id:x/y interface notation and not the compressed id:z format. Its just a matter of implementation in the script, im too lazy to add this. There is not much sanity checking. The last occurence of a line that contains the pseudo ID as a destination is used, no matter how many other mappings with this ID exist before in the NETMAP file. These are typos anyway (see next limitation). A single instance of this script will handle one IOU < -> network mapping. If you, for example, have multiple NICs in your systems and therefore want multiple IOU interfaces to be forwarded, you must launch multiple instances of the script. Every mapping must get a unique pseudo ID as the destination, and every instance of the script must be started by adding this unique ID. Example: $ cat NETMAP 10:1/0@iou-test 20:0/0@iou-test 10:1/1@iou-test 21:0/0@iou-test 11:1/0@iou-test 22:0/0@iou-test [...]$ sudo ./iou2net.pl -i eth0 -p 20 & [...] $ sudo ./iou2net.pl -i eth1 -p 21 & [...] $ sudo ./iou2net.pl -i eth2 -p 22 & [...] I didnt test this approach, but it should work. Also, i didnt test the behavior of bridging multiple instances of this script to the same physical interface please provide feedback. Run all your IOU instances as the same user, otherwise you end up with different netio subdirectories in /tmp, and your IOU instances cannot talk to each other. The script needs to know the real uid of the user, therefore you should invoke iou2net.pl with sudo, from the same user that runs the IOU instances.

What works
Ive done some quick tests with a local IOU instance, one Ethernet interface bridged to a real network where a c1841 is located: Basic communication at layer 2 and 3 (Ethernet), up to MTU of 1500 OSPF adjacency over Broadcast segment (multicast) ISIS adjacency LDP adjacency MPLS encapsulation over Ethernet (@1500 byte [MPLS] MTU, no baby giant/jumbo frame support) IPv6 auto discovery various connectivity tests toward v4 and v6 Internet attaching IOU to dynamips (see below)

IOU communication
In this cha pter, i will outline the packet format and methods IOU uses when communicating outside of an IOU instance. Inter-instance communication is done through UNIX domain sockets. These are created in the subdirectory /tmp/netio1000, with a numeric name that corresponds to . So far, i cannot tell whether this directory is the same for anyone, anytime. You can sniff this traffic with strace, like
$ strace -e sendto,recvfrom -xx -o capturefile.txt <your IOU command line>

When sending frames, IOU will submit the entire L2 frame, prepended with a IOU proprietary header. This header is required at the receiving instance, to make the distinction to which local interface the frame is destined to. This is important, because the sockets are per instance (router) and have no way to decide to which internal interface to forward to (whithout extra logic that looks at MAC addresses etc.). Furthermore, IOU does sanity checks with this header. When receiving a frame, the source information (sending ID, sending interface) is checked against the mappings that were read from the NETMAP file. It is not possible to send frames to an instance with valid destination ID and interface numbers and faked/unknown source information; the source ID and interface numbers have to match also. The header format is described in the script. I cannot say if the last two bytes are really a delimiter that is always 001000, or if these fields serve a different purpose. The script walks through the NETMAP file and determines the correct mapping, extracts the source IOU instance ID and its interface numbers. As discussed above, this is important for constructing the IOU header. Then it creates a socket $iou_pseudo_sock for out IOU pseudo ID (the destination), the real IOU instance (the source) will send its frames to this socket. This socket will be read- and writeable by anyone, since this script runs as root, where you usually run IOU as a normal user. Furthermore, we bind to the socket of the source IOU instance ($iou_router_sock). The IOU header that is used when sending frames to the real IOU instance is now prebuild, all the required information is available. Next, we bind to the NIC through PCAP routines. The receiver that handles the traffic direction IOU->real network is forked to allow for non-blocking functionality (There is an option to IO::Socket::UNIX, allowing the socket to operate in nonblocking mode, but i found this way more intuitive). For every frame that the source IOU instance sends, we strip off the first 8 bytes (the IOU header), and transmit the frame via the real NIC.

Print to PDF without this message by purchasing novaPDF (http://www.novapdf.com/) http://etherealmind.com/cisco-iou-external-real-network-remote/

06/01/2013

Cisco IOU:Connect IOU with real or external networks EtherealMind

Page 3 of 8

The receiver that handles the direction real network->IOU is implemented with a pcap capture loop, where the logic is inside the sub recv_loop. Every received frame will be prepended with the precompiled IOU header and send to the socket of the source IOU instance.

Script
This is a reblog from the original article at Connect IOU with real networks or dynamips and probably worth checking there first for any updates.
#!/usr/bin/perl use use use use use strict; warnings; Getopt::Long; Net::Pcap; IO::Socket;

my $version = "v0.31"; my $version_date = "28-Jan-2011"; ################################################################################### # CHANGES # ======= # # v0.31, 28-Jan-2011 # ----------------# - MAC address is now in "ether" format (bytes separated with ":") for building # the capture filter # # v0.3, 27-Jan-2011 # ----------------# - better capture filter handling, after understanding how IOU generates # MAC addresses (related code is still ugly) # - hostnames with hyphen are now accepted # # v0.21, 26-Jan-2011 # ----------------# - changed socket_base handling after receiving hint that "1000" is the uid # that IOU is started with # # v0.2, 24-Jan-2011 # ----------------# - added pcap filter to allow for better performance on busy nics # # v0.1, 23-Jan-2011 # ----------------# - first release # ################################################################################### my $help = < <EOF; iou2net.pl: bridge between iou and real networks (IOUlive replacement) Version $version, $version_date. usage: iou2net.pl -i <network interface> -n [<iou NETMAP file>] -p </iou><iou pseudo instance ID> -i <network interface> The NIC you want to bridge to/from. You need superuser privileges to do that. -n <iou NETMAP file> (optional) A NETMAP file is always needed, because the original IOU instance must be determined by the script. Without this parameter, the script tries to open the NETMAP file from the current directory. If you want to use a file in a different location, use this parameter. -p </iou><iou pseudo instance ID> IOU requires a pseudo instance for this. When bridging your IOU router interface, specify an unused ID as the target in your NETMAP file, like 1:2/1@hobel 666:1/0@hobel

666 is the pseudo IOU instance ID, hobel is the host where the IOU and the script runs at. When starting the script, use 666 then. CAVEATS: For now, you need to use x/y interface format in the NETMAP file, at least for the mapping this script requires. Also, for bridging multiple router interfaces, separate instances of this script must be launched, and you need an unique pseudo IOU ID per instance. EOF my my my my my my my my my my my my my my my my $err; $pcap_recv_data; $iou_recv_data; $iou_header; $iface; $netmap_file = "./NETMAP"; $netmap_handle; $uid; $socket_base; $pseudo_instance; $pseudo_instance_interface_major; $pseudo_instance_interface_minor; $iou_instance; $iou_interface_major; $iou_interface_minor; $mac;

Print to PDF without this message by purchasing novaPDF (http://www.novapdf.com/) http://etherealmind.com/cisco-iou-external-real-network-remote/

06/01/2013

Cisco IOU:Connect IOU with real or external networks EtherealMind

Page 4 of 8

my $pcap_filter; GetOptions( 'help' 'i=s' 'n=s' 'p=i' ); => sub{ print"$help"; exit(0); }, $iface, $netmap_file, $pseudo_instance

=> => =>

die "nPlease provide -i and -p!n$help" unless ($iface && $pseudo_instance); # # # # socket directory is a directory below $TMPDIR (/tmp), composed of "netio" plus uid of the user that runs the iou binary since we assume this script gets invoked with sudo by most people: try to be smart about getting real UID, $< does not (always?) return real uid when using sudo

$uid = $ENV{SUDO_UID}; $uid = $< unless (defined $uid); $socket_base = "/tmp/netio$uid";

# apparently not started with sudo

open (netmap_handle, $netmap_file) or die "Can't open netmap file $netmap_filen"; # walk through NETMAP file and try to determine the source IOU instance while (<netmap_handle>) { # stop when there is a match for our pseudo instance ID as the destination next if !($_ =~ m/^d+:d+/d+@[w-]+[ t]+$pseudo_instance:d+/d+@[w-]+(s|t)*$/); my $inputline = $_; chomp($inputline); # we just ignore any hostname statements $inputline =~ s/@[w-]+//g; my @connline = split (/[ t]+/, $inputline); $connline[0] =~ s/(st)*//g; $connline[1] =~ s/(st)*//g; my @iou_src = split (/:/, $connline[0]); my @iou_dst = split (/:/, $connline[1]); $iou_instance = $iou_src[0]; ($iou_interface_major,$iou_interface_minor) = split (///, $iou_src[1]); ($pseudo_instance_interface_major,$pseudo_instance_interface_minor) = split (///, $iou_dst[1]); } close (netmap_handle);

die "Could not find any valid mapping for IOU pseudo instance $pseudo_instance in NETMAP file" unless ((defined $iou_instance) && (defined $iou_interface_m # unlink socket for IOU pseudo instance unlink "$socket_base/$pseudo_instance"; # create socket for IOU pseudo instance my $iou_pseudo_sock = IO::Socket::UNIX->new(Type=>SOCK_DGRAM, Listen=>5, Local=>"$socket_base/$pseudo_instance") or die "Can't create IOU pseudo socketn"; # allow anyone to read and write chmod 0666, "$socket_base/$pseudo_instance";

# attach to real IOU instance my $iou_router_sock = IO::Socket::UNIX->new(Type=>SOCK_DGRAM, Peer=>"$socket_base/$iou_instance") or die "Can't connect to IOU socket at $socket_base/$iou_ # # # # # # # # # # # precompute IOU header IOU header format Pos (byte) value ============================================================== 00 - 01 destination (receiving) IOU instance ID 02 - 03 source (sending) IOU instance ID 04 receiving interface ID 05 sending interface ID 06 - 07 fixed delimiter, looks like its always 0x01 0x00 interface ID = <major int number> + (<minor int number> * 16) = sprintf("%04x",$iou_instance) . sprintf ("%04x", $pseudo_instance); .= sprintf ("%02x", ($iou_interface_major + ($iou_interface_minor * 16))); .= sprintf ("%02x", ($pseudo_instance_interface_major + ($pseudo_instance_interface_minor * 16))); .= "0100"; = pack("H*", $iou_header);

$iou_header $iou_header $iou_header $iou_header $iou_header

# bind to network interface, promiscuous mode my $pcap = Net::Pcap::open_live($iface, 1522, 1, 100, $err); die "pcap: can't open device $iface: $err (are you root?)n"

if(not defined $pcap);

# receive IOU frame and send to real network # we fork this, so traffic can be received and processed via pcap in the pcap loop below my $iou_pseudo_fork = fork(); if ($iou_pseudo_fork == 0) { while (1) { # IOU frame received via pseudo ID socket $iou_pseudo_sock->recv($iou_recv_data,1522); # cut off IOU header (first 8 bytes) $iou_recv_data =~ s/^.{8}//; # send IOU generated frame to real network Net::Pcap::sendpacket($pcap,$iou_recv_data); } exit(0); } # provide a clean exit when user sends break

Print to PDF without this message by purchasing novaPDF (http://www.novapdf.com/) http://etherealmind.com/cisco-iou-external-real-network-remote/

06/01/2013

Cisco IOU:Connect IOU with real or external networks EtherealMind

Page 5 of 8

$SIG{INT} = &pcap_sigint; # # # # # # # # # # # # # # # # # # construction of IOU MAC address for external connectivity Pos (byte) value ============================================================== 0 (high nibble) from IOU instance ID (2 bytes, only 10 bits used), the two least significant bits from the high byte are taken and shifted one bit left 0 (low nibble) always 0xE 1 - 3 UID of the user that runs the IOU instance 4 low byte of the IOU instance ID 5 interface ID for x64 systems, binary math works well, like $mac = (((($iou_instance & 0x0300) < < 1 ) << 36 ) + 0xE0000000000 ); $mac += $uid << 16; $mac += ($iou_instance & 0xFF) << 8; $mac += ($iou_interface_minor << 4) + $iou_interface_major; apparently I'm too stupid to deal with Math::BigInt for 32bit system compatibility, so I use string operations

my $macstring; $macstring = sprintf "%x", (($iou_instance >> 7 & 6)); $macstring .= "e"; $macstring .= sprintf "%06x", ($uid); $macstring .= sprintf "%02x", (($iou_instance & 0xFF)); $macstring .= sprintf "%02x", (($iou_interface_minor < < 4) + $iou_interface_major); $macstring = join(":", unpack ("(A2)*", $macstring)); # build a capture filter for IOU interface MAC address # this will match only what is destined to $macstring, plus multicasts and broadcasts Net::Pcap::compile($pcap, $pcap_filter, '(ether[0] & 1 = 1) or (ether dst ' . $macstring . ')', 0, 0xFFFFFFFF) && die 'Unable to compile capture filter'; Net::Pcap::setfilter($pcap, $pcap_filter) && die 'Unable to assign capture filter'; print "Forwarding frames between interface $iface and IOU instance $iou_instance, int $iou_interface_major/$iou_interface_minor (MAC: $macstring) # define infinite loop for capturing network traffic my $loop_exit = Net::Pcap::loop($pcap, -1, &recv_loop, $pcap_recv_data); sub recv_loop { my($user_data, $hdr, $pkt) = @_; # add IOU header in front of the received frame my $iou_frame = $iou_header . "$pkt"; # send frame to IOU socket $iou_router_sock->send($iou_frame); } sub pcap_sigint { Net::Pcap::breakloop($pcap); print "n...stopped by user.n"; Net::Pcap::close($pcap); $iou_pseudo_sock->close; $iou_router_sock->close; kill 1, $iou_pseudo_fork; exit(0); }</minor></major></iou></network></iou></your></instance>

Posts Related to this Article


Cisco IOU: Starting Multiple Routers Internets of Interest:25 Jan 11 SSL VPN in IOS 12.4T Cisco ACE Enterprise Load Balancing on a Stick Using OpenFlow and Software Defined Networking: Is It Routing or

Other posts in the series


1. 2. 3. 4. 5. Cisco IOU:Connect IOU with real or external networks (This post) Cisco IOU:Scripted Start Multiple Routing with L2IOU, memory Cisco IOU: What can Cisco do for Testing, Validation & the IPv6 challenge ? Cisco IOU: Starting Multiple Routers Cisco IOU: Shutting down the IOU Processes Socket
My-Home.Schneider-Electric.com Choose From

Filed Under: Blog, IOU Tagged With: Cisco, iou About Greg Ferro Greg Ferro is a Network Engineer/Architect, mostly focussed on Data Centre, Security Infrastructure, and recently Virtualization. He has over 20 years in IT, in wide range of employers working as a freelance consultant including Finance, Service Providers and Online Companies. He is CCIE#6920 and has a few ideas about the world, but not enough to really count. He is a host on the Packet Pushers Podcast, blogger at EtherealMind.com and on Twitter @etherealmind and Google Plus

Print to PDF without this message by purchasing novaPDF (http://www.novapdf.com/) http://etherealmind.com/cisco-iou-external-real-network-remote/

06/01/2013

Cisco IOU:Connect IOU with real or external networks EtherealMind

Page 6 of 8

5 comments
Leave a message...

Discussion

Community

Share

Carlos a year ago

Couple of points that may help someone: if you are using "sudo bash" to run everything as root, then the script confuses your real id and does not find the right netio subdir. Check with -v and see /tmp/netio*. Also, the script assumes macs with xE:xx:xx:xx:xx:xx, wich seem to be the ones used by IOU router images, but at least one ioul2 image uses x2:xx:xx:xx:xx:xx and fails. Easy to fix.

Reply

Share

Someurt 2 years ago

getting the following error when running iou2net: isco@cisco:/opt/GNS3/iou$ sudo ./iou2net.pl -u 12000:127.0.0.1:7005 -p 150iou2net.pl, Version v0.4, 22-Apr-2011.Can't connect to IOU socket at /tmp/netio1000/1 I do see the folder /tmp/netio1000 created but it does not contain any file. Does anyone know how to fix this? thanks

Reply

Share

dnetcrawler@gmail.com 2 years ago

NETMAP file is the directory, and the instance of the router works normally; but I'm getting the following message: Could not find any valid mapping for IOU pseudo instance 1 in NETMAP file at ./iou2net.pl line 95.

Reply

Share

Paul 2 years ago

Ive tested the script-??works perfectly on a Fedora 14 VM run in VMware fusion. Ive move from Dynamips/?GNS to IUO, its excellent. Regards

Reply

Share

flyxj 2 years ago

there is a python script to do this. http://certcollection.org/foru...

Reply

Share

EtherealMind hosts a podcast on Data Networking where we talk nerdy about technology, recent events, conduct interviews and more. We look at technology, the industry and our daily work lives every week. Our motto: Too Much Networking Would Never Be Enough..

Print to PDF without this message by purchasing novaPDF (http://www.novapdf.com/) http://etherealmind.com/cisco-iou-external-real-network-remote/

06/01/2013

Cisco IOU:Connect IOU with real or external networks EtherealMind

Page 7 of 8

Follow me on Social Media Email Google+ Linkedin RSS Twitter

Post Categories Anthological (237) Bookmarks (218) Outbursts (19) Basics (16) Blessay (90) Blog (845) Dynamips (12) Musing (59) Nerdgasm (6) Network ZEN (4) Operation (94) Blue Coat (10) Netscreen (4) Opinion (133) Posters (10) Rant (42) Response (11) Reviews (4) Security (27) Thought for My Day (7) Cisco (138) CCIE (20) IOU (3) Design (96) Dictionary (193) Featured (118) IPv6 (9) Network Diagrams (12) OpenFlow (17) OSX (63) Storage (19) Tech Notes (3) Uncategorized (11) VMware (9) Wireless (2) Topics by tag
ACEBlessay

BlogBookmarks brocade CCIE certification Cisco cli cloud data centreDesigndiagramming Dictionary Dynamips ethernet fcoe hp humor

humour industry IOS ipocalypse ipv6 iscsi mac management Musing network designopenflowOperation Opinion osx podcast Rant SDN Security Storage study tools trill visio vmware worklife zen
Series 20 Practical Cabling Tips cisco Cisco ACE Load Balance with SNAT Cisco IOS CLI Tricks Cisco IOU Usage Design Documentation DevonThink Diagrams Difference between Network &amp; Server IPv6 IPocalypse Knowledge Management

Print to PDF without this message by purchasing novaPDF (http://www.novapdf.com/) http://etherealmind.com/cisco-iou-external-real-network-remote/

06/01/2013

Cisco IOU:Connect IOU with real or external networks EtherealMind

Page 8 of 8

Network Dictionary Network Zen Poster Predictions 2012 Screencasts Switch Silicon Fabrics Tech Notes Working with Putty

Recent Twitters Post: How to Live with Introverts by =SVeidt on deviantART http://t.co/7DgRndDn about 10 hours ago Chillax at the Souk in central London after theatre - wine & baklava #BeerOClock http://t.co/E73vBsG0 about 17 hours ago :Blog post: Screencast: Knowledge Management in Technology - Part 2 http://t.co/5ITfaeqK about 19 hours ago Heading to Lindon Theatre tonight #BeerOclock http://t.co/l7pQndBU about 24 hours ago :Blog post: My Intentions for 2013 http://t.co/4ZOQHC4v about 1 day ago Find me on the Twitter

Return to top of page Copyright Greg Ferro 2008-2013 - When people agree with me, I think I must be wrong.

Print to PDF without this message by purchasing novaPDF (http://www.novapdf.com/) http://etherealmind.com/cisco-iou-external-real-network-remote/

06/01/2013

Vous aimerez peut-être aussi