forked from hip2b2/poxstuff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathof_firewall.py
152 lines (135 loc) · 5.89 KB
/
of_firewall.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/python
# Copyright 2012 William Yu
#
# This file is part of POX.
#
# POX is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# POX 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 POX. If not, see <http://www.gnu.org/licenses/>.
#
# NOISY FIREWALL. This is a simple firewall implementation for demonstration
# purposes. This firewall is bad because only flows for valid packets are
# installed. Non-matches always trigger a PacketIn().
#
# This is a demonstration file aims to build a firewall. In this demo,
# firewall rules are applied to specific ports in the switch using the
# following commands:
# AddRule (event, dl_type=0x800, nw_proto=1, port=0, src_port=of.OFPP_ALL)
# DeleteRule (event, dl_type=0x800, nw_proto=1, port=0, src_port=of.OFPP_ALL):
# ShowRule ()
#
# Mininet Command Line: sudo mn --topo single,3 --mac --switch ovsk --controller remote
# Command Line: ./pox.py py log.level --DEBUG samples.of_firewall
#
# THIS VERSION SUPPORT resend() functionality in the betta branch POX.
#
# These next two imports are common POX convention
from pox.core import core
from pox.lib.util import dpidToStr
import pox.openflow.libopenflow_01 as of
from pox.lib.packet.ethernet import ethernet
# Even a simple usage of the logger is much nicer than print!
log = core.getLogger()
# This table maps (switch,MAC-addr) pairs to the port on 'switch' at
# which we last saw a packet *from* 'MAC-addr'.
# (In this case, we use a Connection object for the switch.)
table = {}
# This table contains the firewall rules:
# firewall[(switch, dl_type, nw_proto, port, src_port)] = TRUE/FALSE
#
# Our firewall only supports inbound rule enforcement per port only.
# By default, this is empty.
# Sample dl_type(s): IP (0x800)
# Sample nw_proto(s): ICMP (1), TCP (6), UDP (17)
#
firewall = {}
# function that allows adding firewall rules into the firewall table
def AddRule (event, dl_type=0x800, nw_proto=1, port=0, src_port=of.OFPP_ALL):
firewall[(event.connection,dl_type,nw_proto,port,src_port)]=True
log.debug("Adding firewall rule to %s: %s %s %s %s" %
dpidToStr(event.connection.dpid), dl_type, nw_proto, port, src_port)
# function that allows deleting firewall rules from the firewall table
def DeleteRule (event, dl_type=0x800, nw_proto=1, port=0, src_port=of.OFPP_ALL):
try:
del firewall[(event.connection,dl_type,nw_proto,port,src_port)]
log.debug("Deleting firewall rule in %s: %s %s %s %s" %
dpidToStr(event.connection.dpid), dl_type, nw_proto, port, src_port)
except KeyError:
log.error("Cannot find in %s: %s %s %s %s" %
dpidToStr(event.connection.dpid), dl_type, nw_proto, port, src_port)
# function to display firewall rules
def ShowRules ():
for key in firewall:
log.info("Rule %s defined" % key)
# function to handle all housekeeping items when firewall starts
def _handle_StartFirewall (event):
log.info("Firewall Tutorial is running.")
# function to handle all PacketIns from switch/router
def _handle_PacketIn (event):
packet = event.parsed
# only process Ethernet packets
if packet.type != ethernet.IP_TYPE:
return
# check if packet is compliant to rules before proceeding
if (firewall[(event.connection, packet.dl_type, packet.nw_proto, packet.tp_src, event.port)] == True):
log.debug("Rule (%s %s %s %s) FOUND in %s" %
dpidToStr(event.connection.dpid), packet.dl_type, packet.nw_proto, packet.tp_src, event.port)
else:
log.debug("Rule (%s %s %s %s) NOT FOUND in %s" %
dpidToStr(event.connection.dpid), packet.dl_type, packet.nw_proto, packet.tp_src, event.port)
return
# Learn the source and fill up routing table
table[(event.connection,packet.src)] = event.port
dst_port = table.get((event.connection,packet.dst))
if dst_port is None:
# We don't know where the destination is yet. So, we'll just
# send the packet out all ports (except the one it came in on!)
msg = of.ofp_packet_out(resend = event.ofp)
msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
msg.send(event.connection)
log.debug("Broadcasting %s.%i -> %s.%i" %
(packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))
else:
# Since we know the switch ports for both the source and dest
# MACs, we can install rules for both directions.
msg = of.ofp_flow_mod()
msg.match.dl_type = packet.dl_type
msg.match.nw_proto = packet.nw_proto
if (nw_proto != 1):
msg.match.tp_src = packet.tp_src
msg.match.dl_dst = packet.src
msg.match.dl_src = packet.dst
msg.idle_timeout = 10
msg.hard_timeout = 30
msg.actions.append(of.ofp_action_output(port = event.port))
msg.send(event.connection)
# This is the packet that just came in -- we want to
# install the rule and also resend the packet.
msg = of.ofp_flow_mod()
msg.match.dl_type = packet.dl_type
msg.match.nw_proto = packet.nw_proto
if (nw_proto != 1):
msg.match.tp_src = packet.tp_src
msg.match.dl_src = packet.src
msg.match.dl_dst = packet.dst
msg.idle_timeout = 10
msg.hard_timeout = 30
msg.actions.append(of.ofp_action_output(port = dst_port))
msg.send(event.connection, resend = event.ofp)
log.debug("Installing %s.%i -> %s.%i AND %s.%i -> %s.%i" %
(packet.dst, dst_port, packet.src, event.ofp.in_port,
packet.src, event.ofp.in_port, packet.dst, dst_port))
# main function to start module
def launch ():
core.openflow.addListenerByName("ConnectionUp", _handle_StartFirewall)
core.openflow.addListenerByName("PacketIn", _handle_PacketIn)