mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 13:46:44 -04:00
Update network configuration to work with Linksys WRT1900ACS and Cisco Catalyst 3560G.
This commit is contained in:
113
access_point_config.go
Normal file
113
access_point_config.go
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright 2017 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Methods for configuring a Linksys WRT1900ACS access point running OpenWRT for team SSIDs and VLANs.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"os"
|
||||
"sync"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var accessPointSshPort = 22
|
||||
|
||||
const (
|
||||
red1Vlan = 10
|
||||
red2Vlan = 20
|
||||
red3Vlan = 30
|
||||
blue1Vlan = 40
|
||||
blue2Vlan = 50
|
||||
blue3Vlan = 60
|
||||
)
|
||||
|
||||
var accessPointMutex sync.Mutex
|
||||
|
||||
// Sets up wireless networks for the given set of teams.
|
||||
func ConfigureTeamWifi(red1, red2, red3, blue1, blue2, blue3 *Team) error {
|
||||
// Make sure multiple configurations aren't being set at the same time.
|
||||
accessPointMutex.Lock()
|
||||
defer accessPointMutex.Unlock()
|
||||
|
||||
config, err := generateAccessPointConfig(red1, red2, red3, blue1, blue2, blue3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
command := fmt.Sprintf("cat <<ENDCONFIG > /etc/config/wireless && wifi radio0\n%sENDCONFIG\n", config)
|
||||
return runAccessPointCommand(command)
|
||||
}
|
||||
|
||||
func generateAccessPointConfig(red1, red2, red3, blue1, blue2, blue3 *Team) (string, error) {
|
||||
// Determine what new SSIDs are needed.
|
||||
networks := make(map[int]*Team)
|
||||
var err error
|
||||
if err = addTeamNetwork(networks, red1, red1Vlan); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err = addTeamNetwork(networks, red2, red2Vlan); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err = addTeamNetwork(networks, red3, red3Vlan); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err = addTeamNetwork(networks, blue1, blue1Vlan); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err = addTeamNetwork(networks, blue2, blue2Vlan); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err = addTeamNetwork(networks, blue3, blue3Vlan); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Generate the config file to be uploaded to the AP.
|
||||
template, err := template.ParseFiles("templates/access_point.cfg")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var configFile bytes.Buffer
|
||||
err = template.Execute(&configFile, networks)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return configFile.String(), nil
|
||||
}
|
||||
|
||||
// Verifies the validity of the given team's WPA key and adds a network for it to the list to be configured.
|
||||
func addTeamNetwork(networks map[int]*Team, team *Team, vlan int) error {
|
||||
if team == nil {
|
||||
return nil
|
||||
}
|
||||
if len(team.WpaKey) < 8 || len(team.WpaKey) > 63 {
|
||||
return fmt.Errorf("Invalid WPA key '%s' configured for team %d.", team.WpaKey, team.Id)
|
||||
}
|
||||
networks[vlan] = team
|
||||
return nil
|
||||
}
|
||||
|
||||
// Logs into the access point via SSH and runs the given shell command.
|
||||
func runAccessPointCommand(command string) error {
|
||||
// Open an SSH connection to the AP.
|
||||
config := &ssh.ClientConfig{User: eventSettings.ApUsername,
|
||||
Auth: []ssh.AuthMethod{ssh.Password(eventSettings.ApPassword)},
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey()}
|
||||
conn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", eventSettings.ApAddress, accessPointSshPort), config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
session, err := conn.NewSession()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer session.Close()
|
||||
defer conn.Close()
|
||||
session.Stdout = os.Stdout
|
||||
|
||||
// Run the command. An error will be returned if the exit status is non-zero.
|
||||
return session.Run(command)
|
||||
}
|
||||
BIN
access_point_config.tar.gz
Normal file
BIN
access_point_config.tar.gz
Normal file
Binary file not shown.
80
access_point_config_test.go
Normal file
80
access_point_config_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"regexp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfigureAccessPoint(t *testing.T) {
|
||||
radioRe := regexp.MustCompile("option device 'radio0'")
|
||||
ssidRe := regexp.MustCompile("option ssid '([-\\w ]+)'")
|
||||
wpaKeyRe := regexp.MustCompile("option key '([-\\w ]+)'")
|
||||
vlanRe := regexp.MustCompile("option network 'vlan(\\d+)'")
|
||||
|
||||
// Should not configure any team SSIDs if there are no teams.
|
||||
config, _ := generateAccessPointConfig(nil, nil, nil, nil, nil, nil)
|
||||
assert.NotContains(t, config, "option device 'radio0'")
|
||||
ssids := ssidRe.FindAllStringSubmatch(config, -1)
|
||||
wpaKeys := wpaKeyRe.FindAllStringSubmatch(config, -1)
|
||||
vlans := vlanRe.FindAllStringSubmatch(config, -1)
|
||||
assert.Equal(t, "Cheesy Arena", ssids[0][1])
|
||||
assert.Equal(t, "1234Five", wpaKeys[0][1])
|
||||
assert.Equal(t, "100", vlans[0][1])
|
||||
|
||||
// Should configure two SSID for two teams.
|
||||
config, _ = generateAccessPointConfig(&Team{Id: 254, WpaKey: "aaaaaaaa"}, nil, nil, nil, nil,
|
||||
&Team{Id: 1114, WpaKey: "bbbbbbbb"})
|
||||
assert.Equal(t, 2, len(radioRe.FindAllString(config, -1)))
|
||||
ssids = ssidRe.FindAllStringSubmatch(config, -1)
|
||||
wpaKeys = wpaKeyRe.FindAllStringSubmatch(config, -1)
|
||||
vlans = vlanRe.FindAllStringSubmatch(config, -1)
|
||||
assert.Equal(t, "Cheesy Arena", ssids[0][1])
|
||||
assert.Equal(t, "1234Five", wpaKeys[0][1])
|
||||
assert.Equal(t, "100", vlans[0][1])
|
||||
assert.Equal(t, "254", ssids[1][1])
|
||||
assert.Equal(t, "aaaaaaaa", wpaKeys[1][1])
|
||||
assert.Equal(t, "10", vlans[1][1])
|
||||
assert.Equal(t, "1114", ssids[2][1])
|
||||
assert.Equal(t, "bbbbbbbb", wpaKeys[2][1])
|
||||
assert.Equal(t, "60", vlans[2][1])
|
||||
|
||||
// Should configure all SSIDs for six teams.
|
||||
config, _ = generateAccessPointConfig(&Team{Id: 1, WpaKey: "11111111"},
|
||||
&Team{Id: 2, WpaKey: "22222222"}, &Team{Id: 3, WpaKey: "33333333"}, &Team{Id: 4, WpaKey: "44444444"},
|
||||
&Team{Id: 5, WpaKey: "55555555"}, &Team{Id: 6, WpaKey: "66666666"})
|
||||
assert.Equal(t, 6, len(radioRe.FindAllString(config, -1)))
|
||||
ssids = ssidRe.FindAllStringSubmatch(config, -1)
|
||||
wpaKeys = wpaKeyRe.FindAllStringSubmatch(config, -1)
|
||||
vlans = vlanRe.FindAllStringSubmatch(config, -1)
|
||||
assert.Equal(t, "Cheesy Arena", ssids[0][1])
|
||||
assert.Equal(t, "1234Five", wpaKeys[0][1])
|
||||
assert.Equal(t, "100", vlans[0][1])
|
||||
assert.Equal(t, "1", ssids[1][1])
|
||||
assert.Equal(t, "11111111", wpaKeys[1][1])
|
||||
assert.Equal(t, "10", vlans[1][1])
|
||||
assert.Equal(t, "2", ssids[2][1])
|
||||
assert.Equal(t, "22222222", wpaKeys[2][1])
|
||||
assert.Equal(t, "20", vlans[2][1])
|
||||
assert.Equal(t, "3", ssids[3][1])
|
||||
assert.Equal(t, "33333333", wpaKeys[3][1])
|
||||
assert.Equal(t, "30", vlans[3][1])
|
||||
assert.Equal(t, "4", ssids[4][1])
|
||||
assert.Equal(t, "44444444", wpaKeys[4][1])
|
||||
assert.Equal(t, "40", vlans[4][1])
|
||||
assert.Equal(t, "5", ssids[5][1])
|
||||
assert.Equal(t, "55555555", wpaKeys[5][1])
|
||||
assert.Equal(t, "50", vlans[5][1])
|
||||
assert.Equal(t, "6", ssids[6][1])
|
||||
assert.Equal(t, "66666666", wpaKeys[6][1])
|
||||
assert.Equal(t, "60", vlans[6][1])
|
||||
|
||||
// Should reject a missing WPA key.
|
||||
_, err := generateAccessPointConfig(&Team{Id: 254}, nil, nil, nil, nil, nil)
|
||||
if assert.NotNil(t, err) {
|
||||
assert.Contains(t, err.Error(), "Invalid WPA key")
|
||||
}
|
||||
}
|
||||
151
aironet.go
151
aironet.go
@@ -1,151 +0,0 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Methods for configuring a Cisco Aironet AP1252AG access point for team SSIDs and VLANs.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var aironetTelnetPort = 23
|
||||
|
||||
const (
|
||||
red1Vlan = 11
|
||||
red2Vlan = 12
|
||||
red3Vlan = 13
|
||||
blue1Vlan = 14
|
||||
blue2Vlan = 15
|
||||
blue3Vlan = 16
|
||||
)
|
||||
|
||||
var aironetMutex sync.Mutex
|
||||
|
||||
// Sets up wireless networks for the given set of teams.
|
||||
func ConfigureTeamWifi(red1, red2, red3, blue1, blue2, blue3 *Team) error {
|
||||
// Make sure multiple configurations aren't being set at the same time.
|
||||
aironetMutex.Lock()
|
||||
defer aironetMutex.Unlock()
|
||||
|
||||
for _, team := range []*Team{red1, red2, red3, blue1, blue2, blue3} {
|
||||
if team != nil && (len(team.WpaKey) < 8 || len(team.WpaKey) > 63) {
|
||||
return fmt.Errorf("Invalid WPA key '%s' configured for team %d.", team.WpaKey, team.Id)
|
||||
}
|
||||
}
|
||||
|
||||
// Determine what new SSIDs are needed and build the commands to set them up.
|
||||
oldSsids, err := getSsids()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addSsidsCommand := ""
|
||||
associateSsidsCommand := ""
|
||||
replaceSsid := func(team *Team, vlan int) {
|
||||
if team == nil {
|
||||
return
|
||||
}
|
||||
if oldSsids[strconv.Itoa(team.Id)] == vlan {
|
||||
delete(oldSsids, strconv.Itoa(team.Id))
|
||||
} else {
|
||||
addSsidsCommand += fmt.Sprintf("dot11 ssid %d\nvlan %d\nauthentication open\nauthentication "+
|
||||
"key-management wpa version 2\nmbssid guest-mode\nwpa-psk ascii %s\n", team.Id, vlan, team.WpaKey)
|
||||
associateSsidsCommand += fmt.Sprintf("ssid %d\n", team.Id)
|
||||
}
|
||||
}
|
||||
replaceSsid(red1, red1Vlan)
|
||||
replaceSsid(red2, red2Vlan)
|
||||
replaceSsid(red3, red3Vlan)
|
||||
replaceSsid(blue1, blue1Vlan)
|
||||
replaceSsid(blue2, blue2Vlan)
|
||||
replaceSsid(blue3, blue3Vlan)
|
||||
if len(addSsidsCommand) != 0 {
|
||||
associateSsidsCommand = "interface Dot11Radio1\n" + associateSsidsCommand
|
||||
}
|
||||
|
||||
// Build the command to remove the SSIDs that are no longer needed.
|
||||
removeSsidsCommand := ""
|
||||
for ssid, _ := range oldSsids {
|
||||
removeSsidsCommand += fmt.Sprintf("no dot11 ssid %s\n", ssid)
|
||||
}
|
||||
|
||||
// Build and run the overall command to do everything in a single telnet session.
|
||||
command := removeSsidsCommand + addSsidsCommand + associateSsidsCommand
|
||||
if len(command) > 0 {
|
||||
_, err = runAironetConfigCommand(removeSsidsCommand + addSsidsCommand + associateSsidsCommand)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Returns a map of currently-configured SSIDs to VLANs.
|
||||
func getSsids() (map[string]int, error) {
|
||||
// Get the entire config dump.
|
||||
config, err := runAironetCommand("show running-config\n")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Parse out the SSIDs and VLANs from the config dump.
|
||||
re := regexp.MustCompile("(?s)dot11 ssid (\\w+)\\s+vlan (1[1-6])")
|
||||
ssidMatches := re.FindAllStringSubmatch(config, -1)
|
||||
if ssidMatches == nil {
|
||||
// There are probably no SSIDs currently configured.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Build the map of SSID to VLAN.
|
||||
ssids := make(map[string]int)
|
||||
for _, match := range ssidMatches {
|
||||
vlan, _ := strconv.Atoi(match[2])
|
||||
ssids[match[1]] = vlan
|
||||
}
|
||||
return ssids, nil
|
||||
}
|
||||
|
||||
// Logs into the Aironet via Telnet and runs the given command in user exec mode. Reads the output and returns
|
||||
// it as a string.
|
||||
func runAironetCommand(command string) (string, error) {
|
||||
// Open a Telnet connection to the AP.
|
||||
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", eventSettings.ApAddress, aironetTelnetPort))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Login to the AP, send the command, and log out all at once.
|
||||
writer := bufio.NewWriter(conn)
|
||||
_, err = writer.WriteString(fmt.Sprintf("%s\n%s\nterminal length 0\n%sexit\n", eventSettings.ApUsername,
|
||||
eventSettings.ApPassword, command))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = writer.Flush()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Read the response.
|
||||
var reader bytes.Buffer
|
||||
_, err = reader.ReadFrom(conn)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return reader.String(), nil
|
||||
}
|
||||
|
||||
// Logs into the Aironet via Telnet and runs the given command in global configuration mode. Reads the output
|
||||
// and returns it as a string.
|
||||
func runAironetConfigCommand(command string) (string, error) {
|
||||
return runAironetCommand(fmt.Sprintf("config terminal\n%send\ncopy running-config startup-config\n\n",
|
||||
command))
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestConfigureAironet(t *testing.T) {
|
||||
aironetTelnetPort = 9023
|
||||
eventSettings = &EventSettings{ApAddress: "127.0.0.1", ApUsername: "user", ApPassword: "password"}
|
||||
var command string
|
||||
|
||||
// Should do nothing if current configuration is blank.
|
||||
mockTelnet(t, aironetTelnetPort, "", &command)
|
||||
assert.Nil(t, ConfigureTeamWifi(nil, nil, nil, nil, nil, nil))
|
||||
assert.Equal(t, "", command)
|
||||
|
||||
// Should remove any existing teams but not other SSIDs.
|
||||
aironetTelnetPort += 1
|
||||
mockTelnet(t, aironetTelnetPort,
|
||||
"dot11 ssid 1\nvlan 1\ndot11 ssid 254\nvlan 12\ndot11 ssid Cheesy Arena\nvlan 17\n", &command)
|
||||
assert.Nil(t, ConfigureTeamWifi(nil, nil, nil, nil, nil, nil))
|
||||
assert.Equal(t, "user\npassword\nterminal length 0\nconfig terminal\nno dot11 ssid 254\nend\n"+
|
||||
"copy running-config startup-config\n\nexit\n", command)
|
||||
|
||||
// Should configure new teams and leave existing ones alone if still needed.
|
||||
aironetTelnetPort += 1
|
||||
mockTelnet(t, aironetTelnetPort, "dot11 ssid 254\nvlan 11\n", &command)
|
||||
assert.Nil(t, ConfigureTeamWifi(&Team{Id: 254, WpaKey: "aaaaaaaa"}, nil, nil, nil, nil,
|
||||
&Team{Id: 1114, WpaKey: "bbbbbbbb"}))
|
||||
assert.Equal(t, "user\npassword\nterminal length 0\nconfig terminal\ndot11 ssid 1114\nvlan 16\n"+
|
||||
"authentication open\nauthentication key-management wpa version 2\nmbssid guest-mode\nwpa-psk ascii "+
|
||||
"bbbbbbbb\ninterface Dot11Radio1\nssid 1114\nend\ncopy running-config startup-config\n\nexit\n",
|
||||
command)
|
||||
|
||||
// Should reject a missing WPA key.
|
||||
aironetTelnetPort += 1
|
||||
mockTelnet(t, aironetTelnetPort, "", &command)
|
||||
err := ConfigureTeamWifi(&Team{Id: 254}, nil, nil, nil, nil, nil)
|
||||
if assert.NotNil(t, err) {
|
||||
assert.Contains(t, err.Error(), "Invalid WPA key")
|
||||
}
|
||||
}
|
||||
|
||||
func mockTelnet(t *testing.T, port int, response string, command *string) {
|
||||
go func() {
|
||||
// Fake the first connection which should just get the configuration.
|
||||
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
assert.Nil(t, err)
|
||||
defer ln.Close()
|
||||
conn, err := ln.Accept()
|
||||
assert.Nil(t, err)
|
||||
conn.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
|
||||
var reader bytes.Buffer
|
||||
reader.ReadFrom(conn)
|
||||
assert.Contains(t, reader.String(), "terminal length 0\nshow running-config\nexit\n")
|
||||
conn.Write([]byte(response))
|
||||
conn.Close()
|
||||
|
||||
// Fake the second connection which should configure stuff.
|
||||
conn2, err := ln.Accept()
|
||||
assert.Nil(t, err)
|
||||
conn2.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
|
||||
var reader2 bytes.Buffer
|
||||
reader2.ReadFrom(conn2)
|
||||
*command = reader2.String()
|
||||
conn2.Close()
|
||||
}()
|
||||
time.Sleep(100 * time.Millisecond) // Give it some time to open the socket.
|
||||
}
|
||||
316
ap_config.txt
316
ap_config.txt
@@ -1,316 +0,0 @@
|
||||
! Baseline configuration for the Cisco Aironet AP1252AG access point. Load this into the AP prior to
|
||||
! configuring Cheesy Arena to connect to it. Default user/pass is cheesyarena/1234Five.
|
||||
!
|
||||
version 15.2
|
||||
no service pad
|
||||
service timestamps debug datetime msec
|
||||
service timestamps log datetime msec
|
||||
service password-encryption
|
||||
!
|
||||
hostname ChezyAP
|
||||
!
|
||||
logging rate-limit console 9
|
||||
!
|
||||
aaa new-model
|
||||
!
|
||||
!
|
||||
aaa authentication login default local
|
||||
aaa authorization exec default local
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
aaa session-id common
|
||||
!
|
||||
!
|
||||
dot11 syslog
|
||||
dot11 vlan-name Blue1 vlan 14
|
||||
dot11 vlan-name Blue2 vlan 15
|
||||
dot11 vlan-name Blue3 vlan 16
|
||||
dot11 vlan-name CheesyArena vlan 2
|
||||
dot11 vlan-name Red1 vlan 11
|
||||
dot11 vlan-name Red2 vlan 12
|
||||
dot11 vlan-name Red3 vlan 13
|
||||
!
|
||||
dot11 ssid 1
|
||||
vlan 11
|
||||
authentication open
|
||||
authentication key-management wpa version 2
|
||||
mbssid guest-mode
|
||||
wpa-psk ascii 7 0257550A5A575E701D
|
||||
!
|
||||
dot11 ssid 2
|
||||
vlan 12
|
||||
authentication open
|
||||
authentication key-management wpa version 2
|
||||
mbssid guest-mode
|
||||
wpa-psk ascii 7 06545D731E1C5B4B57
|
||||
!
|
||||
dot11 ssid 3
|
||||
vlan 13
|
||||
authentication open
|
||||
authentication key-management wpa version 2
|
||||
mbssid guest-mode
|
||||
wpa-psk ascii 7 115A4A564441585F57
|
||||
!
|
||||
dot11 ssid 4
|
||||
vlan 14
|
||||
authentication open
|
||||
authentication key-management wpa version 2
|
||||
mbssid guest-mode
|
||||
wpa-psk ascii 7 101A5D4D5143465F58
|
||||
!
|
||||
dot11 ssid 5
|
||||
vlan 15
|
||||
authentication open
|
||||
authentication key-management wpa version 2
|
||||
mbssid guest-mode
|
||||
wpa-psk ascii 7 00514653510E5E535A
|
||||
!
|
||||
dot11 ssid 6
|
||||
vlan 16
|
||||
authentication open
|
||||
authentication key-management wpa version 2
|
||||
mbssid guest-mode
|
||||
wpa-psk ascii 7 1441445D5A527C7D72
|
||||
!
|
||||
dot11 ssid Cheesy Arena
|
||||
vlan 2
|
||||
authentication open
|
||||
authentication key-management wpa version 2
|
||||
guest-mode
|
||||
wpa-psk ascii 7 144640585822233D21
|
||||
!
|
||||
crypto pki token default removal timeout 0
|
||||
!
|
||||
!
|
||||
username cheesyarena privilege 15 password 7 040A59555B0745580C
|
||||
!
|
||||
!
|
||||
bridge irb
|
||||
!
|
||||
!
|
||||
interface Dot11Radio0
|
||||
no ip address
|
||||
no ip route-cache
|
||||
!
|
||||
encryption mode ciphers aes-ccm tkip
|
||||
!
|
||||
encryption vlan 2 mode ciphers aes-ccm tkip
|
||||
!
|
||||
ssid Cheesy Arena
|
||||
!
|
||||
antenna gain 0
|
||||
station-role root
|
||||
no dot11 extension aironet
|
||||
bridge-group 1
|
||||
bridge-group 1 subscriber-loop-control
|
||||
bridge-group 1 spanning-disabled
|
||||
bridge-group 1 block-unknown-source
|
||||
no bridge-group 1 source-learning
|
||||
no bridge-group 1 unicast-flooding
|
||||
!
|
||||
interface Dot11Radio0.2
|
||||
encapsulation dot1Q 2
|
||||
no ip route-cache
|
||||
bridge-group 2
|
||||
bridge-group 2 subscriber-loop-control
|
||||
bridge-group 2 spanning-disabled
|
||||
bridge-group 2 block-unknown-source
|
||||
no bridge-group 2 source-learning
|
||||
no bridge-group 2 unicast-flooding
|
||||
!
|
||||
interface Dot11Radio1
|
||||
no ip address
|
||||
no ip route-cache
|
||||
!
|
||||
encryption mode ciphers aes-ccm tkip
|
||||
!
|
||||
encryption vlan 11 mode ciphers aes-ccm tkip
|
||||
!
|
||||
encryption vlan 12 mode ciphers aes-ccm tkip
|
||||
!
|
||||
encryption vlan 13 mode ciphers aes-ccm tkip
|
||||
!
|
||||
encryption vlan 14 mode ciphers aes-ccm tkip
|
||||
!
|
||||
encryption vlan 15 mode ciphers aes-ccm tkip
|
||||
!
|
||||
encryption vlan 16 mode ciphers aes-ccm tkip
|
||||
!
|
||||
ssid 1
|
||||
!
|
||||
ssid 2
|
||||
!
|
||||
ssid 3
|
||||
!
|
||||
ssid 4
|
||||
!
|
||||
ssid 5
|
||||
!
|
||||
ssid 6
|
||||
!
|
||||
antenna gain 0
|
||||
dfs band 3 block
|
||||
mbssid
|
||||
channel width 40-above
|
||||
channel dfs
|
||||
station-role root
|
||||
no dot11 extension aironet
|
||||
bridge-group 1
|
||||
bridge-group 1 subscriber-loop-control
|
||||
bridge-group 1 spanning-disabled
|
||||
bridge-group 1 block-unknown-source
|
||||
no bridge-group 1 source-learning
|
||||
no bridge-group 1 unicast-flooding
|
||||
!
|
||||
interface Dot11Radio1.11
|
||||
encapsulation dot1Q 11
|
||||
no ip route-cache
|
||||
bridge-group 11
|
||||
bridge-group 11 subscriber-loop-control
|
||||
bridge-group 11 spanning-disabled
|
||||
bridge-group 11 block-unknown-source
|
||||
no bridge-group 11 source-learning
|
||||
no bridge-group 11 unicast-flooding
|
||||
!
|
||||
interface Dot11Radio1.12
|
||||
encapsulation dot1Q 12
|
||||
no ip route-cache
|
||||
bridge-group 12
|
||||
bridge-group 12 subscriber-loop-control
|
||||
bridge-group 12 spanning-disabled
|
||||
bridge-group 12 block-unknown-source
|
||||
no bridge-group 12 source-learning
|
||||
no bridge-group 12 unicast-flooding
|
||||
!
|
||||
interface Dot11Radio1.13
|
||||
encapsulation dot1Q 13
|
||||
no ip route-cache
|
||||
bridge-group 13
|
||||
bridge-group 13 subscriber-loop-control
|
||||
bridge-group 13 spanning-disabled
|
||||
bridge-group 13 block-unknown-source
|
||||
no bridge-group 13 source-learning
|
||||
no bridge-group 13 unicast-flooding
|
||||
!
|
||||
interface Dot11Radio1.14
|
||||
encapsulation dot1Q 14
|
||||
no ip route-cache
|
||||
bridge-group 14
|
||||
bridge-group 14 subscriber-loop-control
|
||||
bridge-group 14 spanning-disabled
|
||||
bridge-group 14 block-unknown-source
|
||||
no bridge-group 14 source-learning
|
||||
no bridge-group 14 unicast-flooding
|
||||
!
|
||||
interface Dot11Radio1.15
|
||||
encapsulation dot1Q 15
|
||||
no ip route-cache
|
||||
bridge-group 15
|
||||
bridge-group 15 subscriber-loop-control
|
||||
bridge-group 15 spanning-disabled
|
||||
bridge-group 15 block-unknown-source
|
||||
no bridge-group 15 source-learning
|
||||
no bridge-group 15 unicast-flooding
|
||||
!
|
||||
interface Dot11Radio1.16
|
||||
encapsulation dot1Q 16
|
||||
no ip route-cache
|
||||
bridge-group 16
|
||||
bridge-group 16 subscriber-loop-control
|
||||
bridge-group 16 spanning-disabled
|
||||
bridge-group 16 block-unknown-source
|
||||
no bridge-group 16 source-learning
|
||||
no bridge-group 16 unicast-flooding
|
||||
!
|
||||
interface GigabitEthernet0
|
||||
no ip address
|
||||
no ip route-cache
|
||||
duplex auto
|
||||
speed auto
|
||||
bridge-group 1
|
||||
bridge-group 1 spanning-disabled
|
||||
no bridge-group 1 source-learning
|
||||
!
|
||||
interface GigabitEthernet0.2
|
||||
encapsulation dot1Q 2
|
||||
no ip route-cache
|
||||
bridge-group 2
|
||||
bridge-group 2 spanning-disabled
|
||||
no bridge-group 2 source-learning
|
||||
!
|
||||
interface GigabitEthernet0.11
|
||||
encapsulation dot1Q 11
|
||||
ip access-group 100 in
|
||||
no ip route-cache
|
||||
bridge-group 11
|
||||
bridge-group 11 spanning-disabled
|
||||
no bridge-group 11 source-learning
|
||||
!
|
||||
interface GigabitEthernet0.12
|
||||
encapsulation dot1Q 12
|
||||
ip access-group 100 in
|
||||
no ip route-cache
|
||||
bridge-group 12
|
||||
bridge-group 12 spanning-disabled
|
||||
no bridge-group 12 source-learning
|
||||
!
|
||||
interface GigabitEthernet0.13
|
||||
encapsulation dot1Q 13
|
||||
ip access-group 100 in
|
||||
no ip route-cache
|
||||
bridge-group 13
|
||||
bridge-group 13 spanning-disabled
|
||||
no bridge-group 13 source-learning
|
||||
!
|
||||
interface GigabitEthernet0.14
|
||||
encapsulation dot1Q 14
|
||||
ip access-group 100 in
|
||||
no ip route-cache
|
||||
bridge-group 14
|
||||
bridge-group 14 spanning-disabled
|
||||
no bridge-group 14 source-learning
|
||||
!
|
||||
interface GigabitEthernet0.15
|
||||
encapsulation dot1Q 15
|
||||
ip access-group 100 in
|
||||
no ip route-cache
|
||||
bridge-group 15
|
||||
bridge-group 15 spanning-disabled
|
||||
no bridge-group 15 source-learning
|
||||
!
|
||||
interface GigabitEthernet0.16
|
||||
encapsulation dot1Q 16
|
||||
ip access-group 100 in
|
||||
ip access-group 101 out
|
||||
no ip route-cache
|
||||
bridge-group 16
|
||||
bridge-group 16 spanning-disabled
|
||||
no bridge-group 16 source-learning
|
||||
!
|
||||
interface BVI1
|
||||
ip address 10.0.0.60 255.0.0.0
|
||||
no ip route-cache
|
||||
!
|
||||
ip default-gateway 10.0.0.1
|
||||
ip http server
|
||||
ip http authentication aaa
|
||||
no ip http secure-server
|
||||
ip http help-path http://www.cisco.com/warp/public/779/smbiz/prodconfig/help/eag
|
||||
access-list 100 deny udp any any eq 1120
|
||||
access-list 100 permit ip any any
|
||||
access-list 101 deny tcp any any eq 1750
|
||||
access-list 101 permit ip any any
|
||||
!
|
||||
bridge 1 route ip
|
||||
!
|
||||
!
|
||||
!
|
||||
line con 0
|
||||
line vty 0 4
|
||||
transport input all
|
||||
!
|
||||
sntp server 216.66.0.142
|
||||
end
|
||||
@@ -495,8 +495,8 @@ func TestSetupNetwork(t *testing.T) {
|
||||
|
||||
// Verify the setup ran by checking the log for the expected failure messages.
|
||||
eventSettings.NetworkSecurityEnabled = true
|
||||
aironetTelnetPort = 10023
|
||||
catalystTelnetPort = 10023
|
||||
accessPointSshPort = 10022
|
||||
switchTelnetPort = 10023
|
||||
mainArena.LoadMatch(&Match{Type: "test"})
|
||||
var writer bytes.Buffer
|
||||
log.SetOutput(&writer)
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfigureCatalyst(t *testing.T) {
|
||||
catalystTelnetPort = 9050
|
||||
eventSettings = &EventSettings{SwitchAddress: "127.0.0.1", SwitchPassword: "password"}
|
||||
var command string
|
||||
|
||||
// Should do nothing if current configuration is blank.
|
||||
mockTelnet(t, catalystTelnetPort, "", &command)
|
||||
assert.Nil(t, ConfigureTeamEthernet(nil, nil, nil, nil, nil, nil))
|
||||
assert.Equal(t, "", command)
|
||||
|
||||
// Should remove any existing teams but not other SSIDs.
|
||||
catalystTelnetPort += 1
|
||||
mockTelnet(t, catalystTelnetPort,
|
||||
"interface Vlan2\nip address 10.0.100.2\ninterface Vlan15\nip address 10.2.54.61\n", &command)
|
||||
assert.Nil(t, ConfigureTeamEthernet(nil, nil, nil, nil, nil, nil))
|
||||
assert.Equal(t, "password\nenable\npassword\nterminal length 0\nconfig terminal\ninterface Vlan15\nno ip"+
|
||||
" address\nno access-list 115\nend\ncopy running-config startup-config\n\nexit\n", command)
|
||||
|
||||
// Should configure new teams and leave existing ones alone if still needed.
|
||||
catalystTelnetPort += 1
|
||||
mockTelnet(t, catalystTelnetPort, "interface Vlan15\nip address 10.2.54.61\n", &command)
|
||||
assert.Nil(t, ConfigureTeamEthernet(nil, &Team{Id: 1114}, nil, nil, &Team{Id: 254}, nil))
|
||||
assert.Equal(t, "password\nenable\npassword\nterminal length 0\nconfig terminal\n"+
|
||||
"ip dhcp excluded-address 10.11.14.1 10.11.14.100\nno ip dhcp pool dhcp12\nip dhcp pool dhcp12\n"+
|
||||
"network 10.11.14.0 255.255.255.0\ndefault-router 10.11.14.61\nlease 7\nno access-list 112\n"+
|
||||
"access-list 112 permit ip 10.11.14.0 0.0.0.255 host 10.0.100.5\n"+
|
||||
"access-list 112 permit udp any eq bootpc any eq bootps\ninterface Vlan12\n"+
|
||||
"ip address 10.11.14.61 255.255.255.0\nend\ncopy running-config startup-config\n\nexit\n", command)
|
||||
}
|
||||
@@ -154,10 +154,12 @@ func TestListenForDriverStations(t *testing.T) {
|
||||
defer db.Close()
|
||||
eventSettings, _ = db.GetEventSettings()
|
||||
|
||||
oldAddress := driverStationTcpListenAddress
|
||||
driverStationTcpListenAddress = "127.0.0.1"
|
||||
go ListenForDriverStations()
|
||||
mainArena.Setup()
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
driverStationTcpListenAddress = oldAddress // Put it back to avoid affecting other tests.
|
||||
|
||||
// Connect with an invalid initial packet.
|
||||
tcpConn, err := net.Dial("tcp", "127.0.0.1:1750")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Methods for configuring a Cisco Catalyst 3750 switch for team VLANs.
|
||||
// Methods for configuring a Cisco Switch 3500-series switch for team VLANs.
|
||||
|
||||
package main
|
||||
|
||||
@@ -15,15 +15,15 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var catalystTelnetPort = 23
|
||||
var switchTelnetPort = 23
|
||||
|
||||
var catalystMutex sync.Mutex
|
||||
var switchMutex sync.Mutex
|
||||
|
||||
// Sets up wired networks for the given set of teams.
|
||||
func ConfigureTeamEthernet(red1, red2, red3, blue1, blue2, blue3 *Team) error {
|
||||
// Make sure multiple configurations aren't being set at the same time.
|
||||
catalystMutex.Lock()
|
||||
defer catalystMutex.Unlock()
|
||||
switchMutex.Lock()
|
||||
defer switchMutex.Unlock()
|
||||
|
||||
// Determine what new team VLANs are needed and build the commands to set them up.
|
||||
oldTeamVlans, err := getTeamVlans()
|
||||
@@ -70,7 +70,7 @@ func ConfigureTeamEthernet(red1, red2, red3, blue1, blue2, blue3 *Team) error {
|
||||
// Build and run the overall command to do everything in a single telnet session.
|
||||
command := removeTeamVlansCommand + addTeamVlansCommand
|
||||
if len(command) > 0 {
|
||||
_, err = runCatalystConfigCommand(removeTeamVlansCommand + addTeamVlansCommand)
|
||||
_, err = runSwitchConfigCommand(removeTeamVlansCommand + addTeamVlansCommand)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -82,7 +82,7 @@ func ConfigureTeamEthernet(red1, red2, red3, blue1, blue2, blue3 *Team) error {
|
||||
// Returns a map of currently-configured teams to VLANs.
|
||||
func getTeamVlans() (map[int]int, error) {
|
||||
// Get the entire config dump.
|
||||
config, err := runCatalystCommand("show running-config\n")
|
||||
config, err := runSwitchCommand("show running-config\n")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -107,11 +107,11 @@ func getTeamVlans() (map[int]int, error) {
|
||||
return teamVlans, nil
|
||||
}
|
||||
|
||||
// Logs into the Catalyst via Telnet and runs the given command in user exec mode. Reads the output and
|
||||
// Logs into the switch via Telnet and runs the given command in user exec mode. Reads the output and
|
||||
// returns it as a string.
|
||||
func runCatalystCommand(command string) (string, error) {
|
||||
func runSwitchCommand(command string) (string, error) {
|
||||
// Open a Telnet connection to the switch.
|
||||
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", eventSettings.SwitchAddress, catalystTelnetPort))
|
||||
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", eventSettings.SwitchAddress, switchTelnetPort))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -138,9 +138,9 @@ func runCatalystCommand(command string) (string, error) {
|
||||
return reader.String(), nil
|
||||
}
|
||||
|
||||
// Logs into the Catalyst via Telnet and runs the given command in global configuration mode. Reads the output
|
||||
// Logs into the switch via Telnet and runs the given command in global configuration mode. Reads the output
|
||||
// and returns it as a string.
|
||||
func runCatalystConfigCommand(command string) (string, error) {
|
||||
return runCatalystCommand(fmt.Sprintf("config terminal\n%send\ncopy running-config startup-config\n\n",
|
||||
func runSwitchConfigCommand(command string) (string, error) {
|
||||
return runSwitchCommand(fmt.Sprintf("config terminal\n%send\ncopy running-config startup-config\n\n",
|
||||
command))
|
||||
}
|
||||
@@ -1,186 +1,299 @@
|
||||
! Baseline configuration for the Catalyst 3500-series switch. Load this into the switch prior to configuring
|
||||
! Cheesy Arena to connect to it. Default password is 1234Five.
|
||||
!
|
||||
version 12.1
|
||||
version 12.2
|
||||
no service pad
|
||||
service timestamps debug uptime
|
||||
service timestamps log uptime
|
||||
service timestamps debug datetime msec
|
||||
service timestamps log datetime msec
|
||||
no service password-encryption
|
||||
!
|
||||
hostname ChezySwitch
|
||||
!
|
||||
boot-start-marker
|
||||
boot-end-marker
|
||||
!
|
||||
enable secret 5 $1$kKSW$fCMwnMdYvXui1TulfyYHN/
|
||||
!
|
||||
ip subnet-zero
|
||||
!
|
||||
!
|
||||
no aaa new-model
|
||||
system mtu routing 1500
|
||||
ip routing
|
||||
ip dhcp excluded-address 10.0.100.1 10.0.100.100
|
||||
!
|
||||
ip dhcp pool dhcppool
|
||||
network 10.0.100.0 255.255.255.0
|
||||
default-router 10.0.100.1
|
||||
domain-name team254.com
|
||||
dns-server 8.8.8.8 8.8.4.4
|
||||
lease 7
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
spanning-tree mode pvst
|
||||
spanning-tree portfast default
|
||||
spanning-tree extend system-id
|
||||
!
|
||||
vlan internal allocation policy ascending
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
interface FastEthernet0/1
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/2
|
||||
switchport access vlan 11
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/3
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/4
|
||||
switchport access vlan 12
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/5
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/6
|
||||
switchport access vlan 13
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/7
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/8
|
||||
switchport access vlan 14
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/9
|
||||
switchport trunk encapsulation dot1q
|
||||
switchport mode trunk
|
||||
!
|
||||
interface FastEthernet0/10
|
||||
switchport access vlan 15
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/11
|
||||
switchport trunk encapsulation dot1q
|
||||
switchport mode trunk
|
||||
!
|
||||
interface FastEthernet0/12
|
||||
switchport access vlan 16
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/13
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/14
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/15
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/16
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/17
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/18
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/19
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/20
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/21
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/22
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/23
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface FastEthernet0/24
|
||||
switchport access vlan 2
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/1
|
||||
switchport trunk encapsulation dot1q
|
||||
switchport mode trunk
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/2
|
||||
switchport access vlan 2
|
||||
switchport trunk encapsulation dot1q
|
||||
switchport trunk native vlan 100
|
||||
switchport mode trunk
|
||||
!
|
||||
interface GigabitEthernet0/3
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/4
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/5
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/6
|
||||
switchport access vlan 10
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/7
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/8
|
||||
switchport access vlan 20
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/9
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/10
|
||||
switchport access vlan 30
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/11
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/12
|
||||
switchport access vlan 40
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/13
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/14
|
||||
switchport access vlan 50
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/15
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/16
|
||||
switchport access vlan 60
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/17
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/18
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/19
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/20
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/21
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/22
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/23
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/24
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/25
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/26
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/27
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/28
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/29
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/30
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/31
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/32
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/33
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/34
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/35
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/36
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/37
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/38
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/39
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/40
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/41
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/42
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/43
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/44
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/45
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/46
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/47
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/48
|
||||
switchport access vlan 100
|
||||
switchport mode access
|
||||
!
|
||||
interface GigabitEthernet0/49
|
||||
!
|
||||
interface GigabitEthernet0/50
|
||||
!
|
||||
interface GigabitEthernet0/51
|
||||
!
|
||||
interface GigabitEthernet0/52
|
||||
!
|
||||
interface Vlan1
|
||||
ip address 10.0.0.61 255.255.255.0
|
||||
!
|
||||
interface Vlan2
|
||||
interface Vlan10
|
||||
ip address 10.0.1.61 255.255.255.0
|
||||
ip access-group 110 in
|
||||
!
|
||||
interface Vlan20
|
||||
ip address 10.0.2.61 255.255.255.0
|
||||
ip access-group 120 in
|
||||
!
|
||||
interface Vlan30
|
||||
ip address 10.0.3.61 255.255.255.0
|
||||
ip access-group 130 in
|
||||
!
|
||||
interface Vlan40
|
||||
ip address 10.0.4.61 255.255.255.0
|
||||
ip access-group 140 in
|
||||
!
|
||||
interface Vlan50
|
||||
ip address 10.0.5.61 255.255.255.0
|
||||
ip access-group 150 in
|
||||
!
|
||||
interface Vlan60
|
||||
ip address 10.0.6.61 255.255.255.0
|
||||
ip access-group 160 in
|
||||
!
|
||||
interface Vlan100
|
||||
ip address 10.0.100.2 255.255.255.0
|
||||
!
|
||||
interface Vlan11
|
||||
ip address 10.0.1.61 255.255.255.0
|
||||
ip access-group 111 in
|
||||
!
|
||||
interface Vlan12
|
||||
ip address 10.0.2.61 255.255.255.0
|
||||
ip access-group 112 in
|
||||
!
|
||||
interface Vlan13
|
||||
ip address 10.0.3.61 255.255.255.0
|
||||
ip access-group 113 in
|
||||
!
|
||||
interface Vlan14
|
||||
ip address 10.0.4.61 255.255.255.0
|
||||
ip access-group 114 in
|
||||
!
|
||||
interface Vlan15
|
||||
ip address 10.0.5.61 255.255.255.0
|
||||
ip access-group 115 in
|
||||
!
|
||||
interface Vlan16
|
||||
ip address 10.0.6.61 255.255.255.0
|
||||
ip access-group 116 in
|
||||
!
|
||||
ip classless
|
||||
ip http server
|
||||
no ip http server
|
||||
no ip http secure-server
|
||||
!
|
||||
access-list 111 permit ip 10.0.1.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 111 permit udp any eq bootpc any eq bootps
|
||||
access-list 112 permit ip 10.0.2.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 112 permit udp any eq bootpc any eq bootps
|
||||
access-list 113 permit ip 10.0.3.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 113 permit udp any eq bootpc any eq bootps
|
||||
access-list 114 permit ip 10.0.4.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 114 permit udp any eq bootpc any eq bootps
|
||||
access-list 115 permit ip 10.0.5.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 115 permit udp any eq bootpc any eq bootps
|
||||
access-list 116 permit ip 10.0.6.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 116 permit udp any eq bootpc any eq bootps
|
||||
!
|
||||
access-list 110 permit ip 10.0.1.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 110 permit udp any eq bootpc any eq bootps
|
||||
access-list 120 permit ip 10.0.2.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 120 permit udp any eq bootpc any eq bootps
|
||||
access-list 130 permit ip 10.0.3.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 130 permit udp any eq bootpc any eq bootps
|
||||
access-list 140 permit ip 10.0.4.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 140 permit udp any eq bootpc any eq bootps
|
||||
access-list 150 permit ip 10.0.5.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 150 permit udp any eq bootpc any eq bootps
|
||||
access-list 160 permit ip 10.0.6.0 0.0.0.255 host 10.0.100.5
|
||||
access-list 160 permit udp any eq bootpc any eq bootps
|
||||
!
|
||||
snmp-server community 1234Five RO
|
||||
!
|
||||
!
|
||||
line con 0
|
||||
exec-timeout 0 0
|
||||
line vty 0 4
|
||||
@@ -190,5 +303,4 @@ line vty 5 15
|
||||
password 1234Five
|
||||
login
|
||||
!
|
||||
!
|
||||
end
|
||||
|
||||
70
switch_config_test.go
Normal file
70
switch_config_test.go
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestConfigureSwitch(t *testing.T) {
|
||||
switchTelnetPort = 9050
|
||||
eventSettings = &EventSettings{SwitchAddress: "127.0.0.1", SwitchPassword: "password"}
|
||||
var command string
|
||||
|
||||
// Should do nothing if current configuration is blank.
|
||||
mockTelnet(t, switchTelnetPort, "", &command)
|
||||
assert.Nil(t, ConfigureTeamEthernet(nil, nil, nil, nil, nil, nil))
|
||||
assert.Equal(t, "", command)
|
||||
|
||||
// Should remove any existing teams but not other SSIDs.
|
||||
switchTelnetPort += 1
|
||||
mockTelnet(t, switchTelnetPort,
|
||||
"interface Vlan100\nip address 10.0.100.2\ninterface Vlan50\nip address 10.2.54.61\n", &command)
|
||||
assert.Nil(t, ConfigureTeamEthernet(nil, nil, nil, nil, nil, nil))
|
||||
assert.Equal(t, "password\nenable\npassword\nterminal length 0\nconfig terminal\ninterface Vlan50\nno ip"+
|
||||
" address\nno access-list 150\nend\ncopy running-config startup-config\n\nexit\n", command)
|
||||
|
||||
// Should configure new teams and leave existing ones alone if still needed.
|
||||
switchTelnetPort += 1
|
||||
mockTelnet(t, switchTelnetPort, "interface Vlan50\nip address 10.2.54.61\n", &command)
|
||||
assert.Nil(t, ConfigureTeamEthernet(nil, &Team{Id: 1114}, nil, nil, &Team{Id: 254}, nil))
|
||||
assert.Equal(t, "password\nenable\npassword\nterminal length 0\nconfig terminal\n"+
|
||||
"ip dhcp excluded-address 10.11.14.1 10.11.14.100\nno ip dhcp pool dhcp20\nip dhcp pool dhcp20\n"+
|
||||
"network 10.11.14.0 255.255.255.0\ndefault-router 10.11.14.61\nlease 7\nno access-list 120\n"+
|
||||
"access-list 120 permit ip 10.11.14.0 0.0.0.255 host 10.0.100.5\n"+
|
||||
"access-list 120 permit udp any eq bootpc any eq bootps\ninterface Vlan20\n"+
|
||||
"ip address 10.11.14.61 255.255.255.0\nend\ncopy running-config startup-config\n\nexit\n", command)
|
||||
}
|
||||
|
||||
func mockTelnet(t *testing.T, port int, response string, command *string) {
|
||||
go func() {
|
||||
// Fake the first connection which should just get the configuration.
|
||||
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
assert.Nil(t, err)
|
||||
defer ln.Close()
|
||||
conn, err := ln.Accept()
|
||||
assert.Nil(t, err)
|
||||
conn.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
|
||||
var reader bytes.Buffer
|
||||
reader.ReadFrom(conn)
|
||||
assert.Contains(t, reader.String(), "terminal length 0\nshow running-config\nexit\n")
|
||||
conn.Write([]byte(response))
|
||||
conn.Close()
|
||||
|
||||
// Fake the second connection which should configure stuff.
|
||||
conn2, err := ln.Accept()
|
||||
assert.Nil(t, err)
|
||||
conn2.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
|
||||
var reader2 bytes.Buffer
|
||||
reader2.ReadFrom(conn2)
|
||||
*command = reader2.String()
|
||||
conn2.Close()
|
||||
}()
|
||||
time.Sleep(100 * time.Millisecond) // Give it some time to open the socket.
|
||||
}
|
||||
46
templates/access_point.cfg
Normal file
46
templates/access_point.cfg
Normal file
@@ -0,0 +1,46 @@
|
||||
config wifi-device 'radio1'
|
||||
option type 'mac80211'
|
||||
option channel '11'
|
||||
option hwmode '11g'
|
||||
option path 'soc/soc:pcie-controller/pci0000:00/0000:00:02.0/0000:02:00.0'
|
||||
option htmode 'HT20'
|
||||
option disabled '0'
|
||||
option txpower '20'
|
||||
option country 'US'
|
||||
|
||||
config wifi-iface
|
||||
option device 'radio1'
|
||||
option mode 'ap'
|
||||
option hidden '1'
|
||||
option encryption 'psk2+ccmp'
|
||||
option network 'vlan100'
|
||||
option ssid 'Cheesy Arena'
|
||||
option key '1234Five'
|
||||
option macaddr '62:38:e0:12:6b:17'
|
||||
|
||||
config wifi-device 'radio0'
|
||||
option type 'mac80211'
|
||||
option hwmode '11a'
|
||||
option path 'soc/soc:pcie-controller/pci0000:00/0000:00:01.0/0000:01:00.0'
|
||||
option txpower '23'
|
||||
option channel '157'
|
||||
option country 'US'
|
||||
option htmode 'HT20'
|
||||
option basic_rates '6500,7200'
|
||||
option short_gi_20 '0'
|
||||
|
||||
{{range $vlan, $team := .}}
|
||||
config wifi-iface
|
||||
option device 'radio0'
|
||||
option mode 'ap'
|
||||
option isolate '0'
|
||||
option bgscan '0'
|
||||
option wds '0'
|
||||
option maxassoc '1'
|
||||
option hidden '1'
|
||||
option network 'vlan{{$vlan}}'
|
||||
option encryption 'psk2+ccmp'
|
||||
option ssid '{{$team.Id}}'
|
||||
option key '{{$team.WpaKey}}'
|
||||
option disabled '0'
|
||||
{{end}}
|
||||
@@ -160,7 +160,7 @@
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Networking</legend>
|
||||
<p>Enable this setting if you have a Cisco Aironet AP1252AG access point and Catalyst 3500-series
|
||||
<p>Enable this setting if you have a Linksys WRT1900ACS access point and Catalyst 3500-series
|
||||
switch available, for isolating each team to its own SSID and VLAN.</p>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-7 control-label">Enable advanced network security</label>
|
||||
|
||||
Reference in New Issue
Block a user