Thursday, November 20, 2014

'Tis the Season: A highly unoptimized Secret Santa C++ Program!

Note: Since this program utilizes the stoi function, it must be run using a C++ 11 compiler Also, angle brackets got messed up in the formatting to post on html.. I've gotta do some digging to fix that -- I'm an html noob atm. 


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include <cmath>
#include <ctype.h>

using namespace std;

const int MAX = 50;

void get_names(string[], int&);
void print_hat(string[], int);
void secret_santa(int*, bool*, int);
void gift_to(string[], int, int*);
void print_ascii();

int main()
{
 string hat[MAX];
 string temp;
 int count = 0;
 string x;

 

 get_names(hat, count);
 print_ascii();

 if(count > 1)
 {
  print_hat(hat, count);
  cout << "Hit enter to begin sort!" << endl;
  getline(cin, x);

  int * givesTo = new int [count];    // recipient of gift
  for(int i = 0; i < count; i++)
   givesTo[i] = -1;

  bool * assigned = new bool [count];    // assigned: T or F
  for(int i = 0; i < count; i++)     // init to false
   assigned[i] = false;   

  print_ascii();
  secret_santa(givesTo, assigned, count);
  gift_to(hat, count, givesTo);
 }
 else
  cout << "There are not enough participants" << endl;

 return 0;
}

void get_names(string hat[], int &count)
{
 bool moreNames = true;
 string temp;

 // add names to hat
 while(moreNames)
 {

  print_ascii();
  print_ascii();

  // prompt for input 
  cout << "Enter your name to be put in the hat!" << endl;
  cout << "Or hit enter when you're done" << endl << endl;
  cout << "New Name: ";

  getline(cin, temp);

  // add to list and increment count
  if(!temp.empty())
  {
   hat[count] = temp;
   count++;
  }

  // finish adding to list
  else
  {
   moreNames = false;
   cout << endl;
  }
 }
}

void print_hat(string hat[], int count)
{
 // print numbers and corresponding participants
 cout << "Secret Santa Participants" << endl;
 for(int i = 0; i < count; i++)
  cout << i << ". " << hat[i] << endl;
}

void secret_santa(int * givesTo, bool * assigned, int count)
{
 int cnt = 0;

 print_ascii();

 // initialize srand to time (randomize)
 srand(time(NULL));

 // assign secret santas
 for(int i = 0; i < count; i++)
 {
  // do until assigned
  while(givesTo[i] == -1)
  {
   // redo if last participant has no suitor
   if((i == count-1) && assigned[i] == false)
   {
    //reinitialize arrays
    for(int j = 0; j < count; j++)
    {
     givesTo[j] = -1;
     assigned[j] = false;
    }

    // i will become 0 at the end
    i = -1;
   }

   // find someone to pair
   else
   {
    // find random number in range
    int temp = rand() % (count);

    // if number not itself and not already assigned
    if(temp != i && assigned[temp] == false)
    {
     // assign number
     givesTo[i] = temp;

     // mark number to not be used again
     assigned[temp] = true;
    } 
   }
  }
 }
}

void gift_to(string hat[], int count, int * givesTo)
{
 string temp;
 int num = -1;
 int assign;
 string again;
 bool exit = false;
 while(!exit)
 {
  print_ascii();
  print_ascii();  

  // prompt and print list
  cout << "Enter only your number to see who you got." << endl << endl;
  cout << "type 'exit' to complete. (Warning: results are lost after exit)" << endl;
  print_hat(hat, count);
  cout << endl << "Number: ";
  getline(cin, temp);

  // if enter with no input, do nothing  
  if(!temp.empty())
  {
   // verify all digits  
   if(isdigit(temp[0]))
    num = stoi(temp);
   
   // exit program
   if(temp == "exit")
    exit = true;
   
   // if num is out of range
   else if(num < 0 || num >= count)
   {
    print_ascii();
    cout << "Invalid number. Press Enter to try again." << endl;
    getline(cin, again);
   }

   // if num is valid
   else
   {
    
    print_ascii();

    // print requested secret-santa result
    cout << hat[num] << "," << endl << endl;
    assign = givesTo[num];
    cout << "You are " <<  hat[assign] << "'s Secret Santa!" << endl;
    cout << endl;

    // hit enter to make new request
    cout << "Press enter to select a new name." << endl;
    getline(cin, again);
   }

   // reinitialize 
   num = -1;
  }
 }
}

