root/samrb/trunk/SimpleAuthManager.rb

Revision 2, 6.8 KB (checked in by gautam, 18 months ago)

Initial import.

Line 
1#!/usr/bin/ruby
2#
3# Copyright (c) 2010-2012 WINLAB, Rutgers University, USA
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy
6# of this software and associated documentation files (the "Software"), to deal
7# in the Software without restriction, including without limitation the rights
8# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9# copies of the Software, and to permit persons to whom the Software is
10# furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in
13# all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21# THE SOFTWARE.
22#
23#
24
25require 'yaml'
26require 'socket'      # Sockets are in standard library
27require 'rubygems'
28require 'open4'
29require 'orderedhash'
30require 'snmp'
31
32$sClientStore = 'WimaxClient.yaml'
33$sClick = '/usr/local/bin/click'
34$sClickConf = 'Wimax.click'
35$sNullMac = '00:00:00:00:00:00'
36
37# Insert the list of client mac addresses,
38# and their corresponding IP addresses in ips varaible below.
39$ips = {   
40'00:aa:bb:cc:dd:ee' => '10.41.0.10',
41}
42
43# Insert the network specific entries below:
44$def_gw = "10.41.0.1"    # Holds the IP of the default gateway.
45$net_mask = "255.255.0.0" # Holds the netmask
46$def_ip = "10.41.0.254"   # This is a default IP used for a client whose entry is not found in the client MAC listing described above.
47
48$sHostname = 'localhost'
49$dRcvPort = 54321
50$dSndPort = 54322
51
52class Client 
53  attr_accessor :mac
54  attr_accessor :ul
55  attr_accessor :dl
56  attr_accessor :ip
57  attr_accessor :vlan
58
59  def initialize(mac,ipa)
60    @mac = mac
61    @ip = ipa
62    @ul = nil
63    @dl = nil
64    @vlan = nil
65  end
66
67end
68
69#hClients.delete(mac)
70#
71
72def AddClient(mac)
73  # Check if MAC address exists already
74
75#  SNMP::Manager.open(:Host => "ofwireless.stanford.edu",:Version => ::SNMPv2c, :Community => 'public') do |snmp|
76#    x=snmp.trap_v2(100,
77#     
78#    'localhost',
79#    :enterpriseSpecific, #Generic Trap Type
80#    []
81#  )
82
83  if ($hClients.has_key?(mac)) then
84    # If it does just remove it's tunnels
85    $hClients[mac].dl = nil
86    $hClients[mac].ul = nil
87  else 
88    # if not create it
89    if ($ips.has_key?(mac)) then
90      $hClients[mac] = Client.new(mac,$ips[mac])
91      puts "New client [#{mac}] = #{@ip}"
92    else
93      puts "Unknown mac= "+mac
94      $hClients[mac] = Client.new(mac,$def_ip)
95    end
96#    # and then store it in persistent storage
97#    open($sClientStore, 'w') { |f| YAML.dump($hClients, f) }
98  end
99end
100
101def addGRE(mac,ch,gre)
102  # Check if MAC address exists already
103  AddClient(mac) unless ($hClients.has_key?(mac))
104  if (ch == '1') then
105    $hClients[mac].ul = gre
106  else 
107    $hClients[mac].dl = gre
108  end
109end
110
111def delGRE(mac,ch,gre)
112  # Check if MAC address exists already
113  if ($hClients.has_key?(mac)) then
114    if (ch == '1') then
115      $hClients[mac].ul = nil
116    else 
117      $hClients[mac].dl = nil
118    end
119  end
120end
121
122def CreateClickConfiguration(file,clients)
123
124  file << "
125switch :: EtherSwitch;
126eth0_queue :: Queue;
127FromDevice(eth0, PROMISC 1) -> [0]switch;
128switch[0] -> eth0_queue -> ToDevice(eth0);
129"
130  puts "Writting to a file"
131  i = 1
132  clients.each { |mac,client|
133    next unless (client.ul != nil and client.dl != nil);
134    file << "// ---  Client #{i} -------- //"
135    file << "
136AddressInfo(c_#{i} #{client.ip} #{client.mac});
137arr_#{i} :: ARPResponder(c_#{i});
138arq_#{i} :: ARPQuerier(c_#{i});
139"
140    file << "
141Script(write arq_#{i}.gateway #{$def_gw}, write arq_#{i}.netmask #{$net_mask} )
142"
143    file << "
144ulgre_#{i} :: FromDevice(#{client.ul});
145dlgre_#{i} :: ToDevice(#{client.dl});
146"
147    file << "
148switch[#{i}] -> cf_#{i} :: Classifier(12/0806 20/0001, 12/0806 20/0002, -);
149cf_#{i}[0] -> arr_#{i} -> [#{i}]switch
150cf_#{i}[1] -> [1]arq_#{i}
151cf_#{i}[2] -> Strip(14) -> dlgreq_#{i} :: Queue -> dlgre_#{i};
152// Switch output //
153ulgre_#{i} -> GetIPAddress(16) -> arq_#{i} -> [#{i}]switch;
154"
155    i += 1
156  }
157
158end
159
160def KillProcess(proc)
161   pipe = IO.popen("pkill -9  #{proc}")
162   pipe.readlines.each { |line|
163   }
164end
165
166def RunClick(conf)
167  if $oClickThread and $oClickThread.alive? then 
168     puts "Killing click PID=#{$oClickThread.pid}"
169     Process.kill(9, $oClickThread.pid)
170     $oClickThread.kill
171  end
172  $oClickMonitor.kill if $oClickMonitor and $oClickMonitor.alive?
173
174  stdin,stdout,stderr = '','',''
175  $oClickThread = Open4::bg("#{$sClick} #{conf}",0=>stdin, 1=>stdout, 2=>stderr)
176  puts "Started click PID=#{$oClickThread.pid}"
177  $oClickMoitor = Thread.new {
178    loop {
179      puts stderr unless stderr.gets.nil?
180      puts stdout unless stdout.gets.nil?
181      sleep(1)
182    }
183  }
184end
185
186def RestartClick()
187  if File.exist?($sClickConf+".bak") then File.delete($sClickConf+".bak") end
188  if File.exist?($sClickConf) then File.rename($sClickConf,$sClickConf+".bak") end
189  open($sClickConf, 'w') { |f| CreateClickConfiguration(f,$hClients); f.close }
190  RunClick($sClickConf) 
191end
192
193def AsngwRcvr
194  # Connect to the ASN daemon
195  r = UDPSocket.open
196  r.bind(0, $dRcvPort)
197
198  loop { 
199    line = r.recvfrom(100)[0]    # Read line from the ASN
200    args = line.split(' ')
201    case args[0]
202      when /^MS_REG/ then
203        AddClient(args[1])                                      # Nee client
204        UDPSocket.open.send("ALLOW", 0, $sHostname, $dSndPort)  # Accept it unconditionaly
205        puts "Added client: "+args[1]
206      when /^MS_DEL/ then
207        delGRE(args[1],args[2],args[3])
208        puts "Del GRE "+args[1]+" "+args[2]+" "+args[3]
209      when /^MS_GRE/ then
210        addGRE(args[1],args[2],args[3])
211        puts "Add GRE "+args[1]+" "+args[2]+" "+args[3]
212        if args[2] == "2" then RestartClick() end
213      else puts "Unknown command: "+line
214    end 
215 }
216end
217
218## do we have anything stored?
219#if File.exist?($sClientStore) then
220#  # if we do load the state
221#  $hClients = open($sClientStore) { |f| YAML.load(f) }
222#else
223#  # otherwise initialise the hash
224#  $hClients = OrderedHash.new
225#  # and persistant storage
226#  open($sClientStore, 'w') { |f| YAML.dump($hClients, f) }
227#end
228
229KillProcess("click")
230
231$hClients  = OrderedHash.new
232$oClickThread = nil
233$oClickMonitor = nil
234
235$hGREs = {}
236# Lets check if there are tunnels already up
237ifc = IO.popen("/sbin/ifconfig -a | grep gre")
238ifc.each {  |gre| 
239  $hGREs[gre.scan(/greAnc_\d+/)[0]] = 1 
240}
241# now let's find mobiles that are assigned to these
242if !($hGREs.empty?)
243  File.open("/etc/asnctrl_gre.conf").each { | line|
244    mac,dir,tunnel,des = line.split(" ")
245    next if !($hGREs.has_key?(mac))
246    AddGre(mac,dir,tunnel)
247  }
248end
249RestartClick()
250AsngwRcvr()
251
252 
253
254
255
Note: See TracBrowser for help on using the browser.