Network Port Mapping

BaddMann
Contributor

I'd really like to create Smart Groups based on the ports and switches the computers are plugged into.
I've Found this awesome app called "whichswitch.app". Tells me enough info to create the smart groups but is locked behind a lot of GUI muck.

Has anyone got any scripts (bash, perl, python, anything really) that can capture the CDP Packets or the LLDP Packets on a network interface and parse out port and switch info?

Here is what I've found so far, an LLDP tutorial that I'm not able to get working:
http://www.adminsys.ch/2012/09/12/add-lldp-information-absolute-manage-mac-os/

And which switch, the program that got me looking down this rabbit hole:
http://www.computernetworkbasics.com/whichswitch

thank you in advance for any information.

PS: I'm not sure why this is tag Aperture.
I'd Un-tag but I have no idea how.

1 ACCEPTED SOLUTION

BaddMann
Contributor

Alright, needless update time:

I've created an api version of the script that's been functioning correctly for weeks, so it's time to post.
It's not neat, and I've already thought of three ways to improve it while getting it sanitized for this post.

Feel free to fix my messy messy script:

#!/bin/sh

 jssAPIUsername=“<yourapiwriteuser>”
 jssAPIPassword=“<yourapiwriteuserpassword>”
 jssAddress="https://<yourjss>:8443"

#Create the Dump ###The Meat and Potatos of this whole script! The rest is useless fluff, thought this does need to be cleaned up.
tcpdump -nn -v -i en0 -s 1500 -c 1 'ether[20:2] == 0x2000' | grep -e "(0x0" | awk -F ",|:" '{printf "%-30s %-50s
", $1, $NF}' > /tmp/portinfo.txt

#Extract the relevant Info from Dump
PORT=`cat /tmp/portinfo.txt | grep "(0x03)" | awk '{print $NF}' | tr "'" " "`
DEVICE=`cat /tmp/portinfo.txt | grep "(0x01)" | awk '{print $NF}' | tr "'" " "`
VLAN=`cat /tmp/portinfo.txt | grep "(0x0a)" | awk '{print $NF}'`
echo "$DEVICE - $PORT - $VLAN"

#Create XML with Dumped data to import into Casper the Extended attributes are created before hand and are simple text inputs, all this does is give them values.
cat >/tmp/myXMLFile.xml <<EOL
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<computer>
<extension_attributes>
<attribute>
<name>(Cisco) Network Port</name>
<value>$(echo $PORT)</value>
</attribute>
<attribute>
<name>(Cisco) Network Switch</name>
<value>$(echo $DEVICE)</value>
</attribute>
<attribute>
<name>(Cisco) Network VLAN</name>
<value>$(echo $VLAN)</value>
</attribute>
</extension_attributes>
</computer>
EOL


# Determine the Serial, then post info blindly to their records within casper.
serial=`ioreg -l | grep IOPlatformSerialNumber|awk '{print $4}' | cut -d " -f 2`
cd /tmp
curl -k -s -I -u $jssAPIUsername:$jssAPIPassword $jssAddress/JSSResource/computers/serialnumber/$serial -T "myXMLFile.xml" -X PUT

#Set ARD field for easy lookup, useful for lookup while remoted-in or using other tools.
/usr/libexec/PlistBuddy -c "Set :Text3 $VLAN $PORT $DEVICE" /Library/Preferences/com.apple.RemoteDesktop.plist

exit 0

View solution in original post

7 REPLIES 7

guzmanhm
New Contributor II

Did you ever find anything to make this work?

BaddMann
Contributor

Yes I did, but I've been unable to implement it correctly as an EA.

Here is my code, maybe you can add to it.

#!/bin/sh

tcpdump -nn -v -i en0 -s 1500 -c 1 'ether[20:2] == 0x2000' | grep -e "(0x0" | awk -F ",|:" '{printf "%-30s %-50s
", $1, $NF}' > /tmp/portinfo.txt

That creates the temporary file that I was trying to get my EA scripts to parse through but I'm failing.

Here is my current EA(s), that keeps wiping out them selves. I'm probably going to have to re-write this all as api posts. :(

This Gets the network port from the TCPDump Tool
Port-ID (0x03)

#!/bin/sh

if [ ! -f /tmp/portinfo.txt ]
then
  PORT=`cat /tmp/portinfo.txt | grep "(0x03)" | awk '{print $NF}'`
  echo "<result>$PORT</result>"
fi

This Gets the network Switch DNS Name from the TCPDump Tool
Device-ID (0x01)

#!/bin/sh

if [ ! -f /tmp/portinfo.txt ]
then
  PORT=`cat /tmp/portinfo.txt | grep "(0x01)" | awk '{print $NF}'`
  echo "<result>$PORT</result>"
fi

This Gets the network VLAN from the TCPDump Tool
Native VLAN ID (0x0a)

#!/bin/sh

if [ ! -f /tmp/portinfo.txt ]
then
  PORT=`cat /tmp/portinfo.txt | grep "(0x0a)" | awk '{print $NF}'`
  echo "<result>$PORT</result>"
fi

Thank you for the interest.

BaddMann
Contributor

Alright, needless update time:

I've created an api version of the script that's been functioning correctly for weeks, so it's time to post.
It's not neat, and I've already thought of three ways to improve it while getting it sanitized for this post.

Feel free to fix my messy messy script:

#!/bin/sh

 jssAPIUsername=“<yourapiwriteuser>”
 jssAPIPassword=“<yourapiwriteuserpassword>”
 jssAddress="https://<yourjss>:8443"

#Create the Dump ###The Meat and Potatos of this whole script! The rest is useless fluff, thought this does need to be cleaned up.
tcpdump -nn -v -i en0 -s 1500 -c 1 'ether[20:2] == 0x2000' | grep -e "(0x0" | awk -F ",|:" '{printf "%-30s %-50s
", $1, $NF}' > /tmp/portinfo.txt

#Extract the relevant Info from Dump
PORT=`cat /tmp/portinfo.txt | grep "(0x03)" | awk '{print $NF}' | tr "'" " "`
DEVICE=`cat /tmp/portinfo.txt | grep "(0x01)" | awk '{print $NF}' | tr "'" " "`
VLAN=`cat /tmp/portinfo.txt | grep "(0x0a)" | awk '{print $NF}'`
echo "$DEVICE - $PORT - $VLAN"

#Create XML with Dumped data to import into Casper the Extended attributes are created before hand and are simple text inputs, all this does is give them values.
cat >/tmp/myXMLFile.xml <<EOL
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<computer>
<extension_attributes>
<attribute>
<name>(Cisco) Network Port</name>
<value>$(echo $PORT)</value>
</attribute>
<attribute>
<name>(Cisco) Network Switch</name>
<value>$(echo $DEVICE)</value>
</attribute>
<attribute>
<name>(Cisco) Network VLAN</name>
<value>$(echo $VLAN)</value>
</attribute>
</extension_attributes>
</computer>
EOL


# Determine the Serial, then post info blindly to their records within casper.
serial=`ioreg -l | grep IOPlatformSerialNumber|awk '{print $4}' | cut -d " -f 2`
cd /tmp
curl -k -s -I -u $jssAPIUsername:$jssAPIPassword $jssAddress/JSSResource/computers/serialnumber/$serial -T "myXMLFile.xml" -X PUT

#Set ARD field for easy lookup, useful for lookup while remoted-in or using other tools.
/usr/libexec/PlistBuddy -c "Set :Text3 $VLAN $PORT $DEVICE" /Library/Preferences/com.apple.RemoteDesktop.plist

exit 0

gmarnin
New Contributor III

BaddMann - How often do you run this script and what mechanism are you using to run it?

BaddMann
Contributor

Right now on enrollment policy only, but as we may not be imaging where the computer may be at rest I'm contemplating doing it at startup.
The previous values are just over-written by the new values, so it's performing just like an EA.

I also run it once in a while manually when I'm feeling a little A.D.D. about our Inventory database missing data. As our switches DNS names clue us in on physical location I can tell if a macintosh is not where it's suppose to be and I can start cracking technician heads. :P

I've not tested performance possibilities yet. This script can take up to 30 seconds to get the packets from the network (Depends on the switch config), so I'll do a few startup runs before the semester starts.

Eventually I'm hoping to use all the network typology info to build JDS instances for particular switches as one of our bottlenecks right now are the 1GB links to each building. If I image a class of 25 Macs across the link I quickly flood the outbound network for that building and have the network admins shouting out my name in vain.

I hope this helps.

gmarnin
New Contributor III

Interesting. I've been working on a similar idea for the munkireport-php project. It's still a wip but figuring out when / how often to run the script is the current road block.

See https://github.com/munkireport/munkireport-php/pull/119

BaddMann
Contributor

Oh wow thanks. That link has some info I was spending months googling for!!

Munki would be a whole new beast. I'd say make a separate process execute every time munki runs a check. That way if you happen to not be on a cisco router it doesn't hang munki.
That process simply writes the DUMP file.
Next Munki Run have it read the dump file if it exists.
Store the dump in tmp, so that if the computer is ever shutdown, it gets created again when booted.
That should handle 90% of the situations that is important. The only one it won't really help with is the power user with a macbook wondering around and plugging in as he/she goes.

Otherwise crankd would be your other, more complicated option.
http://grahamgilbert.com/blog/2013/07/12/using-crankd-to-react-to-network-events/
It detects network changes and executes scripts on those changes.