void print_ascii()
{

 cout << "\033[2J\033[1;1H"; 
 cout << "*****************************************" << endl;
 cout << "*                                       *" << endl;
 cout << "*  $$$$$ $$$$$ $$$$$ $$$$$ $$$$$ $$$$$  *" << endl;
 cout << "*  $     $     $     $   $ $       $    *" << endl;
 cout << "*  $$$$$ $$$$$ $     $$$$$ $$$$$   $    *" << endl;
 cout << "*      $ $     $     $  $  $       $    *" << endl;
 cout << "*  $$$$$ $$$$$ $$$$$ $   $ $$$$$   $    *" << endl;
 cout << "*     $$$$$ $$$$$ $   $ $$$$$ $$$$$     *" << endl;
 cout << "*     $     $   $ $$  $   $   $   $     *" << endl;
 cout << "*     $$$$$ $$$$$ $ $ $   $   $$$$$     *" << endl;
 cout << "*         $ $   $ $  $$   $   $   $     *" << endl;
 cout << "*     $$$$$ $   $ $   $   $   $   $     *" << endl;
 cout << "*                                       *" << endl;
 cout << "*****************************************" << endl;
 cout << endl;
}

Friday, October 17, 2014

Bug Alert: Network Connect VPN Client on OSX Yosemite

Doing some wireless troubleshooting, I came across a bug in Network Connect. Losing network connectivity (computer sleeps, lost wireless connection, etc) while connected to a VPN using Network Connect will effectively break your internet connectivity. You will still connect to a network and obtain an IP address but you won't access the web. If you ping google.com, you will get a "cannot allocate memory" message. The Network Connect will attempt to reconnect but will fail.

A couple fixes:

If you encounter the "cannot allocate memory" message when trying to ping a server, do one of the following to clear your route. 
  • Reboot your computer
  • On terminal, do a netstat -rn
    • Get the IP address from the default gateway
    • sudo route delete -host <ipaddress>
    • Turn your wireless off and on
A better OS X VPN client would be Junos Pulse. This client requires a Junos Pulse account so you'll have to search the web for a free download. I found mine from Step 3 in Troubleshooting here http://iso.csusb.edu/download/vpn

This may be fixed with any upcoming Yosemite updates. It's been pretty buggy on release.


Wednesday, October 15, 2014

Parse switch logs to MySQL database

This is my first program utilizing Python and MySQL together. It is not perfect but it works. 

Note: Inserting an element into MySQL one-by-one would take days (the input is several hundred-thousand lines). I used executemany() to stick a whole array into one insertion. Cut my time from 10 hours to 4 minutes!


# parse_syslog.py

# This is a script to parse switch syslogs nightly into a MySQL Database
# Input is a .gz file of Cisco switch logs
import MySQLdb
import time
import gzip
# mySQL Config
mysqlhost = 'localhost'
mysqlusername = 'user'
mysqlpassword = 'notrealpassword'
mysqldatabase = 'switch_logs'
mysqldb = MySQLdb.connect(mysqlhost, mysqlusername, mysqlpassword, mysqldatabase)
# ask user for name of .gz file
filename = raw_input('Enter a file name: ')
# open .gz file for input
input_file = gzip.open(filename, 'rb')
try:
 # initializations
 msgValid = False
 interface1 = None
 interface2 = None
 vlan = None
 cnt = 0
 err = '%'
 import_list = []
 # get line
 line = input_file.readline()
 # get date 
 ldate = time.strftime("%Y-%m-%d")
 # go through every line in the file
 while line:
  # parse the line
  args = line.split()
  # get next line
  line = input_file.readline()
  # extract information from parsed line
  # get error message
  msg = [s for s in args if "%" in s]
  if len(msg) > 0:
   if msg[0][0] == '%':
    msg = msg[0]
    msgValid = True  
  # if found error msg, get time, ip, interface, vlan
  if msgValid == True:
   # increment count
   cnt=cnt+1
   # get time
   time = args[2]
   # get ip address
   ip = args[3]
   # get vlan
   try:
    vlanIndex = args.index('vlan')+1
    vlan = args[vlanIndex].split('.',1)[0]
    if vlan.isdigit() == False:
     vlan = None
   except ValueError:
    pass
   # get interfaces
   # create list of interfaces found in args
   interfaces = [s for s in args if "Gi" in s]
   # if found Gi interfaces
   if len(interfaces) > 0: 
    interface1 = interfaces[0].split(',',1)[0]
    if len(interfaces) == 2:
     interface2 = interfaces[1]
   # if not found Gi, find Fa interfaces
   else:
    interfaces = [s for s in args if "Fa" in s]
    if len(interfaces) > 0: 
     interface1 = interfaces[0]
     if len(interfaces) == 2:
      interface2 = interfaces[1]   
   # insert into list
   arr = [ip, time, ldate, msg, interface1, interface2, vlan]
   import_list.append(arr)
   # reinitialize variables
   interface1 = None
   interface2 = None
   msgValid = False
   vlan = None
   msg = None
