Initial oftest skeleton with wrapper generators and pylibopenflow
diff --git a/tools/pylibopenflow/pylib/of/simu.py b/tools/pylibopenflow/pylib/of/simu.py
new file mode 100644
index 0000000..508b076
--- /dev/null
+++ b/tools/pylibopenflow/pylib/of/simu.py
@@ -0,0 +1,144 @@
+"""This module simulates the network.
+
+Copyright(C) 2009, Stanford University
+Date November 2009
+Created by ykk
+"""
+import openflow
+import output
+import of.msg
+import of.network
+
+class network(of.network.network):
+ """Class to simulate OpenFlow network
+
+ Copyright(C) 2009, Stanford University
+ Date November 2009
+ Created by ykk
+ """
+ def __init__(self):
+ """Initialize network
+ """
+ of.network.network.__init__(self)
+ ##Name of use for output
+ self.name = self.__class__.__name__+str(id(self))
+
+class link(of.network.link):
+ """Class to simulate link
+
+ Copyright(C) 2009, Stanford University
+ Date November 2009
+ Created by ykk
+ """
+ def __init__(self, switch1, switch2, isUp=True):
+ """Initialize link
+ """
+ of.network.link.__init__(self, switch1, switch2)
+ ##Name of use for output
+ self.name = self.__class__.__name__+str(id(self))
+ ##Indicate if link is up
+ self.isUp = isUp
+
+class switch(of.network.switch):
+ """Class to simulate OpenFlow switch
+
+ Copyright(C) 2009, Stanford University
+ Date November 2009
+ Created by ykk
+ """
+ def __init__(self, messages, controller, port, miss_send_len=128,
+ dpid=None, n_buffers=100, n_tables=1,
+ capability=None, parser=None, connection=None):
+ """Initialize switch
+ """
+ of.network.switch.__init__(self, miss_send_len,
+ None, dpid, n_buffers, n_tables,
+ capability)
+ ##Name of use for output
+ self.name = self.__class__.__name__+str(id(self))
+ ##Reference to OpenFlow messages
+ self.__messages = messages
+ ##Reference to connection
+ self.connection = openflow.tcpsocket(messages, controller, port)
+ self.sock = self.connection.sock
+ ##Reference to Parser
+ self.parser = None
+ if (parser == None):
+ self.parser = of.msg.parser(messages)
+ else:
+ self.parser = parser
+
+ def receive_openflow(self, packet):
+ """Switch receive OpenFlow packet, and respond accordingly
+ """
+ dic = self.__messages.peek_from_front("ofp_header", packet)
+ if (dic["type"][0] == self.__messages.get_value("OFPT_HELLO")):
+ output.dbg("Receive hello", self.name)
+ elif (dic["type"][0] == self.__messages.get_value("OFPT_ECHO_REQUEST")):
+ self.reply_echo(dic["xid"][0])
+ elif (dic["type"][0] == self.__messages.get_value("OFPT_FEATURES_REQUEST")):
+ self.reply_features(dic["xid"][0])
+ elif (dic["type"][0] == self.__messages.get_value("OFPT_FLOW_MOD")):
+ self.handle_flow_mod(packet)
+ else:
+ output.dbg("Unprocessed message "+self.parser.header_describe(dic),
+ self.name)
+
+ def send_hello(self):
+ """Send hello
+ """
+ self.connection.structsend("ofp_hello",
+ 0, self.__messages.get_value("OFPT_HELLO"),
+ 0, 0)
+ output.dbg("Send hello",self.name)
+
+ def send_packet(self, inport, bufferid=None, packet="", xid=0, reason=None):
+ """Send packet in
+ Assume no match as reason, bufferid = 0xFFFFFFFF,
+ and empty packet by default
+ """
+ if (reason == None):
+ reason = self.__messages.get_value("OFPR_NO_MATCH")
+ if (bufferid == None):
+ bufferid = int("0xFFFFFFFF",16)
+ pktin = self.__messages.pack("ofp_packet_in",
+ 0, self.__messages.get_value("OFPT_PACKET_IN"),
+ 0, xid, #header
+ bufferid, len(packet),
+ inport, reason, 0)
+ self.connection.structsend_raw(pktin+packet)
+ output.dbg("Send packet ",self.name)
+
+ def send_echo(self, xid=0):
+ """Send echo
+ """
+ self.connection.structsend_xid("ofp_header",
+ 0, self.__messages.get_value("OFPT_ECHO_REQUEST"),
+ 0, xid)
+ output.dbg("Send echo", self.name)
+
+ def reply_echo(self, xid):
+ """Reply to echo request
+ """
+ self.connection.structsend_xid("ofp_header",
+ 0, self.__messages.get_value("OFPT_ECHO_REPLY"),
+ 0, xid)
+ output.dbg("Reply echo of xid:"+str(xid),self.name)
+
+ def reply_features(self, xid):
+ """Reply to feature request
+ """
+ self.connection.structsend_xid("ofp_switch_features",
+ 0, self.__messages.get_value("OFPT_FEATURES_REPLY"),
+ 0, xid,
+ self.datapath_id, self.n_buffers,
+ self.n_tables,0,0,0,
+ self.capability.get_capability(self.__messages),
+ self.capability.get_actions(self.__messages))
+ output.dbg("Replied features request of xid "+str(xid), self.name)
+
+ def handle_flow_mod(self, packet):
+ """Handle flow mod: just print it here
+ """
+ output.dbg(self.parser.flow_mod_describe(packet), self.name)
+