#! /usr/bin/env ruby # # Trema command-line tool. # # Copyright (C) 2008-2013 NEC 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., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # $LOAD_PATH.unshift File.expand_path(File.join File.dirname(__FILE__), '..', 'ruby') require 'rubygems' require 'bundler/setup' require 'gli' require 'trema/command' require 'trema/util' require 'trema/version' require 'trema/default_openflow_channel_port' class BinTrema include Trema::Command include Trema::Util include GLI::App def initialize program_desc 'Trema command-line tool' desc 'Displays the current runtime version' version Trema::VERSION desc 'Be verbose' switch [:v, :verbose], :negatable => false desc 'Runs a trema application' arg_name 'controller' command :run do | c | c.desc 'Runs as a daemon' c.switch [:d, :daemonize], :negatable => false c.desc 'Enables Trema wireshark plugin' c.switch [:s, :tremashark], :negatable => false c.desc "Overrides the default openflow channel port #{Trema::DEFAULT_OPENFLOW_CHANNEL_PORT}" c.flag [:p, :port] c.desc 'Specifies emulated network configuration' c.flag [:c, :conf] c.desc 'Disables initial flow cleanup for a connected switch' c.switch [:r, :no_flow_cleanup], :negatable => false c.action do | global_options, options, args | trema_run options end end desc 'Terminates a trema process' arg_name 'name' command :kill do | c | c.action do | global_options, options, args | help_now!('name is required') if args.empty? args.each do | each | trema_kill each end end end desc 'Starts a killed trema process again' arg_name 'name' command :up do | c | c.action do | global_options, options, args | trema_up args[ 0] end end desc 'Terminates all trema processes' command :killall do | c | c.action do trema_killall end end desc 'Sends UDP packets to destination host' command :send_packets do | c | c.desc 'host that sends packets' c.flag [:s, :source] c.desc 'host that receives packets' c.flag [:d, :dest] c.desc 'number of times to increment the IP source address' c.default_value nil c.flag [:inc_ip_src] c.desc 'number of times to increment the IP destination address' c.default_value nil c.flag [:inc_ip_dst] c.desc 'set the initial UDP source port' c.flag [:tp_src] c.desc 'number of times to increment the UDP source port' c.default_value nil c.flag [:inc_tp_src] c.desc 'set the initial UDP destination port' c.flag [:tp_dst] c.desc 'number of times to increment the UDP destination port' c.default_value nil c.flag [:inc_tp_dst] c.desc 'send packet rate - packets per second' c.flag [:pps] c.desc 'number of packets to send' c.flag [:n_pkts] c.desc 'time duration to send packets' c.flag [:duration] c.desc 'length of UDP payload' c.flag [:length] c.desc 'increment UDP payload' c.default_value nil c.flag [:inc_payload] c.action do | global_options, options, args | fail '--source option is mandatory' if options[ :source].nil? fail '--dest option is mandatory' if options[ :dest].nil? trema_send_packets options[ :source], options[ :dest], options end end desc "Brings a switch's specified port up" command :port_up do | c | c.desc 'switch name' c.flag [:s, :switch] c.desc 'port' c.flag [:p, :port] c.action do | global_options, options, args | fail '--switch option is mandatory' if options[ :switch].nil? fail '--port option is mandatory' if options[ :port].nil? trema_port_up options[ :switch], options[ :port] end end desc "Brings a switch's specified port down" command :port_down do | c | c.desc 'switch name' c.flag [:s, :switch] c.desc 'port' c.flag [:p, :port] c.action do | global_options, options, args | fail '--switch option is mandatory' if options[ :switch].nil? fail '--port option is mandatory' if options[ :port].nil? trema_port_down options[ :switch], options[ :port] end end desc 'Shows stats of packets' arg_name 'host' command :show_stats do | c | c.desc 'Show stats of packets sent' c.switch [:t, :tx], :negatable => false c.desc 'Show stats of packets received' c.switch [:r, :rx], :negatable => false c.action do | global_options, options, args | help_now!('host is required') if args.empty? trema_show_stats args[ 0], options[ :tx], options[ :rx] end end desc 'Resets stats of packets' arg_name 'hosts...' command :reset_stats do | c | c.action do | global_options, options, args | hosts = args if hosts.empty? hosts = Trema::DSL::Context.load_current.hosts.keys end hosts.each do | each | trema_reset_stats each end end end desc 'Print all flow entries' arg_name 'switches...' command :dump_flows do | c | c.action do | global_options, options, args | help_now!('switches is required') if args.empty? trema_dump_flows args end end desc 'Opens a new shell in the specified network namespace' arg_name 'name' command :netns do | c | c.action do | global_options, options, args | trema_netns args[ 0] end end desc "Opens in your browser Trema's Ruby API documentation" command :ruby do | c | c.action do trema_ruby end end desc 'Displays the current runtime version' command :version do | c | c.action do trema_version end end GLI::Commands::Help.skips_pre = false pre do | global, command, options, args | $verbose = global[ :verbose] if global[ :version] trema_version exit_now! nil, 0 end assert_trema_is_built if FileTest.exist?(Trema.tmp) && !FileTest.writable?(Trema.tmp) # Trema is system widely installed with gem command sh "sudo chmod a+w -R #{ Trema.tmp }" end FileUtils.mkdir_p Trema.log FileUtils.mkdir_p Trema.pid FileUtils.mkdir_p Trema.sock true end on_error do | exception | # Error logic here # return false to skip default error handling true end end def start(argv) run argv rescue puts $! $!.backtrace.each do | each | puts each end exit end end exit BinTrema.new.start(ARGV) ### Local variables: ### mode: Ruby ### coding: utf-8 ### indent-tabs-mode: nil ### End: