wktools Version 4 - Mapper Lua API
  (c) 2003 - 2014 by Mathias Spoerr


Table of contents:

1. General Information

2. Usage and global variables

3. Structs

4. Functions

5. Example: Lua Parser for HP ProCurve devices



1. General

With the Lua API it is possible to write custom parsers for devices not supported by wktools Mapper. wktools provides several wrapper functions to insert the parsed data into the SQLite database. This document lists all available methods and shows how to use them.

Database Layout:






2. Usage and global variables

2.1. How to start a Lua script

A script is loaded when a data file starts with "!!! UseScript scriptname". The given script file must be available in the wktools directory and must have ".lua" as file extension. scriptname itself is used without ".lua".


2.2. ParserDB

The ParserDB object is provided by wktools and represents the Sqlite database and maintains it's status. Call all functions from this object.


2.3. Get Data-File content

The data file is loaded by wktools and Lua receives the content by calling the ParserDB:getStringToParse() function:

	data = ParserDB:getStringToParse()



3. Structs

The following two structs are available to save interface and crypto related data. The two main interface-insert-functions would have too many arguments, hence the structs are used to simplify the function usage.

cryptoSets: Crypto Details

	struct cryptoSets {
		string intfName,
		string dev_id,
		string peer,
		string local_net,
		string remote_net,
		string vrf,
		string pfs_grp,
		string pkt_encaps,
		string pkt_decaps,
		string pkt_encrypt,
		string pkt_decrypt,
		string send_err,
		string rcv_err,
		string path_mtu,
		string status,
		string esp_i,
		string ah_i,
		string pcp_i,
		string esp_o,
		string ah_o,
		string pcp_o,
		string settings,
		string tag,
		string seqnr
	};
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	cSets = cryptoSets()
	cSets.intfName = "Intf-Name"
	...
	
intfNameMandatoryInterface Name (normalized)
dev_idMandatoryDevice ID
peerMandatoryPeer IP Address
local_netMandatoryLocal Crypto Network
remote_netMandatoryRemote Crypto Network
vrfOptionalVRF
pfs_grpOptionalPFS DH Group
pkt_encapsMandatoryNumber of encapsulated packets; Use "0" if not applicable.
pkt_decapsMandatoryNumber of decapsulated packets; Use "0" if not applicable.
pkt_encryptMandatoryNumber of encrypted packets; Use "0" if not applicable.
pkt_decryptMandatoryNumber of decrypted packets; Use "0" if not applicable.
send_errMandatoryNumber of send errors; Use "0" if not applicable.
rcv_errMandatoryNumber of receive errors; Use "0" if not applicable.
path_mtuMandatoryPath MTU; Use "0" if not applicable.
statusMandatoryStatus of SA
esp_iOptionalInbound ESP SA
ah_iOptionalInbound AH SA
pcp_iOptionalInbound PCP SA
esp_oOptionalOutbound ESP SA
ah_oOptionalOutbound AH SA
pcp_oOptionalOutbound PCP SA
settingsOptionalSettings
tagOptionalCrypto Map Tag
seqnrOptionalCrypto Map Sequence Number


intfSets: Main information to define an interface

	struct intfSets {
		string intfName, 
		string nameif, 
		string intfType, 
		string phl, 
		string macAddress, 
		string ipAddress, 
		string subnetMask, 
		string duplex, 
		string speed,
		string status, 
		string description, 
		string l2l3, 
		string dev_id
		}
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	iSets = intfSets()
	iSets.intfName = "Intf-ID"
	...
	
intfNameMandatoryInterface Name (Needs Normalization -> intfNameChange() )
nameifOptionalAlternate Interface name, like ASA nameif
intfTypeMandatoryInterface Type (Needs Normalization -> intfTypeCheck() )
phlMandatorylogical or physical? (Needs Normalization -> intfPhlCheck() )
  • 0...Logical
  • 1...Physical, including Po
  • 2...VSL
  • 3...Veth
macAddressOptionalInterface MAC Address
ipAddressOptionalInterface IP Address; Only Primary IP Address; Secondary IPs are inserted into the Subnet table
subnetMaskOptionalSubnet Mask
duplexOptionalInterface Duplex Settings
speedOptionalInterface Speed Settings
statusMandatoryInterface Status (Up/Down...);
!!! It is important to use "Up" for active interfaces, "Down" for inactive Interfaces and "Disabled" for shutdown interfaces (upper/lower case does not matter) !!!
descriptionOptionalDescription
l2l3MandatoryLayer2 (L2) or Layer3 (L3)
dev_idMandatoryDevice ID; The interface will be attached to the given device


intfStats: Interface counters

	struct intfStats {
		string errLvl, 
		string lastClear, 
		string loadLvl, 
		string iCrc, 
		string iFrame, 
		string iOverrun, 
		string iIgnored, 
		string iWatchdog, 
		string iPause, 
		string iDribbleCondition, 
		string ibuffer, 
		string l2decodeDrops, 
		string runts, 
		string giants, 
		string throttles, 
		string ierrors, 
		string underrun, 
		string oerrors, 
		string oCollisions, 
		string oBabbles, 
		string oLateColl, 
		string oDeferred, 
		string oLostCarrier, 
		string oNoCarrier, 
		string oPauseOutput, 
		string oBufferSwapped, 
		string resets, 
		string obuffer, 
		string lastInput, 
		string intf_id
		}
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	iStats = intfStats()
	iStats.errLvl = "error-level"
	...
	
errLvlMandatorySum of all errors; Must be "0" at least.
lastClearOptionalTimestamp of last "clear counters" or similar command.
loadLvlMandatoryInterface Load Level; Must be "0" at least.
iCrcOptional# CRC errors
iFrameOptional# Frame erros
iOverrunOptional# Overruns
iIgnoredOptional# Ignored
iWatchdogOptional# Watchdog errors
iPauseOptional# Pause frames
iDribbleConditionOptional# Dribble Condition errors
ibufferOptional# Input Buffer Drops
l2decodeDropsOptional# L2 Decode Drops
runtsOptional# Runts
giantsOptional# Giants
throttlesOptional# Throttles
ierrorsOptional# Total Input errors
underrunOptional# Underruns
oerrorsOptional# Total Output errors
oCollisionsOptional# Collisions
oBabblesOptional# Babbles
oLateCollOptional# Late Collisions
oDeferredOptional# Deferred
oLostCarrierOptional# Lost Carrier
oNoCarrierOptional# No Carrier
oPauseOutputOptional# Output Pause Frames
oBufferSwappedOptional# Buffer Swaps
resetsOptional# Interface Resets
obufferOptional# Output Buffer Drops
lastInputOptionalTimestamp of last Input Packet
intf_idMandatoryInterface ID; The counters will be attached to the given interface.





4. Functions

This section lists all available wktools functions to be used by Lua.

getIntfID: Get Interface ID from Interface Name

	string getIntfID(
		string dev_id, 
		string interfaceName, 
		bool err
		)
	

Usage:

	iID = ParserDB:getIntfID(dev_id, port, true)
	
dev_idMandatoryDevice ID
interfaceNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
errMandatorytrue: Print error if Interface not found; false: No error


getIntfIDfromL3Route: Look-up Outbound Interface-ID for an Input-IP in the Routing Table

	string getIntfIDfromL3Route(
		string ipAddress, 
		string dev_id
		)
	

Usage:

	iID = ParserDB:getIntfIDfromL3Route(ipAddress, dev_id)
	
ipAddressMandatoryIP Address for which the look-up should be done.
dev_idMandatoryDevice ID


getIntfNameFromID: Get Interface Name from Interface ID

	string getIntfNameFromID(
		string intf_id, 
		bool error
		)
	

Usage:

	iName = ParserDB:getIntfNameFromID(intf_id, false)
	
intf_idMandatoryInterface ID
errorMandatorytrue: Print error if Interface not found; false: No error


getIntfNamefromIP: Get Interface-Name from Interface IP address.

	string getIntfNamefromIP(
		string ipAddress, 
		string dev_id
		)
	

Usage:

	iName = ParserDB:getIntfNamefromIP(ipAddress, dev_id)
	
ipAddressMandatoryInterface IP Address.
dev_idMandatoryDevice ID


getIntfIDFromNameif: Get Interface ID from nameif

	string getIntfIDFromNameif(
		string dev_id, 
		string nameif, 
		bool err
		)
	

Usage:

	iID = ParserDB:getIntfID(dev_id, altName, true)
	
dev_idMandatoryDevice ID
nameifMandatoryAlternate Interface name or nameif for ASA firewalls
errMandatorytrue: Print error if Interface not found; false: No error


getIntfNameFromNameif: Get Interface Name from nameif

	string getIntfNameFromNameif(
		string dev_id, 
		string nameif
		)
	

Usage:

	iName = ParserDB:getIntfNameFromNameif(dev_id, altName)
	
dev_idMandatoryDevice ID
nameifMandatoryAlternate Interface name or nameif for ASA firewalls


insertCDP: Add CDP or LLDP neighbors to the database

	insertCDP(string hostname, 
		string nName, 
		string alternatenName, 
		string intf, 
		string nIntfIP, 
		string nIntf, 
		string type, 
		string platform, 
		string sw_version, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertCDP(localHostname, neighborHostname, alternateNeighborName, 
		localIntf, neighborIP, neighborIntf, neighborType, neighborPlatform, neighborSW_version, dev_id)
	
hostnameMandatoryLocal Hostname
nNameMandatoryNeighbor Hostname
alternatenNameOptionalAlternate Neighbor Hostname; May be used to differentiate between devices with the same hostname, or to save the FQDN.
intfMandatoryLocal Interface Name; Use ParserDB:intfNameChange() to normalize the Interface name
nIntfIPOptionalNeighbor IP address
nIntfMandatoryNeighbor Interface Name; Use ParserDB:intfNameChange() to normalize the Interface name
typeMandatoryNeighbor Type - Use the following values to specify the neighbor device type:
  • 1 Router
  • 2 Switch
  • 3 Firewall
  • 4 AccessPoint
  • 8 L3 Switch
  • 6 VoiceGateway
  • 11 Phone
  • 12 End-system
  • 13 ATA
  • 14 Camera
  • 99 Unknown
platformOptionalNeighbor HW Platform
sw_versionOptionalNeighbor SW Version
dev_idMandatoryDevice ID


insertCrypto: Adds a new crypto map SA to the DB

	insertCrypto(
		cryptoSets *cSets
		)
	

Usage:

	ParserDB:insertCrypto(cSets)
	
cSetsMandatoryName of the cryptoSets structure with the crypto info


insertCryptoIntf: Add crypto information to an interface.

	insertCryptoIntf(
		string cryptoMapTag, 
		string cryptoLocalIP, 
		string cryptoRemoteIP, 
		string intfName, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertCryptoIntf(cryptoMapTag, cryptoLocalIP, cryptoRemoteIP, intfName, dev_id)
	
cryptoMapTagOptionalCrypto Map Name
cryptoLocalIPOptionalLocal Crypto Peer IP Address
cryptoRemoteIPOptionalRemote Crypto Peer IP Address; Only relevant for point-to-point tunnels. For Multipoint tunnels please use insertCrypto()
intfNameMandatoryInterface Name
dev_idMandatoryDevice ID


insertCryptoMapIntf: Add a virtual Interface for each crypto Map Peer IP address.

	insertCryptoMapIntf(
		string intfName, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertCryptoMapIntf(intfName, dev_id)
	
intfNameMandatoryInterface Name
dev_idMandatoryDevice ID


insertDevice: Add a new device to the database and return the Device ID, which is needed as function argument very often.

	string insertDevice(
		string hName, 
		string hType, 
		string hHwtype, 
		string hConfReg
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	dev_id = ParserDB:insertDevice(hostname, hType, hHwtype, hConfReg)
	
hNameMandatoryHostname
hTypeMandatoryHardware Type - Use the following values to specify the Device Type:
  • 1 Router
  • 2 Switch
  • 3 Firewall
  • 4 AccessPoint
  • 8 L3 Switch
  • 6 VoiceGateway
  • 11 Phone
  • 12 End-system
  • 13 ATA
  • 14 Camera
  • 99 Unknown
hHwtypeMandatoryUse the same value as for "hType"; "hType" may be changed by wktools later on, while "hHwtype" stays the same.
hConfRegOptionalConfig Register


insertDevTracking: Add IP Device Tracking Information.

	string insertDevTracking(
		string macAddress, 
		string ipAddress, 
		string state, 
		string vlanID,
		string intfName,
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertDevTracking(macAddress, ipAddress, state, vlanID, intfName, dev_id)
	
macAddressMandatoryMAC Address
ipAddressMandatoryIP Address
stateOptionalState
vlanIDOptionalVLAN ID
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name
dev_idMandatoryDevice ID


insertDevTrackingDev: Add Device-related IP Device Tracking information

	string insertDevTrackingDev(
		string devTrackingStatus, 
		string devTrackingProbeCount, 
		string devTrackingProbeInterval, 
		string devTrackingProbeDelay,
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertDevTrackingDev(devTrackingStatus, devTrackingProbeCount, devTrackingProbeInterval, devTrackingProbeDelay, dev_id)
	
devTrackingStatusOptionalGlobal IP Device Tracking status
devTrackingProbeCountOptionalIP Device Tracking Probe Count
devTrackingProbeIntervalOptionalIP Device Tracking Probe Interval
devTrackingProbeDelayOptionalIP Device Tracking Probe Delay Interval
dev_idMandatoryDevice ID


insertDHCPSnooping: Add IP DHCP Snooping Information.

	string insertDHCPSnooping(
		string macAddress, 
		string ipAddress, 
		string leaseTime, 
		string vlanID,
		string intfName,
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertDHCPSnooping(macAddress, ipAddress, leaseTime, vlanID, intfName, dev_id)
	
macAddressMandatoryMAC Address
ipAddressMandatoryIP Address
leaseTimeOptionalDHCP Lease Time
vlanIDOptionalVLAN ID
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name
dev_idMandatoryDevice ID


insertDot1xDev: Add Device-global dot1x information to the DB

	insertDot1xDev(
		string status, 
		string version, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertDot1xDev(status, version, dev_id)
	
statusMandatorySystem Auth Control Status
versionOptionaldot1x Version
dev_idMandatoryDevice ID


insertDot1xIntf: Add interface related dot1x information

	insertDot1xIntf(
		string dot1x, 
		string mab, 
		string intfName, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertDot1xIntf(dot1x, mab, intfName, dev_id)
	
dot1xOptionaldot1x role; If not set, mab must not be empty.
mabOptionalMAB status; If not set, dot1x must not be empty.
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
dev_idMandatoryDevice ID


insertDot1xUser: Add authentication session information to the DB

	insertDot1xUser(
		string userMac, 
		string method, 
		string domain, 
		string status,
		string intfName,
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertDot1xUser(userMac, method, domain, status, intfName, dev_id)
	
userMacMandatoryend-client MAC address
methodMandatoryMAB/dot1x/...
domainMandatoryVoice/Data/...
statusMandatoryAuthentication status
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
dev_idMandatoryDevice ID


insertFlash: Add flash and HDD information to a device.

	insertFlash(
		string fname, 
		string fsize, 
		string ffree, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertFlash(partitionName, partitionSize, free, dev_id)
	
fnameMandatoryPartition Name
fsizeMandatoryPartition Size
ffreeOptionalFree space
dev_idMandatoryDevice ID


insertFOStatus: Add Failover status to a device.

	insertFOStatus(
		string foStatus, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertFOStatus(foStatus, dev_id)
	
foStatusMandatoryFailover Status
dev_idMandatoryDevice ID


insertHardware: Add detailed hardware information like serial number, description and part number to a device, including modules and other parts. Returns the DB ID of the added hardware. This ID is needed to attach modules to a chassis. Updates may be done with updateHardware() function

	string insertHardware(
		string hPos, 
		string hModell, 
		string hDescription, 
		string hChassisSN, 
		string hRevision, 
		string hMem, 
		string hBootfile, 
		string hVersion, 
		string dev_id, 
		string boxHwInfId
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	hwId = ParserDB:insertHardware(position, modellName, description, serialNumber, hwRevision, memorySize, bootfile, version, dev_id, boxHwInfId)
	
hPosMandatoryPosition: Either "box" for the chassis itself, or the module identifier, or power supply position, or...
The position for a chassis must be "box"
hModellMandatoryModel name or Part number
hDescriptionOptionalDescription
hChassisSNOptionalSerial Number
hRevisionOptionalHW Revision number
hMemOptionalMemory size
hBootfileOptionalBootfile
hVersionOptionalSW Version
dev_idMandatoryDevice ID; The hardware will be attached to the given device.
boxHwInfIdMandatoryHardware ID of the chassis; Keep empty ("") when adding the chassis itself; Use the HW ID of the chassis when adding modules, power supplies or SFPs...


insertHSRP: Add HSRP information to DB

	string insertHSRP(
		string intfName,
		string grp,
		string priority,
		string state,
		string active,
		string standby,
		string virtualIP,
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertHSRP(intfName, grp, priority, state, active, standby, virtualIP, dev_id)
	
intfNameMandatoryInterface Name
grpOptionalGroup#
priorityOptionalPriority
stateOptionalState
activeOptionalActive Node
standbyOptionalStandby Node
virtualIPMandatoryVirtual IP Address
dev_idMandatoryDevice ID


insertInterface: Adds a new interface to the DB; Returns the Interface ID

	string insertInterfaceStruct(
		intfSets *iSets
		)
	

Usage:

	hwId = ParserDB:insertInterface(iSets)
	
iSetsMandatoryName of the intfSets structure with the interface info


insertIntfN1k: Attach VM-Ware information to a virtual switchport.

	insertIntfN1k(
		string actModule, 
		string owner, 
		string portProfile, 
		string intf_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertIntfN1k(actModule, owner, portProfile, intf_id)
	
actModuleMandatoryActive on Module -> Virtual Ethernet Module # where this interface is active
ownerOptionalOwner (VM where this interface is attached to)
portProfileOptionalPort Profile -> VMWare Port Profile
intf_idMandatoryInterface ID


insertIntfStats: Adds interface statistics to an interface.

	insertIntfStats(
		intfStats *iStats
		)
	

Usage:

	ParserDB:insertIntfStats(iStats)
	
iStatsMandatoryName of the intfStats structure with the interface counter info


insertLic: Add license information; Returns true when successful, otherwise false.

	bool insertLic(
		string lName, 
		string lStatus, 
		string lType, 
		string lNextBoot, 
		string lCluster, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertLic(licName, licStat, licTape, licNextBoot, licCluster, dev_id)
	
lNameMandatoryLicense Name
lStatusOptionalLicense Status
lTypeOptionalLicense Type
lNextBootOptionalLicense upon next boot
lClusterOptionalCluster License
dev_idMandatoryDevice ID; The license will be attached to the given device.


insertNeighbor: Add ARP or CAM table entry to the DB. The entry is bound to the interface where the neighor is seen.

	insertNeighbor(
		string intf_id, 
		string maca, 
		string ipa, 
		string self
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertNeighbor(intf_id, macAddress, ipAddress, self)
	
intf_idMandatoryInterface ID where the neighbor is found
macaMandatoryMAC Address of the neighbor; Use ParserDB:macAddChange() to normalize the MAC address format.
ipaOptionalIP Address of the neighbor
selfOptionalOwn IP? -> Set to "1" if the IP address is owned by the device itself, or leave empty ("") if it's some neighbors IP


insertOspfIntf: Add OSPF interface related information.

	insertOspfIntf(
		string area, 
		string nwType, 
		string cost, 
		string processID, 
		string intfName,
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertOspfIntf(area, nwType, cost, processID, intfName, dev_id)
	
areaMandatoryArea
nwTypeOptionalNetwork Type
costOptionalCost
processIDMandatoryOSPF Process ID
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
dev_idMandatoryDevice ID


insertOspfProcess: Add OSPF process information to DB.

	insertOspfProcess(
		string routerID, 
		string processID, 
		string vrf, 
		string spfExecutions, 
		string spfLastRun, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertOspfProcess(routerID, processID, vrf, spfExecutions, spfLastRun, dev_id)
	
routerIDMandatoryOSPF Router-ID
processIDMandatoryOSPF Process ID.
vrfOptionalvrf Name
spfExecutionsOptionalNumber of SPF executions
spfLastRunOptionalTime of last SPF run
dev_idMandatoryDevice ID


insertPhone: Add IP phone details to an IP phone device.

	insertPhone(
		string voiceVlan, 
		string cm1, 
		string cm2, 
		string dscpSig, 
		string dscpConf, 
		string dscpCall, 
		string defGW, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertPhone(voiceVlan, cm1, cm2, dscpSig, dscpConf, dscpCall, defGW, dev_id)
	
voiceVlanOptionalVoice VLAN
cm1OptionalCallManager 1 IP
cm2OptionalCallManager 2 IP
dscpSigOptionalDSCP for Signalling
dscpConfOptionalDSCP for Config
dscpCallOptionalDSCP for RDP
defGWOptionalDefault Gateway
dev_idMandatoryDevice ID of the IP phone to which this information should be attached to


insertPoeDev: Add device related PoE information.

	insertPoeDev(
		string poeStatus, 
		string poeCurrent, 
		string poeMax, 
		string poeRemaining, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertPoeDev(poeStatus, poeCurrent, poeMax, poeRemaining, dev_id)
	
poeStatusMandatoryPOE Status
poeCurrentOptionalcurrent PoE usage for the whole device
poeMaxOptionalMaximum PoE output of the device
poeRemainingMandatoryAvailable PoE output
dev_idMandatoryDevice ID of the device to which this information should be attached to


insertPoeIntf: Add interface related PoE information.

	insertPoeIntf(
		string poeStatus, 
		string poeWatt, 
		string poeWattmax, 
		string poeDevice, 
		string intfName, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertPoeIntf(poeStatus, poeWatt, poeWattmax, poeDevice, intfName, dev_id)
	
poeStatusMandatoryPOE Status
poeWattMandatorycurrent POE usage
poeWattmaxOptionalmaximum POE Output
poeDeviceOptionalPOE end device
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
dev_idMandatoryDevice ID of the device to which this information should be attached to


insertRoute: Add IPv4 routes

	insertRoute(
		string prot, 
		string ip, 
		string prefix, 
		string nh, 
		string intf, 
		string type, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertRoute(protocol, ip, prefix, nextHop, intf, type, dev_id)
	
protMandatoryRouting Protocol
ipMandatoryNetwork Address
prefixMandatorySubnet Mask: Mask is needed in /Prefix format; If in SubnetMask format, then use ParserDB:maskToBits() function to change format
nhMandatoryNext Hop
intfMandatoryInterface Name: Use ParserDB:intfNameChange() to normalize the Interface name
typeOptionalType, for future use, Leave empty ("")
dev_idMandatoryDevice ID of the device to which this information should be attached to


insertRpGlobal: Add global Routing Protocol information

	insertRpGlobal(
		string bgpAS, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertRpNeighbor(bgpAS, dev_id)
	
bgpASMandatoryBGP AS number
dev_idMandatoryDevice ID of the device to which this information should be attached to


insertRpNeighbor: Add a Routing Protocol Neighbor

	insertRpNeighbor(
		string rp, 
		string neighborID, 
		string neighborIntfIP, 
		string uptime, 
		string neighborState, 
		string neighborStateChanges, 
		string neighborAS,
		string intfName, 
		string dev_id
		)
	

Usage:

Optional arguments may be empty strings (""), but must be set.

	ParserDB:insertRpNeighbor(rp, neighborID, neighborIntfIP, uptime, neighborState, neighborStateChanges, neighborAS, intfName, dev_id)
	
rpMandatoryRouting Protocol
neighborIDMandatoryNeighbor ID
neighborIntfIPMandatoryNeighbor Interface IP
uptimeOptionalNeighbor Uptime
neighborStateMandatoryNeighbor State
neighborStateChangesOptional# Neighbor State Changes
neighborASOptionalNeighbor AS#
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
dev_idMandatoryDevice ID of the device to which this information should be attached to


insertSnmp: Add SNMP Location to a device

	insertSnmp(
		string snmpLoc, 
		string dev_id
		)
	

Usage:

	ParserDB:insertSnmp(snmpLoc, dev_id)
	
snmpLocMandatorySNMP Location
dev_idMandatoryDevice ID of the device to which this information should be attached to


insertSnoopingDev: Add device-specific IP DHCP Snooping information

	insertSnoopingDev(
		string dhcpSnoopState, 
		string dhcpSnoopVlans,
		string dhcpSnoop82,
		string dev_id
		)
	

Usage:

	ParserDB:insertSnoopingDev(dhcpSnoopState, dhcpSnoopVlans, dhcpSnoop82, dev_id)
	
dhcpSnoopStateMandatoryGlobal DHCP Snooping Status
dhcpSnoopVlansOptionalDHCP Snooping VLANs
dhcpSnoop82OptionalDHCP Option 82 Status
dev_idMandatoryDevice ID of the device to which this information should be attached to


insertSnoopingIntf: Add IP DHCP Snooping Interface information

	insertSnoopingIntf(
		string dhcpSnoopingTrust, 
		string intfName,
		string dev_id
		)
	

Usage:

	ParserDB:insertSnoopingIntf(dhcpSnoopingTrust, intfName, dev_id)
	
dhcpSnoopingTrustMandatoryDHCP Snooping Trust?
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
dev_idMandatoryDevice ID of the device to which this information should be attached to


insertSTPInstance: Add a new STP instance; Vlans and interfaces will can be bound to this instance later; Returns the Instance ID

	string insertSTPInstance(string stpPrio, string stpRootPort)
	

Usage:

	ParserDB:insertSTPInstance(stpPrio, stpRootPort)
	
stpPrioMandatoryLocal STP Priority for this instance
stpRootPortMandatorySTP Root Port for this instance


insertSTPStatus: Add the current STP status of an interface; This may be VLAN related

	insertSTPStatus(
		string dev_id,
		string intfName, 
		string stpIntfStatus, 
		string designatedRootID, 
		string designatedBridgeID, 
		string stpTransitionCount, 
		string vlanid, 
		bool intVlan,
		string statsOnly
		)
	

Usage:

	ParserDB:insertSTPStatus(dev_id, intfName, stpIntfStatus, designatedRootID, designatedBridgeID, stpTransitionCount, vlanid, intVlan)
	
dev_idMandatoryDevice ID of the device to which this information should be attached to
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
stpIntfStatusMandatorySTP Port-Status
designatedRootIDMandatoryRoot ID; Use ParserDB:macAddChange() to normalize the MAC address format.
designatedBridgeIDMandatoryDesignated Bridge ID; Use ParserDB:macAddChange() to normalize the MAC address format.
stpTransitionCountOptionalSTP Transition Count
vlanidOptionalVLAN ID, Optional if intVlan set to "false"
For MST use the following Values:
  • 9999: IST Instance
  • 9xxx: Where xxx ist the MST instance ID
  • -> VLAN IDs 9000-9999 are reserved for MST
intVlanMandatoryIf the STP status shall be attached to an interface, VLAN or MST Instance, this option must be set to "true".
statsOnlyOptionalDefault = "0"; Is entry only for statistic purposes? 0...NO; 1...YES


insertVlan: Add a VLAN to the DB and attach an STP instance to it; Returns the DB vlan_id

	string insertVlan(
		string vlanNr, 
		string dev_id, 
		string stpInstance
		)
	

Usage:

	vlan_id = ParserDB:insertVlan(vlanNr, dev_id, stpInstance)
	
vlanNrMandatoryVLAN ID
dev_idMandatoryDevice ID of the device to which this information should be attached to
stpIntanceMandatorySTP Instance ID; Leave empty if not applicable


insertVrf: Add a vrf; Returns the DB vrf_id

	string insertVrf(
		string vrfName, 
		string rd, 
		string rtI, 
		string rtE
		)
	

Usage:

	vrf_id = ParserDB:insertVrf(vrfName, rd, importTarget, exportTarget)
	
vrfNameMandatoryVRF Name
rdMandatoryRD
rtIOptionalImport Route Target
rtEOptionalExport Route Target


insertVrfLink: Attach a vrf to an interface and device.

	insertVrfLink(
		string intfName, 
		string dev_id, 
		string vrf_id
		)	
	

Usage:

	ParserDB:insertVrfLink(intfName, dev_id, vrf_id)	
	
intfNameMandatoryInterface Name; Use ParserDB:intfNameChange() to normalize the Interface name.
dev_idMandatoryDB Device ID
vrf_idOptionalDB VRF ID


intfNameChange: Interface Name Normalizer.

	string intfNameChange(
		string intfName
		)	
	

Usage:

	intfName = ParserDB:intfNameChange(intfName)	
	
intfNameMandatoryInterface Name; It is very important to normalize the interface names to have the same name across all show output.


intfPhlCheck: To set the Interface Type (physical or logical). This is needed for neighborship calculation to make sure that no physical interface is attached to a logical interface. The value is needed to insert an interface to the DB.

	intfPhlCheck(
		string intfName,
		string intfSpeed
		)	
	

Usage:

	phl = ParserDB:intfPhlCheck(intfName, intfSpeed)	
	
intfNameMandatoryNormalized Interface Name
intfSpeedMandatoryInterface Speed


intfTypeCheck: To set the Interface Type in terms of Speed, Subinterface, Port-Channel... This is needed to make sure only interfaces with the same type (i.e. both of type GE) are connected to each other. The value is needed to insert an interface to the DB.

	intfTypeCheck(
		string intfName,
		string intfSpeed
		)	
	

Usage:

	type = ParserDB:intfTypeCheck(intfName, intfSpeed)	
	
intfNameMandatoryNormalized Interface Name
intfSpeedMandatoryInterface Speed


insertSubnet: To insert IP subnets to the DB and attach it to an interface.

	insertSubnet(
		string intfip, 
		string intfmask, 
		string intf_id
		)
	

Usage:

	ParserDB:insertSubnet(interfaceIP, interfaceSubnetMask, intf_id)
	
intfipMandatoryIP Address
intfmaskMandatorySubnet Mask in /Bit format; Use ParserDB:maskToBits() function to convert from dotted decimal to /Bit format.
intf_idMandatoryInterface ID


macAddChange: MAC address normalizer - returns the MAC address in "abcd.ef12.3456" format, which is needed for wktools to calculate neighborships.

	string macAddChange(
		string macAddress
		)
	

Usage:

	macAddress = ParserDB:macAddChange(macAddress)
	
macAddressMandatoryMAC address


markNeighbor: To mark entries in the DB neighbor table (MAC & IP addresses of th device itself). This helps neighborship calculation.

	markNeighbor(
		string dev_id
		)
	

Usage:

	ParserDB:markNeighbor(dev_id)
	
dev_idMandatoryDevice ID


markVethMember: Add Interface ID of the associated physical interface to an Veth interface.

	markVethMember(
		string dev_id, 
		string boundToIntf, 
		string intf_id
		)
	

Usage:

	ParserDB:markVethMember(dev_id, boundToIntf, intf_id)
	
dev_idMandatoryDevice ID
boundToIntfMandatoryInterface Name of the physical Interface
intf_idMandatoryInterface ID of the Veth Interface


markVPC: Add global vPC information (or similar for Non-Cisco devices).

	markVPC(
		string dev_id, 
		string vpcDomId, 
		string vpcLink,
		string vpcId
		)
	

Usage:

	ParserDB:markVPC(dev_id, vpcDomId, vpcLink, vpcId)
	
dev_idMandatoryDevice ID
vpcDomIdMandatoryvPC Domain ID
vpcLinkMandatoryvPC Peer Link - Interface Name
vpcIdMandatoryvPC ID of the Peer Link


markVSL: Mark VSL interfaces.

	markVSL(
		string intf_id
		)
	

Usage:

	ParserDB:markVSL(intf_id)
	
intf_idMandatoryInterface ID of the interface to mark


maskToBits: Convert SubnetMask from dotted decimal to /Bit format

	string maskToBits(
		string subnetMask
		)
	

Usage:

	subnetMask = ParserDB:maskToBits(subnetMask)
	
subnetMaskMandatorySubnet Mask to convert


nextHopIntfCheck: Get Interface ID for IP address - This may be helpful when only the IP address is known, but the associated interface is missing.

	string nextHopIntfCheck(
		string ipaddr,
		string dev_id
		)
	

Usage:

	iID = ParserDB:nextHopIntfCheck(ipaddr, dev_id)
	
ipaddrMandatoryIP Address
dev_idMandatoryDevice ID


updateChannelMember: Mark Member Interfaces with Interface ID from Port-Channel Interface

	updateChannelMember(
		string ch_intf_id, 
		string chMem, 
		string dev_id
		)
	

Usage:

	ParserDB:updateChannelMember(ch_intf_id, chMem, dev_id)
	
ch_intf_idMandatoryInterface ID of the Port-Channel Interface
chMemMandatoryString with all Member Interfaces, separated with comma (",") or SPACE.
dev_idMandatoryDevice ID


updateHardware: Updates Hardware-related information of a device/module/component to the DB. Updates only positions not empty (""). Hardware must be inserted with insertHardware() function and may be updated later with updateHardware()

	updateHardware(
		string hModell, 
		string hDescription, 
		string hChassisSN, 
		string hRevision, 
		string hMem, 
		string hBootfile, 
		string hVersion, 
		string hwinfo_id
		)
	

Usage:

	ParserDB:updateHardware(hModell, hDescription, hChassisSN, hRevision, hMem, hBootfile, hVersion, hwinfo_id)
	
hModellMandatoryModel name or Part number
hDescriptionOptionalDescription
hChassisSNOptionalSerial Number
hRevisionOptionalHW Revision number
hMemOptionalMemory size
hBootfileOptionalBootfile
hVersionOptionalSW Version
hwInfo_idMandatoryHW Info ID; Returned by insertHardware()


updateIntfL2Info: To insert switchport-related interface information to the DB.

	updateIntfL2Info(
		string l2AdminMode, 
		string l2Mode, 
		string l2encap, 
		string dtp, 
		string nativeAccess, 
		string voiceVlan, 
		string opPrivVlan, 
		string allowedVlan, 
		string intf_id
		)
	

Usage:

	ParserDB:updateIntfL2Info(l2AdminMode, l2Mode, l2encap, dtp, nativeAccess, voiceVlan, opPrivVlan, allowedVlan, intf_id)
	
l2AdminModeMandatoryL2 Admin Mode
l2ModeMandatoryL2 Operational Mode
l2encapMandatoryL2 Encapsulation
dtpMandatoryDTP Status
nativeAccessMandatoryNative and Access Vlan Id (Depends on Operational Mode)
voiceVlanMandatoryVoice Vlan ID
opPrivVlanMandatoryPrivate VLAN Status
allowedVlanMandatoryAllowed VLANs (Trunk)
intf_idMandatoryInterface ID


updateSTP: Add device-specific STP information

	updateSTP(
		string stpBridgeID, 
		string stpProtocol, 
		string dev_id
		)
	

Usage:

	ParserDB:updateSTP(stpBridgeID, stpProtocol, dev_id)
	
stpBridgeIDMandatorySTP Bridge ID (Needs Normalization -> macAddChange()
stpProtocolMandatorySTP Protocol
dev_idMandatoryDevice ID


updateSubInterfaces: Add Interface ID of physical interface to subinterface DB entry.

	updateSubInterfaces(
		string intf_id, 
		string mintf_id, 
		string dev_id
		)
	

Usage:

	ParserDB:updateSubInterfaces(intf_id, mintf_id, dev_id)
	
intf_idMandatorySubInterface Interface ID
mintf_idMandatoryPhysical Interface ID
dev_idMandatoryDevice ID





5. Example: Lua Parser for HP ProCurve devices

A small sample script for HP ProCurve devices will show the usage of the Lua API. The script is added to all further wktools releases. Please send changes or new scripts to wktools@spoerr.org to add them to the sample list.

Notice: The script is only used as Proof of Concept and contains little error handling and minimum testing was done!

-- HP Procurve Parser for wktools
-- For reference and documentation
-- !! This script contains only minimum error handling !!
--
-- wktools provides the ParserDB object for all function calls.
-- Print string: "ParserDB:printString(string)"
--
-- !!! This script is only working when using this show command sequence exactly as it is:
-- show version
-- show system
-- show interfaces config
-- show interfaces brief
-- show interfaces all
-- show trunks
-- show vlan
-- show ip
-- show arp
-- show mac-address
-- show spanning-tree
-- show cdp neighbor detail
-- show lldp info rem all
-- show ip route
-- show ip ospf neighbor
-- show module
-- show interfaces transceiver
-- show flash
-- show power-over-ethernet
-- show power-over-ethernet brief
--
-- Trim Whitespace function
function trim(s)
  return s:gsub("^%s+", ""):gsub("%s+$", "")
end

-- Load String to parse; The file was already loaded by wktools
data = ParserDB:getStringToParse()


-- Get Positions for all interesting show commands
pos01, pos010 = data:find("show version.-show system")
pos02, pos020 = data:find("show system.-show interfaces config")
pos03, pos030 = data:find("show interfaces config.-show interfaces brief")
pos04, pos040 = data:find("show interfaces brief.-show interfaces all")
pos05, pos050 = data:find("show interfaces all.-show trunks")
pos06, pos060 = data:find("show trunks.-show vlan")
pos07, pos070 = data:find("show vlan.-show ip")
pos08, pos080 = data:find("show ip.-show arp")
pos09, pos090 = data:find("show arp.-show mac%-address")
pos10, pos100 = data:find("show mac%-address.-show spanning%-tree")
pos11, pos110 = data:find("show spanning%-tree.-show cdp neighbor detail")
pos12, pos120 = data:find("show cdp neighbor detail.-show lldp info rem all")
pos13, pos130 = data:find("show lldp info rem all.-show ip route.")
pos14, pos140 = data:find("show ip route.-show ip ospf neighbor")
pos15, pos150 = data:find("show ip ospf neighbor.-show module")
pos16, pos160 = data:find("show module.-show interfaces transceiver")
pos17, pos170 = data:find("show interfaces transceiver.-show power%-over%-ethernet")
pos18, pos180 = data:find("show power%-over%-ethernet.-show power%-over%-ethernet brief")
pos19, pos190 = data:find("show power%-over%-ethernet brief.*")

if pos01 ~= nil then
    pos01, pos010 = data:find("Image stamp:.*Boot Image:")
end

-- Position pos04 after table header of "show interfaces brief" table
if pos04 ~= nil then
    postemp, pos04 = data:find("%- %+ %-.-\n", pos04)
end

-- Position pos06 after table header of "show trunks" table
if pos06 ~= nil then
    postemp, pos06 = data:find("%- %+ %-.-\n", pos06)
end

-- Position pos07 after table header of "show vlan" table
if pos07 ~= nil then
    postemp, pos07 = data:find("%- %+ %-.-\n", pos07)
end
-- Position pos08 after table header of "show ip" table
if pos08 ~= nil then
    postemp, pos08 = data:find("%- %+ %-.-\n", pos08)
end

-- Position pos14 after table header of "show ip route" table
if pos14 ~= nil then
    postemp, pos14 = data:find("%-%-%-.-\n", pos14)
end

-- Position pos09 after table header of "show arp" table
if pos09 ~= nil then
    postemp, pos09 = data:find("%-%-%-.-\n", pos09)
end

-- Position pos10 after table header of "show mac-address" table
if pos10 ~= nil then
    postemp, pos10 = data:find("%-%-%-.-\n", pos10)
end

-- Position pos17 after table header of "show interfaces transceiver" table
if pos17 ~= nil then
    postemp, pos17 = data:find("%-%-%-.-\n", pos17)
end


-- Extract the needed show data to work with it later on
ver = data:sub(pos01, pos010)			-- OK
sys = data:sub(pos02, pos020)			-- OK
icon = data:sub(pos03, pos030)			-- Parser not included
ibrief = data:sub(pos04, pos040)		-- OK
iall = data:sub(pos05, pos050)			-- OK
trunk = data:sub(pos06, pos060)			-- OK
vlan = data:sub(pos07, pos070)			-- OK
ip = data:sub(pos08, pos080)			-- OK
arp = data:sub(pos09, pos090)			-- OK
mac = data:sub(pos10, pos100)			-- OK
stp = data:sub(pos11, pos110)			-- OK
cdp = data:sub(pos12, pos120)			-- OK - Some devices are not included due to lack of needed data
lldp = data:sub(pos13, pos130)			-- OK - Some devices are not included due to lack of needed data
iproute = data:sub(pos14, pos140)		-- OK
ospf = data:sub(pos15, pos150)			-- Parser not included
module = data:sub(pos16, pos160)		-- OK
itrans = data:sub(pos17, pos170)		-- OK
poe = data:sub(pos18, pos180)			-- OK
poebrief = data:sub(pos19, pos190)		-- OK

--------------------------------------------------------------------------------------------------------------

-- "show version" Parser
-- Image File
ParserDB:printString("show version & show system\r\n")
apos1, apos2 = ver:find("/%g*")
bootimage = ver:sub(apos1, apos2)

-- Version
apos1, apos2 = ver:find("%u%.%g*")
version = ver:sub(apos1, apos2)

-- "show system" Parser
-- Hostname
apos1, apos2 = sys:find("System Name        : ")
apos1, apos2 = sys:find("%g*", apos2+1)
hostname = sys:sub(apos1, apos2)

-- SW Version
apos1, apos2 = sys:find("Software revision  : ")
apos1, apos2 = sys:find("%g*", apos2+1)
version = sys:sub(apos1, apos2)

-- S/N
apos1, apos2 = sys:find("Serial Number      : ")
apos1, apos2 = sys:find("%g*", apos2+1)
sn = sys:sub(apos1, apos2)

-- Base MAC
apos1, apos2 = sys:find("Base MAC Addr      : ")
apos1, apos2 = sys:find("%g*", apos2+1)
basemac = sys:sub(apos1, apos2)
-- MAC Address Normalization in case format is not like aaaa.bbbb.cccc
basemac = ParserDB:macAddChange(basemac)

-- SNMP Location
apos1, apos2 = sys:find("System Location    :")
apos1, apos2 = sys:find("%g*", apos2+2)
location = sys:sub(apos1, apos2)

-- Insert Device
-- Set the following values for type and deviceType
-- 1 Router
-- 2 Switch
-- 3 Firewall
-- 4 AccessPoint
-- 8 L3 Switch
-- 6 VoiceGateway
-- 11 Phone
-- 12 End-system
-- 13 ATA
-- 14 Camera
dev_id = ParserDB:insertDevice(hostname, "2", "2", "")
ParserDB:insertSnmp(location, dev_id)

--------------------------------------------------------------------------------------------------------------

function split(inputstr, sep)
		
		if sep == nil then
                sep = "%s"
        end
        t={} ; i=1
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                t[i] = str
                i = i + 1
        end
        return t
end

--------------------------------------------------------------------------------------------------------------

-- "show interfaces brief" && "show interfaces all " Parser
-- "show interfaces config" is not needed at the moment
ParserDB:printString("show interfaces brief & show interfaces all\r\n")

function readIntfAll(intfName)
	ipos1, ipos2 = iall:find("for port " .. intfName .. ".-Utilization Tx.-\n")
	currentInt = iall:sub(ipos1, ipos2)
	
	-- Interface Name/Description
	ipos1, ipos2 = currentInt:find("Name  :")
	ipos1, ipos2 = currentInt:find("[%g ]-", ipos2+2)
	intfDescription = currentInt:sub(ipos1, ipos2)

	
	-- MAC Address if available
	macAddress = ""
	ipos1, ipos2 = currentInt:find("MAC Address      : ")
	if ipos1 ~= nil then
	    ipos1, ipos2 = currentInt:find("%g*", ipos2+1)
	    macAddress = currentInt:sub(ipos1, ipos2)
	end
	
	-- Errors
	ipos1, ipos2 = currentInt:find("FCS Rx          : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eFcs = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Alignment Rx    : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eAlign = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Runts Rx        : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eRunts = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Drops Tx        : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eDrops = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Collisions Tx   : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eColl = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Late Colln Tx   : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eLateColl = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Giants Rx       : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eGiants = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Excessive Colln : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eExcessColl = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Total Rx Errors : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eRxTotal = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Deferred Tx     : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eDefer = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Discard Rx      : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eDiscard = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Out Queue Len   : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eOutQueue = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Unknown Protos  : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eUnknown = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Utilization Rx  : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eRxUtil = currentInt:sub(ipos1, ipos2)
	
	ipos1, ipos2 = currentInt:find("Utilization Tx  : ")
	ipos1, ipos2 = currentInt:find("[%d ]*", ipos2+1)
	local eTxUtil = currentInt:sub(ipos1, ipos2)
		
	return currentInt, intfDescription, macAddress, eFcs, eAlign, eRunts, eDrops, eColl, eLateColl, eGiants, eExcessColl, eRxTotal, eDefer, eDiscard, eOutQueue, eUnknown, eRxUtil, eTxUtil
end

for line in ibrief:gmatch(".-\n") do 
    -- 1) Split line and save the following values: Port, Type, Enabled, Status, Mode, 
	-- 2) Find Port in "show interfaces all" and read the following data: Name, MAC Address, Err Counter
	-- 3) Write Interface into DB
	
	if #line > 10 then
		local tble = split(line, "%s")
		local intfName = tble[1]
		local intfType, intfMode, intfEna, intfStatus, speed, duplex
		if tble[2] == "|" then
			-- Type and Mode empty
			intfEna = tble[4]
			intfStatus = tble[5]
			intfMode = ""
			speed = ""
			duplex = ""
			intfType = ""
		else
			intfEna = tble[5]
			intfStatus = tble[6]
			intfMode = tble[7]
			p1, p2 = intfMode:find("D")
			speed = intfMode:sub(0, p2-2)
			duplex = intfMode:sub(p2-1, #intfMode)
			intfType = tble[2]
		end
		
		iSets = intfSets()
		
		p1 = intfName:find("%-")
		if p1 ~= nil then
			intfName = intfName:sub(1, p1-1)
		end
		
		-- Read Details for this interface:
		currentInt, intfDescription, macAddress, eFcs, eAlign, eRunts, eDrops, eColl, eLateColl, eGiants, eExcessColl, eRxTotal, eDefer, eDiscard, eOutQueue, eUnknown, eRxUtil, eTxUtil = readIntfAll(intfName)
		
		-- Interface Normalizers:
		-- intfNameChange to shorten the Interface Name if needed/possible
		-- intfTypeCheck to unify the Interface operational speed/type
		-- intfPhlCheck to check whether the interface is a phyical or logical interface
		iSets.intfName = ParserDB:intfNameChange(intfName)
		iSets.intfType = ParserDB:intfTypeCheck(intfName, intfMode)
		iSets.phl = ParserDB:intfPhlCheck(intfName, intfMode)
		iSets.nameif = ""
		iSets.macAddress = ParserDB:macAddChange(macAddress)
		iSets.ipAddress = ""
		iSets.subnetMask = ""
		iSets.duplex = duplex
		iSets.speed = speed
		iSets.status = intfStatus
		iSets.description = intfDescription
		iSets.l2l3 = "L2"
		iSets.dev_id = dev_id
		
		-- Insert Interface to DB
		intf_id = ParserDB:insertInterface(iSets)
		
		-- Insert Interface Statistics to DB
		errLvl = tonumber(eFcs) + tonumber(eUnknown) + tonumber(eRunts) + tonumber(eGiants) + tonumber(eColl) + tonumber(eLateColl) + tonumber(eDefer) + tonumber(eAlign) + tonumber(eDrops) + tonumber(eExcessColl) + tonumber(eDiscard) + tonumber(eOutQueue)
		iLoad = tonumber(eRxUtil)*1,25 + tonumber(eTxUtil)*1,25
		iStats = intfStats()
		iStats.errLvl = trim(tostring(errLvl))
		iStats.lastClear = ""
		iStats.loadLvl = trim(tostring(iLoad))
		iStats.iCrc = trim(eFcs)
		iStats.iFrame = trim(eUnknown)
		iStats.iOverrun = ""
		iStats.iIgnored = ""
		iStats.iWatchdog = ""
		iStats.iPause = ""
		iStats.iDribbleCondition = ""
		iStats.ibuffer = ""
		iStats.l2decodeDrops = trim(eDrops)
		iStats.runts = trim(eRunts)
		iStats.giants = trim(eGiants)
		iStats.throttles = ""
		iStats.ierrors = trim(eRxTotal)
		iStats.underrun = ""
		iStats.oerrors = ""
		iStats.oCollisions = trim(eColl)
		iStats.oBabbles = ""
		iStats.oLateColl = trim(eLateColl)
		iStats.oDeferred = trim(eDefer)
		iStats.oLostCarrier = ""
		iStats.oNoCarrier = ""
		iStats.oPauseOutput = ""
		iStats.oBufferSwapped = ""
		iStats.resets = ""
		iStats.obuffer = ""
		iStats.lastInput = ""
		iStats.intf_id = intf_id			
		
		ParserDB:insertIntfStats(iStats)
		
	end
end

--------------------------------------------------------------------------------------------------------------

-- "show trunks" Parser
ParserDB:printString("show trunks\r\n")

trks = {}
trunkIntfId = ""
for line in trunk:gmatch(".-\n") do 
    -- 1) Split line and save the following values: Port, Name, Group
	-- 2) Find intf_id's for Ports 
	-- 3) Write Trunk Interface to DB
	-- 4) Mark Interfaces in DB

	if #line > 10 then
		local tble = split(line, "%s")
		local intfName = tble[1]
		local intfDescription, group
		if tble[4] == "|" then
			-- Type and Mode empty
			group = tble[5]
			intfDescription = ""
		else
			group = tble[6]
			intfDescription = tble[3]
		end
		
		if trks[group] == nil then
			trks[group] = true
			
			iSets = intfSets()
			iSets.intfName = ParserDB:intfNameChange(group)
			iSets.intfType = ParserDB:intfTypeCheck(group, "")
			iSets.phl = ParserDB:intfPhlCheck(group, "")
			iSets.nameif = ""
			iSets.macAddress = ""
			iSets.ipAddress = ""
			iSets.subnetMask = ""
			iSets.duplex = ""
			iSets.speed = ""
			iSets.status = "Up"
			iSets.description = intfDescription
			iSets.l2l3 = "L2"
			iSets.dev_id = dev_id
		
			trunkIntfId = ParserDB:insertInterface(iSets)
		end
		ParserDB:updateChannelMember(trunkIntfId, intfName, dev_id)
	end
end

--------------------------------------------------------------------------------------------------------------

-- "show vlan" && "show ip" Parser
ParserDB:printString("show vlan & show ip\r\n")

function readVlanDetails(vlanName)
	local vpos1, vpos2 = vlan:find("%d-%s-" .. vlanName .. ".-|")
	if vpos1 ~= nil then
		local vline = vlan:sub(vpos1, vpos2)
		local vtble = split(vline, "%s")
		return vtble[2], vtble[1]
	else
		return "", ""
	end
end

for line in ip:gmatch(".-\n") do 
	-- Lookup Vlan-Nr, Vlan-Name in "show vlan" for all Lines in "show ip table"
	-- The connection between the two tables is the VLAN Name
	if #line > 10 then
		str3 = line:sub(3, 3)
		-- Ignore Lines with table headers
		if str3 ~= "-" then
			local tble = split(line, "%s")
			
			-- Secondary IP addresses are only written into the Subnet Table (DB)
			-- Ignore Table headers
			if ((tble[5] ~= "IP") and (tble[3] ~= nil)) then
				if tble[1] == "|" then	-- Handle Secondary IP addresses
					l3intf_id = l3intf_id -- Interface ID is taken from last time
					ipa = tble[3]
					-- Change Subnetmask to /Bit format
					mask = ParserDB:maskToBits(tble[4])
					-- Insert Subnet into Subnet Table (DB)
					ParserDB:insertSubnet(ipa, mask, l3intf_id)
				else	-- Handle Primary IP addresses
					vName = tble[1]
					-- Delete ... at the end of the VLAN Name in "show ip" output
					vName = vName:gsub("%.%.%.", "")
					-- Add the escape character % to the special characters (-.%+*()[]^$); Otherwise they would be used as Patterns 
					vName = vName:gsub("[%-%.%%%+%*%(%)%[%]%^%$]", "%%%0")
					
					if tble[3] == "Disabled" then
						ipa = ""
						mask = ""				
					else
						ipa = tble[4]
						-- Change Subnetmask to /Bit format
						mask = ParserDB:maskToBits(tble[5])
					end
					vlanName, vlanNr = readVlanDetails(vName)
					-- Fill DB Interface Table with L3 Interface Details if IP is available
					if ipa ~= "" then
						iSets = intfSets()
						if vlanNr ~= "" then
							iName = "Vlan" .. vlanNr
							iNameIf = vlanName
							iDescr = vlanName
						else
							iName = vName
							iNameIf = ""
							iDescr = ""
						end
						iSets.intfName = ParserDB:intfNameChange(iName)
						iSets.intfType = ParserDB:intfTypeCheck(iName, "")
						iSets.phl = ParserDB:intfPhlCheck(iName, "")
						iSets.nameif = iNameIf
						iSets.macAddress = ""
						iSets.ipAddress = ipa
						iSets.subnetMask = mask
						iSets.duplex = ""
						iSets.speed = ""
						iSets.status = "Up"
						iSets.description = iDescr
						iSets.l2l3 = "L3"
						iSets.dev_id = dev_id
					
						l3intf_id = ParserDB:insertInterface(iSets)
						-- Insert Subnet into Subnet Table (DB)
						ParserDB:insertSubnet(ipa, mask, l3intf_id)
					end
				
					-- Fill DB VLAN Table; STP Instance not available, so leave the option blank
					if vlanName ~= "" then
						ParserDB:insertVlan(vlanNr, dev_id, "")
					end
				end
			end
		end
	end
end

--------------------------------------------------------------------------------------------------------------

ParserDB:printString("show ip route\r\n")

-- "show ip route" Parser
for line in iproute:gmatch(".-\n") do 
	-- Split Routing Table
	-- Normalize Subnetmask
	-- Ignore 127.0.0.x networks
	-- Insert into DB Routing Table
	if #line > 10 then
		local rtble = split(line, "%s/")
		local subnet = rtble[1]
		-- Mask is needed in /Prefix format; If in SubnetMask format, then use ParserDB:maskToBits function to change format
		local mask = rtble[2]
		local gateway = rtble[3]
		local vlan = rtble[4]
		local rProt
		local pos = vlan:find("%d")
		if pos == nil then
			rProt = rtble[4]
			vlan = ""
		else
			rProt = rtble[5]
		end
		-- Discard 127.0.0.x IPs
		pos = subnet:find("127%.0%.0%.%d-")
		if (pos == nil) and (rProt ~= "connected") then
			-- Insert Route to Routing Table; Keep type field empty, as it is optional at the moment
			-- Ignore Connected Routes				
			-- If interface name is not available, then leave it empty
			local interface = ""
			if vlan ~= "" then
				interface = "Vlan" .. vlan
			end
			ParserDB:insertRoute(rProt, subnet, mask, gateway, interface, "", dev_id)
		end
	end
end

--------------------------------------------------------------------------------------------------------------

-- "show arp" Parser
ParserDB:printString("show arp\r\n")

for line in arp:gmatch(".-\n") do 
	-- Lookup Vlan-Nr, Vlan-Name in "show vlan" for all Lines in "show ip table"
	-- The connection between the two tables is the VLAN Name
	if #line > 10 then
		local atble = split(line, "%s")
		local ipAddress = atble[1]
		local macAddress = ParserDB:macAddChange(atble[2])
		local port = atble[4]
		-- Problem: HP uses the physical switchport (L2) in the ARP table; But it should be the logical port (L3) instead;
		-- -> Port ID must be read from Subnet Table
		local i_id = ParserDB:nextHopIntfCheck(ipAddress, dev_id)
		
		-- Insert ARP entry to neighbor table (DB)
		ParserDB:insertNeighbor(i_id, macAddress, ipAddress, "")
	end
end

--------------------------------------------------------------------------------------------------------------

-- "show mac-address" Parser
ParserDB:printString("show mac-address\r\n")

for line in mac:gmatch(".-\n") do 
	-- Split entries, normalize MAC Address and insert into DB neighbor Table
	if #line > 10 then
		local mtble = split(line, "%s")
		local macAddress = ParserDB:macAddChange(mtble[1])
		-- Don't forget to always use intfNameChange to normalize the Interface Names
		local port = ParserDB:intfNameChange(mtble[2])
		local vlan = mtble[3]
		-- First the Interface ID is needed
		iID = ParserDB:getIntfID(dev_id, port, true)
		-- Then the MAC address can be written into DB; Leave IP Address and Self empty when only adding CAM entries
		ParserDB:insertNeighbor(iID, macAddress, "", "")
	end
end

--------------------------------------------------------------------------------------------------------------

-- "show spanning-tree" Parser
-- 1) Global STP infos
-- STP Protocol
ParserDB:printString("show spanning-tree\r\n")

apos1, apos2 = stp:find("%(.-%)")
stpProtocol = stp:sub(apos1+1, apos2-1)
apos1, apos2 = stp:find("Force Version :")
apos1, apos2 = stp:find("%g*", apos2+2)
stpProtocol = stpProtocol .. "/" .. stp:sub(apos1, apos2)

-- Switch MAC Address
apos1, apos2 = stp:find("Switch MAC Address : ")
apos1, apos2 = stp:find("%g*", apos2+1)
switchSTPMac = stp:sub(apos1, apos2)
switchSTPMac = ParserDB:macAddChange(switchSTPMac)

-- Insert Switch MAC and STP Protocol to device table
ParserDB:updateSTP(switchSTPMac, stpProtocol, dev_id)

-- Switch Priority
apos1, apos2 = stp:find("Switch Priority%s*: ")
apos1, apos2 = stp:find("%g*", apos2+1)
switchSTPPrio = stp:sub(apos1, apos2)

-- Root MAC Address (for MST only CST Root)
apos1, apos2 = stp:find("Root MAC Address : ")
apos1, apos2 = stp:find("%g*", apos2+1)
rootMac = stp:sub(apos1, apos2)
-- Normalize MAC address
rootMac = ParserDB:macAddChange(rootMac)

-- Root Priority (for MST only CST Root)
apos1, apos2 = stp:find("Root Priority%s*: ")
apos1, apos2 = stp:find("%g*", apos2+1)
rootPrio = stp:sub(apos1, apos2)

-- Root Port (for MST only CST Root)
apos1, apos2 = stp:find("Root Port%s*: ")
apos1, apos2 = stp:find("[%g ]*", apos2+1)
rootPort = stp:sub(apos1, apos2)
if rootPort == "This switch is root" then
	rootPort = ""
else
	-- Normalize Interface Name
	rootPort = ParserDB:intfNameChange(rootPort)
end

-- Insert STP Instance
stpInstance = ParserDB:insertSTPInstance(switchSTPPrio, rootPort)
-- Insert Dummy VLAN 9999; This VLAN marks the CST
ParserDB:insertVlan("9999", dev_id, stpInstance)

-- 2) Interface related STP infos
tpos, apos1 = stp:find("%- %+ %-.-\n", apos1)
stpIntf = stp:sub(apos1, #stp)

for line in stpIntf:gmatch(".-\n") do 
	-- Split entries, normalize MAC Address and insert into DB stp_status Table
	if #line > 10 then
		local stble = split(line, "%s|")
		-- Only insert STP Status for Non-Edge Ports
		if ((stble[6] ~= nil) and (stble[9] == "No")) then
			-- OK
			local port = stble[1]
			port = ParserDB:intfNameChange(port)
			local stpStatus = stble[5]
			local designatedBridge = stble[6]
			designatedBridge = ParserDB:macAddChange(designatedBridge)
			
			-- It is very important to set STP Transition Count to "0" instead to ""
			ParserDB:insertSTPStatus(dev_id, port, stpStatus, designatedBridge, designatedBridge, "0", "9999", true)
		end
	end
end

--------------------------------------------------------------------------------------------------------------

-- "show module" Parser
-- 1) Chassis Info
ParserDB:printString("show module\r\n")

apos1, apos2 = module:find("Status and Counters %- Module Information.-Slot Module Description")
chassis = module:sub(apos1, apos2)
apos1, apos2 = chassis:find("Chassis: ")
apos1, apos2 = chassis:find("%g*%s%g*", apos2+1)
if apos1 ~= nil then
	chassisType = chassis:sub(apos1, apos2)
	apos1, apos2 = chassis:find("Serial Number:%s*")
	apos1, apos2 = chassis:find("%g*", apos2+1)
	chassisSN = chassis:sub(apos1, apos2)
	position = "box"
	-- Insert Chassis information and save id; Important: Always use "box" for Chassis position because of wktools internal special handling
	chassis_id = ParserDB:insertHardware(position, chassisType, "", chassisSN, "", "", bootimage, version, dev_id, "")
end
apos1, apos2 = chassis:find("Management Module: ")
if apos1 ~= nil then
	moduleDescr = "Management Module"
	apos1, apos2 = chassis:find("%g*", apos2+1)
	moduleType = chassis:sub(apos1, apos2)
	apos1, apos2 = chassis:find("Serial Number:%s*", apos2)
	apos1, apos2 = chassis:find("%g*", apos2+1)
	moduleSN = chassis:sub(apos1, apos2)	
	position = "MM"
	-- Attach modules to the chassis by passing the DB id of the cahssis...
	ParserDB:insertHardware(position, moduleType, moduleDescr, moduleSN, "", "", "", "", dev_id, chassis_id)
end

-- 2) Module Info
apos1, apos2 = module:find("%-%-%-%-.-show interfaces transceiver")
ptemp, apos1 = module:find(".-\n", apos1)
modules = module:sub(apos1, apos2)
for line in modules:gmatch(".-\n") do 
	-- Split entries, 
	if #line > 77 then
		position = trim(line:sub(1, 7))
		moduleType = trim(line:sub(8, 16))
		if moduleType:find("ProCurve") ~= nil then
			moduleType = trim(line:sub(8, 23))
			moduleDescr = trim(line:sub(24, 46))
		else
			moduleDescr = trim(line:sub(17, 46))
		end
		moduleSN = trim(line:sub(47, 61))
		hwVersion = trim(line:sub(77, #line))
		-- Attach modules to the chassis by passing the DB id of the cahssis...
		ParserDB:insertHardware(position, moduleType, moduleDescr, moduleSN, hwVersion, "", "", "", dev_id, chassis_id)
	end
end
	
--------------------------------------------------------------------------------------------------------------

-- "show interfaces transceiver" Parser
ParserDB:printString("show interfaces transceiver\r\n")

for line in itrans:gmatch(".-\n") do 
	-- Split entries and insert into HW Table
	if #line > 10 then
		local ittble = split(line, "%s|")
		if ittble[5] ~= nil then
			position = ittble[1]
			moduleType = ittble[3]
			moduleDescr = ittble[2] .. "; Part#: " .. ittble[5]
			moduleSN = ittble[4]
			hwVersion = ""
			ParserDB:insertHardware(position, moduleType, moduleDescr, moduleSN, hwVersion, "", "", "", dev_id, chassis_id)
		end
	end
end
	
--------------------------------------------------------------------------------------------------------------

-- "show cdp neighbor detail" Parser

ParserDB:printString("show cdp neighbor detail\r\n")

apos1 = 0
apos2 = 0
while true do
	apos1, apos2 = cdp:find("Local Port .-Version      :.-\n", apos2)
	if apos1 == nil then
		break
	end
	cdpNeighbor = cdp:sub(apos1, apos2)
	local cpos1, cpos2 = cdpNeighbor:find("Device ID : ")
	cpos1, cpos2 = cdpNeighbor:find("[%g ]*", cpos2+1)
	deviceID = cdpNeighbor:sub(cpos1, cpos2)

	-- Skip HP Procurve Devices since CDP information is not sufficient; These devices will be discovered with "show lldp..."
	tpos1 = deviceID:find("%g%g %g%g %g%g %g%g %g%g %g%g")
	if tpos1 == nil then
		cpos1, cpos2 = cdpNeighbor:find("Port : ")
		cpos1, cpos2 = cdpNeighbor:find("%g*", cpos2+1)	
		localPort = cdpNeighbor:sub(cpos1, cpos2)
		localPort = ParserDB:intfNameChange(localPort)

		cpos1, cpos2 = cdpNeighbor:find("Address      : ")
		cpos1, cpos2 = cdpNeighbor:find("[%g]*", cpos2+1)	
		ipAddress = cdpNeighbor:sub(cpos1, cpos2)

		cpos1, cpos2 = cdpNeighbor:find("Platform     : ")
		cpos1, cpos2 = cdpNeighbor:find("[%g ]*", cpos2+1)	
		platform = cdpNeighbor:sub(cpos1, cpos2)

		cpos1, cpos2 = cdpNeighbor:find("Capability   : ")
		cpos1, cpos2 = cdpNeighbor:find("[%g ]*", cpos2+1)	
		capability = cdpNeighbor:sub(cpos1, cpos2)
		-- Set the following values for type and deviceType
		-- 1 Router
		-- 2 Switch
		-- 3 Firewall
		-- 4 AccessPoint
		-- 8 L3 Switch
		-- 6 VoiceGateway
		-- 11 Phone
		-- 12 End-system
		-- 13 ATA
		-- 14 Camera
		-- 99 Unknown
		if capability == "Switch" then
			nType = "2"
		elseif capability == "Router Switch" then
			nType = "8"
		else
			nType = "99"
		end

		cpos1, cpos2 = cdpNeighbor:find("Device Port  : ")
		cpos1, cpos2 = cdpNeighbor:find("[%g ]*", cpos2+1)	
		remotePort = cdpNeighbor:sub(cpos1, cpos2)
		remotePort = ParserDB:intfNameChange(remotePort)

		cpos1, cpos2 = cdpNeighbor:find("Version      : ")
		cpos1, cpos2 = cdpNeighbor:find("[%g ]*", cpos2+1)	
		version = cdpNeighbor:sub(cpos1, cpos2)

		-- Add neighbor to CDP table
		ParserDB:insertCDP(hostname, deviceID, deviceID, localPort, ipAddress,remotePort, nType, platform, version, dev_id)
	end
end

--------------------------------------------------------------------------------------------------------------

-- "show lldp..." Parser
ParserDB:printString("show lldp...\r\n")

apos1 = 0
apos2 = 0
while true do
	apos3 = apos2
	apos1, apos2 = lldp:find("Local Port.-%-%-%-%-", apos2)
	if apos1 == nil then
		apos1, apos2 = lldp:find("Local Port", apos3)
		if apos1 == nil then
			break
		else
			apos2 = #lldp
		end
	end
	lldpNeighbor = lldp:sub(apos1, apos2)
	
	local cpos1, cpos2 = lldpNeighbor:find("SysName      : ")
	if cpos1 ~= nil then
		cpos1, cpos2 = lldpNeighbor:find("[%g ]*", cpos2+1)
		deviceID = lldpNeighbor:sub(cpos1, cpos2)
	else
		deviceID = ""
	end
	
	cpos1, cpos2 = lldpNeighbor:find("ChassisId    : ")
	cpos1, cpos2 = lldpNeighbor:find("[%g ]*", cpos2+1)
	chassisID = lldpNeighbor:sub(cpos1, cpos2)
	
	if deviceID == "" then
		deviceID = chassisID
		alternateDeviceID = deviceID
	else
		-- Concatenate deviceID and chassisID
		-- This is for switches with Default Hostname to keep them apart
		alternateDeviceID = deviceID .. "." .. chassisID:gsub(" ", "")
	end

	tpos1 = deviceID:find("%g%g %g%g %g%g %g%g %g%g %g%g")
	if tpos1 == nil then
		cpos1, cpos2 = lldpNeighbor:find("Local Port   : ")
		cpos1, cpos2 = lldpNeighbor:find("%g*", cpos2+1)	
		localPort = lldpNeighbor:sub(cpos1, cpos2)
		localPort = ParserDB:intfNameChange(localPort)

		cpos1, cpos2 = lldpNeighbor:find("Address : ")
		cpos1, cpos2 = lldpNeighbor:find("[%g]*", cpos2+1)	
		ipAddress = lldpNeighbor:sub(cpos1, cpos2)

		cpos1, cpos2 = lldpNeighbor:find("System Descr : ")
		cpos1, cpos2 = lldpNeighbor:find("[%g ]*", cpos2+1)	
		platform = lldpNeighbor:sub(cpos1, cpos2)

		cpos1, cpos2 = lldpNeighbor:find("System Capabilities Enabled    : ")
		if cpos1 ~= nil then
			cpos1, cpos2 = lldpNeighbor:find("[%g ]*", cpos2+1)	
			capability = lldpNeighbor:sub(cpos1, cpos2)
		else
			capability = ""
		end
		
		-- Set the following values for type and deviceType
		-- 1 Router
		-- 2 Switch
		-- 3 Firewall
		-- 4 AccessPoint
		-- 8 L3 Switch
		-- 6 VoiceGateway
		-- 11 Phone
		-- 12 End-system
		-- 13 ATA
		-- 14 Camera
		-- 99 Unknown
		if capability == "bridge" then
			nType = "2"
		elseif capability == "bridge, router" then
			nType = "8"
		else
			nType = "12"
		end

		cpos1, cpos2 = lldpNeighbor:find("PortId       : ")
		cpos1, cpos2 = lldpNeighbor:find("[%g ]*", cpos2+1)	
		remotePort = lldpNeighbor:sub(cpos1, cpos2)
		remotePort = ParserDB:intfNameChange(remotePort)

		version = ""

		-- Add neighbor to CDP table
		ParserDB:insertCDP(hostname, deviceID, alternateDeviceID, localPort, ipAddress,remotePort, nType, platform, version, dev_id)
	end
end

--------------------------------------------------------------------------------------------------------------

-- "show power-over-ethernet" Parser
ParserDB:printString("show power-over-ethernet\r\n")

apos1, apos2 = poe:find("Total Available Power  :")
if apos1 ~= nil then
	-- Total PoE
	apos1, apos2 = poe:find("[%g ]*", apos2+1)
	poeTotal = trim(poe:sub(apos1, apos2))

	-- Used PoE
	apos1, apos2 = poe:find("Total used Power       :")
	apos1, apos2 = poe:find("[%g ]*", apos2+1)
	poeUsed = trim(poe:sub(apos1, apos2))

	-- Remaining PoE
	apos1, apos2 = poe:find("Total Remaining Power  :")
	apos1, apos2 = poe:find("[%g ]*", apos2+1)
	poeRemain = trim(poe:sub(apos1, apos2))
	
	ParserDB:insertPoeDev("ON", poeUsed, poeTotal, poeRemain, dev_id)
end

--------------------------------------------------------------------------------------------------------------

-- "show power-over-ethernet" Parser
ParserDB:printString("show power-over-ethernet brief\r\n")

for line in poebrief:gmatch(".-\n") do 
	-- Split entries and insert into Intf Table
	if #line > 10 then
		
		local potble = split(line, "%s")
		if potble[11] ~= nil then
			port = potble[1]
			poeCurrent = potble[8]
			poeMax = potble[6]
			poeStat = potble[3]

			ParserDB:insertPoeIntf(poeStat, poeCurrent, poeMax, "", port, dev_id)
		end
	end
end

--------------------------------------------------------------------------------------------------------------

-- Global --
ParserDB:markNeighbor(dev_id)





 wktools Version 4 Documentation
  (c) 2003 - 2013 by Mathias Spoerr