finally:
 # batch insert into MySQL Database 
 stmt = "INSERT INTO test VALUES(%s, %s, %s, %s, %s, %s, %s)"
 with mysqldb:
  mysqlcur = mysqldb.cursor()
  mysqlcur.executemany(stmt, import_list)
 input_file.close()

Friday, October 10, 2014

AP Configuration

Setting up APs

1. Patch APs into a switch or network ports to boot up and update automatically.

2. Get AP names from switch that APs are patched in and paste into text file
    show cdp neighbors

3. Add new names into text file in front of current names
    <new name>    <current name>

Configuration

1. Login to Controller

2. Change AP names
    config ap name <new name> <old name>
   
   For batch renaming, use awk
    awk '{ print "config ap name",$1,$2 }'<text file name>

3. Set primary base
    config ap primary-base <controller> <ap name>

    For batch
    awk '{ print "config ap primary-base <controller>",$1,"<controller IP" }' <text file name>

4. Set group
    config ap group-name <group name> <ap name>

    For batch
    awk '{ print "config ap group-name <group name>",$1,"\ny"}'<text file name>
   
    AP will reboot

5. If you want to disable AP (enabled by default)
    config ap disable <ap name>

6. Flash LED to track correct AP
    config ap led-state flash 10 <ap name>

Configure a Server with Debian

The server must also include user credentials for others to access the server and enable ssh for remote access.

Setting up the server

1. Install Debian (squeeze) with basic utilities and ssh server
    Note: This can be done in a variety of ways (PXE Network Boot, USB Drive, CD-ROM, etc)

2. Once installed, enter privileged mode
    su

3. Install ntp, tcpdump, vim
    sudo apt-get install <program name>

4. Install Nagios
    Note: refer to wiki page for Nagios NRPE installation

5. Get IP address of server
    ifconfig

6. On a separate computer, login to server using default credentials

7. Enter privileged mode
   su

8. Add usernames of all members
    adduser <username>
   Use a basic default password (it will be replaced)

9. Enable sudo for each member
   usermod -a -G sudo <username>

10. On a preexisting server, view /etc/shadow to find actual password hash

11. Edit /etc/shadow on the server and insert the correct hash.  


Create list of all hosts on subnets

1. Use nmap on linux terminal to find all hosts on a subnet

2. Display all hostnames and their IP
    nmap -v -sn <subnet> | fgrep -v [host | fgrep -v latency | grep report | awk '{print $5"\t"$6}'

3. Display the count of hosts on the subnet
    nmap -v -sn <subnet> | fgrep -v [host | fgrep -v latency | grep -c report

4. Paste the two outputs of Steps 2 and 3 onto a spreadsheet or text file. 

Update 3850 Switch Stack

Setting up the switch stack

1. Create a loop between all stack members with stack cables
    Note: For N stack members, you need N stack cables to run at full duplex and redundancy.

2. Create a loop between all stack members with power cables
    Note: Similar to stack cables, you would need N power cables.

3. Plug in power supplies. Every stack gets one. Add an extra power supply for every 4th stack member.
    Note: When plugging into rack, put one of the power cables into the wall and the rest into UPS for redundancy. 

4. Console into the switch and use screen (Linux) command to view it
    sudo screen /dev/ttyUSB0 9600

Updating the Software 

  1. Enable privileged exec mode
    enable

  2. Configure VLAN 1
    interface vlan 1

  3. Turn the port hot
    no shut

  4. Exit config mode
    end 

  5. Enter global configuration mode
    configure terminal

  6. Configure Gi1/0/1
    int gi1/0/1
     
  7. Set access VLAN to 1
    switchport access vlan 1

  8. Prevent inbound/outbound BPDU
    spanning-tree bpdufilter enable

  9. Turn the port hot
    no shut

  10. Plug a port into gi 1/0/1

  11. Exit config mode
    end

  12. Verify VLAN 1 picked up an IP address
    ip dhcp snooping binding vlan 1

  13. Use scp to copy a file from remote server to the switch (must be on privileged net)
    copy scp://<username>@<file path> flash:/

  14. Install the new firmware on the switch
    software install file flash:cat3k_caa-universalk9.SPA.03.03.04.SE.150-1.EZ4.bin