Comparison script for bytes value mikrotik - mikrotik

i want to comparison bytes value (tx-bytes,rx-bytes) downloaded by user with my pattern for example (100MiB, 50MiB)
but i can't write script for solve this , how can i do that ?
the place i want write script for that is : /interface wireless registration-table > tx-rx bytes value
(an image of this Place)

As you state, you can query registration table using /interface wireless registration-table. Putting this on a scripting loop gives
:foreach wirelessClient in [/interface wireless registration-table find true] do={}
then, in this foreach loop, get each client's statistics using the id (example here with "mac-address" and "bytes" fields)
:local macAddress [/interface wireless registration-table get [ find .id=$wirelessClient ] value-name=mac-address];
:local bytes [/interface wireless registration-table get [ find .id=$wirelessClient ] value-name=bytes];
The "bytes" data returned is in format "RX,TX" (i.e "545124,25422"). So you have to do a little trick to extract the RX string: look for the "," character and extract string before this comma.
:local posComma [ :find $bytes "," -1]
:local RXbytes [:pick $bytes 0 $posComma]
Then, it's easy to check if that client has downloaded more than 50M
:local status "Below 50M";
:if ($RXbytes > 50000000) do={
:set $status "Above 50M"
}
:put "Client: $macAddress $bytes $RXbytes -> $status";
Put all together in a script and execute it, you will get something like
[foo#bar] > import test.rsc
Client: D4:CA:6D:B2:AE:EF 202134,92985 202134 -> Below 50M
Client: 48:9D:24:64:E6:08 8057465,2022134 8057465 -> Below 50M
Client: 2C:56:DC:32:09:F0 3282973,888408 3282973 -> Below 50M
Client: 48:59:29:F6:DF:5D 139664,248984 139664 -> Below 50M
Client: A4:5E:60:EB:AE:33 159890028,12433385 159890028 -> Above 50M
For the complete Mikrotik scripting manual, check http://wiki.mikrotik.com/wiki/Manual:Scripting

Related

Change or personalize OID

Finally managed to have my RPI computer module to work with SNMP.
I have a script running that gives me one of my parameters and if I use query using SNMP I get the info back.
pi#raspberrypi:~ $ snmpwalk -v2c -c public localhost NET-SNMP-EXTEND-MIB::nsExtendObjects | grep snmp_status
NET-SNMP-EXTEND-MIB::nsExtendCommand."snmp_status" = STRING: /home/pi/BDC/snmp_status.py
NET-SNMP-EXTEND-MIB::nsExtendArgs."snmp_status" = STRING:
NET-SNMP-EXTEND-MIB::nsExtendInput."snmp_status" = STRING:
NET-SNMP-EXTEND-MIB::nsExtendCacheTime."snmp_status" = INTEGER: 5
NET-SNMP-EXTEND-MIB::nsExtendExecType."snmp_status" = INTEGER: exec(1)
NET-SNMP-EXTEND-MIB::nsExtendRunType."snmp_status" = INTEGER: run-on-read(1)
NET-SNMP-EXTEND-MIB::nsExtendStorage."snmp_status" = INTEGER: permanent(4)
NET-SNMP-EXTEND-MIB::nsExtendStatus."snmp_status" = INTEGER: active(1)
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."snmp_status" = STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."snmp_status" = STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."snmp_status" = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendResult."snmp_status" = INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."snmp_status".1 = STRING: 0
If my unit is in alarm replies with
NET-SNMP-EXTEND-MIB::nsExtendOutLine."snmp_status".1 = STRING: 1
if not in alarm replies with
NET-SNMP-EXTEND-MIB::nsExtendOutLine."snmp_status".1 = STRING: 0
This status is stored in a file and it's parsed to the SNMP using a python script.
Now... next question.
The SNMP server gives me the following OID
.1.3.6.1.4.1.8072.1.3.2.3.1.2.11.115.110.109.112.95.115.116.97.116.117.115
and for each parameter it gives me one very different IOD.
How can I change this for something more easy... like the ones we see on MIB files?
If you are doing it in the command line, use
snmptranslate -m NET-SNMP-EXTEND-MIB .1.3.6.1.4.1.8072.1.3.2.3.1.2.11.115.110.109.112.95.115.116.97.116.117.115
To do it purely programmatically (i.e. without parsing command line output), you will need a way to parse the MIB files. I think such tools probably exist in Python, but I've never used them myself.
More often, I hard-code constants for the OIDs that I'm interested in, and manually inspect the MIB to know how to decode the index for each object. The OID you gave is an instance of NET-SNMP-EXTEND-MIB::nsExtendOutputFull, which belongs to nsExtendOutput1Entry. Normally the *Entry types will have an INDEX field telling you which field is used as the index of that table. In this case, it has an AUGMENTS field instead, which points you to nsExtendConfigEntry. The INDEX fornsExtendConfigEntry is nsExtendToken, which has a type of DisplayString (basically an OCTET STRING that is limited to human-readable characters).
Here's an example of how I would do this in Python -- you'll need pip install snmp:
from snmp.types import OID, OctetString
nsExtendOutputFull = OID.parse(".1.3.6.1.4.1.8072.1.3.2.3.1.2")
oid = OID.parse(".1.3.6.1.4.1.8072.1.3.2.3.1.2.11.115.110.109.112.95.115.116.97.116.117.115")
nsExtendToken = oid.extractIndex(nsExtendOutputFull, OctetString)
print(f"Index = {nsExtendToken}")
Here's the output:
Index = OctetString(b'snmp_status')

Omnetpp.ini - How to create loop for the host parametres

I have 1000 hosts. I need to simulate the situation when host[0] connects with other 999 hosts by PingApp in accordance with a timetable.
For example
**.host[0]*.numPingApps = 999 #number of hosts
**.host[0]*.pingApp[*].typename = "PingApp"
**.host[0]*.pingApp[*].packetSize = 42 B
**.host[0]*.pingApp[*].sendInterval = 1 s
**.host[0]*.pingApp[*].srcAddr = "host[0]"
**.host[0]*.pingApp[0].destAddr = "host[1]"
**.host[0]*.pingApp[0].startTime = 0 s
**.host[0]*.pingApp[0].stopTime = 5s
**.host[0]*.pingApp[1].destAddr = "host[2]"
**.host[0]*.pingApp[1].startTime = 0.1 s
**.host[0]*.pingApp[1].stopTime = 5.1 s
**.host[0]*.pingApp[2].destAddr = "host[3]"
**.host[0]*.pingApp[2].startTime = 0.2 s
**.host[0]*.pingApp[2].stopTime = 5.2 s
**.host[0]*.pingApp[3].destAddr = "host[4]"
**.host[0]*.pingApp[3].startTime = 0.3 s
**.host[0]*.pingApp[3].stopTime = 5.3 s
and so on...
How can I create the loop for automatic changes of parameters: startTime, stopTime, destAddr, number of pingApp?
I need to increase startTime and stopTime by 0.1s at every step of one point increase of pingApp number and destAddr.
Help me please!
Thank you!
Actually, every host should have only one Ping Application. To achieve your goal you can use the following settings:
**.host[*].numApps = 1
**.host[*].app[0].typename = "PingApp"
**.host[999].app[0].destAddr = "host[0]"
**.host[*].app[0].destAddr = "host[" + string(parentIndex()+1) + "]"
**.host[*].app[0].startTime = replaceUnit (0.1*(parentIndex()), "s")
**.host[*].app[0].stopTime = replaceUnit (5 + 0.1*(parentIndex()), "s")
The paretnIndex() returns the index of the host in vector of hosts, reference OMNeT++ Manual. For the last node (i.e. host[999]) destAddr is set by hand because parentIndex()+1 will return 1000, and there is no host[1000].
The second NED function - replaceUnit() - is used to add the unit to the result of calculation.
Here is an other quasi solution:
From the PingApp's documentation:
string destAddr = default(""); // destination address(es), separated by spaces, "*" means all IPv4/IPv6 interfaces in entire simulation
Specifying '*' allows pinging ALL configured network interfaces in the
whole simulation. This is useful to check if a host can reach ALL other
hosts in the network (i.e. routing tables were set up properly).
To specify the number of ping requests sent to a single destination address,
use the 'count' parameter. After the specified number of ping requests was
sent to a destination address, the application goes to sleep for 'sleepDuration'.
Once the sleep timer has expired, the application switches to the next destination
and starts pinging again. The application stops pinging once all destination
addresses were tested or the simulation time reaches 'stopTime'.
So if you have only these hosts in the network and you don't mind that in the beginning the host pings itself too, destAddr="*" and count=1
I combined answers of #Rudi and #JerzyD. and got the workable solution:
**.host[0]*.numPingApps = 999
**.host[0]*.pingApp[*].typename = "PingApp"
**.host[0]*.pingApp[*].sendInterval = 1 s
**.host[0]*.pingApp[*].packetSize = 42 B
**.host[0]*.pingApp[0..998].destAddr = "host[" + string(index()+1) + "]"
**.host[0]*.pingApp[0..998].startTime = replaceUnit (0.1 * (index()), "s")
**.host[0]*.pingApp[0..998].stopTime = replaceUnit (5 + 0.1 * (index()), "s")

How to calculate data traffic ( internet usage) of ip device through SNMP protocol

I have created a snmp manager which will calculate the traffic of a list of ip address.
Here is the snmp walk cammand :
walk snmpwalk = new walk(" 192.168.30.172" ,". 1.3.6.1.2.1.2.2.1.10", "");
System.out.println(",,,,,,,,,,,,,,,," + snmpwalk.doSnmpwalk());
Here is the output:
1.3.6.1.2.1.2.2.1.10.1=0
1.3.6.1.2.1.2.2.1.10.2=0
1.3.6.1.2.1.2.2.1.10.3=0
1.3.6.1.2.1.2.2.1.10.4=0
1.3.6.1.2.1.2.2.1.10.5=0
1.3.6.1.2.1.2.2.1.10.6=0
1.3.6.1.2.1.2.2.1.10.7=0
1.3.6.1.2.1.2.2.1.10.8=0
1.3.6.1.2.1.2.2.1.10.9=0
1.3.6.1.2.1.2.2.1.10.10=0
1.3.6.1.2.1.2.2.1.10.11=0
1.3.6.1.2.1.2.2.1.10.12=0
1.3.6.1.2.1.2.2.1.10.13=0
1.3.6.1.2.1.2.2.1.10.14=163292301
1.3.6.1.2.1.2.2.1.10.15=0
1.3.6.1.2.1.2.2.1.10.16=0
1.3.6.1.2.1.2.2.1.10.17=0
1.3.6.1.2.1.2.2.1.10.18=0
1.3.6.1.2.1.2.2.1.10.19=0
1.3.6.1.2.1.2.2.1.10.20=0
1.3.6.1.2.1.2.2.1.10.21=0
1.3.6.1.2.1.2.2.1.10.22=0
1.3.6.1.2.1.2.2.1.10.23=0
1.3.6.1.2.1.2.2.1.10.24=163292301
1.3.6.1.2.1.2.2.1.10.25=163292301
1.3.6.1.2.1.2.2.1.10.26=163292301
1.3.6.1.2.1.2.2.1.10.27=163292301
1.3.6.1.2.1.2.2.1.10.28=163292301
1.3.6.1.2.1.2.2.1.10.29=0
1.3.6.1.2.1.2.2.1.10.30=0
1.3.6.1.2.1.2.2.1.10.31=0
1.3.6.1.2.1.2.2.1.10.32=0
1.3.6.1.2.1.2.2.1.10.33=0
1.3.6.1.2.1.2.2.1.10.34=0
1.3.6.1.2.1.2.2.1.10.35=0
1.3.6.1.2.1.2.2.1.10.36=0
1.3.6.1.2.1.2.2.1.10.37=0
1.3.6.1.2.1.2.2.1.10.38=0
1.3.6.1.2.1.2.2.1.10.39=0
Now my question is it possible to calculate the traffic(monthly data usage) at the end of the month of this IP device?
if possible then how can i do that? What is the formula and calculation process?
On Linux I would use awk, e.g.:
awk 'BEGIN{RS="\r"} /::if(In|Out)Octets/{i=$1; sub(/^.*\./,"",i); t[i]+=$4} /::ifDescr/{i=$1; sub(/^.*\./,"",i); d[i]=$4}; END{for(i in t) if(t[i]>0) printf "%s %.2fMB\n",d[i],t[i]/1048576}' Cisco_3750_snmpwalk.txt
It sums ifInOctets and ifOutOctets counters, and displays the sum in MB next to ifDescr string if it is greater than 0. Output for your file looks like this:
Vlan66 0.00MB
Vlan100 2829.20MB
Vlan117 780.88MB
Vlan230 40.42MB
Vlan237 28.77MB
Vlan242 0.01MB
Vlan302 1902.10MB
Vlan312 181.48MB
Vlan325 738.01MB
Vlan328 253.37MB
Vlan330 0.08MB
Vlan331 590.89MB
Vlan337 320.17MB
Vlan356 3247.89MB
Vlan358 1360.38MB
Vlan362 45.38MB
Vlan364 2179.56MB
Vlan400 0.00MB
Vlan404 105.89MB
Vlan413 157.37MB
Vlan466 3487.25MB
Vlan467 0.00MB
Vlan510 2547.83MB
Vlan548 3033.33MB
Vlan603 0.01MB
Vlan624 0.00MB
Vlan667 0.01MB
Vlan725 1.58MB
Vlan776 103.93MB
Vlan875 29.90MB
Vlan908 15.19MB
Vlan910 27.36MB
Vlan936 13.78MB
Vlan956 13.91MB
Vlan965 68.12MB
Vlan966 298.39MB
Vlan967 167.47MB
Vlan1000 0.00MB
GigabitEthernet1/0/1 5629.52MB
GigabitEthernet1/0/2 4220.78MB
GigabitEthernet1/0/3 6369.15MB
GigabitEthernet1/0/9 3866.67MB
GigabitEthernet1/0/15 5511.63MB
GigabitEthernet1/0/16 6030.57MB
GigabitEthernet1/0/18 4251.62MB

Match Multiple Patterns in a String and Return Matches as Hash

I'm working with some log files, trying to extract pieces of data.
Here's an example of a file which, for the purposes of testing, I'm loading into a variable named sample. NOTE: The column layout of the log files is not guaranteed to be consistent from one file to the next.
sample = "test script result
Load for five secs: 70%/50%; one minute: 53%; five minutes: 49%
Time source is NTP, 23:25:12.829 UTC Wed Jun 11 2014
D
MAC Address IP Address MAC RxPwr Timing I
State (dBmv) Offset P
0000.955c.5a50 192.168.0.1 online(pt) 0.00 5522 N
338c.4f90.2794 10.10.0.1 online(pt) 0.00 3661 N
990a.cb24.71dc 127.0.0.1 online(pt) -0.50 4645 N
778c.4fc8.7307 192.168.1.1 online(pt) 0.00 3960 N
"
Right now, I'm just looking for IPv4 and MAC address; eventually the search will need to include more patterns. To accomplish this, I'm using two regular expressions and passing them to Regexp.union
patterns = Regexp.union(/(?<mac_address>\h{4}\.\h{4}\.\h{4})/, /(?<ip_address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/)
As you can see, I'm using named groups to identify the matches.
The result I'm trying to achieve is a Hash. The key should equal the capture group name, and the value should equal what was matched by the regular expression.
Example:
{"mac_address"=>"0000.955c.5a50", "ip_address"=>"192.168.0.1"}
{"mac_address"=>"338c.4f90.2794", "ip_address"=>"10.10.0.1"}
{"mac_address"=>"990a.cb24.71dc", "ip_address"=>"127.0.0.1"}
{"mac_address"=>"778c.4fc8.7307", "ip_address"=>"192.168.1.1"}
Here's what I've come up with so far:
sample.split(/\r?\n/).each do |line|
hashes = []
line.split(/\s+/).each do |val|
match = val.match(patterns)
if match
hashes << Hash[match.names.zip(match.captures)].delete_if { |k,v| v.nil? }
end
end
results = hashes.reduce({}) { |r,h| h.each {|k,v| r[k] = v}; r }
puts results if results.length > 0
end
I feel like there should be a more "elegant" way to do this. My chief concern, though, is performance.

My method to send values of performance counters to Graphite is very slow. What is the bottleneck? And how to improve?

Below I have some code to get the values of instances of performance counters (which are instantiated once a page is visited) and send them to Graphite to display graphs in the following format:
[Path in Graphite (e.g., metric.pages.Counter1)] [value of counter] [epoch time]
To do this I made the following code where the writer is configured correctly to work:
# Get all paths to MultipleInstance counters and averages that start with "BLABLA" and
# put them into an array and get the epoch time
$pathsWithInstances = (get-counter -ListSet BLABLA*) | select -ExpandProperty PathsWithInstances
$epochtime = [int][double]::Parse((Get-Date -UFormat %s))
# This functions splits the path (e.g., \BLABLA Web(welcome)\Page Requests) into three
# parts: the part before the
# opening brace (the CounterCategory, e.g., "\BLABLA Web"), the part in between the braces
# (the page or
# service, e.g., "welcome"), and the part after the closing brace (the name of the test,
# e.g.,
# "\Page Requests"). We obtain the metric out of this information and send it to
# Graphite.
enter code here
foreach ($pathWithInstance in $pathsWithInstances)
{
$instanceProperties = $pathWithInstance.Split('()')
$counterCategory = $instanceProperties[0]
if ($counterCategory -eq ("\BLABLA Web") )
{
# Replace the * with nothing so that counters that are used to display the
# average (e.g., \BLABLAWeb(*)\Page Requests) are displayed on top in the
# Graphite directory.
$pagePath = $instanceProperties[1].Replace('*','')
$nameOfTheTest = $instanceProperties[2]
# Countername which is used in Graphite path gets whitespace and backslash
# removed in the name used for the path in Graphite (naming conventions)
$counterName = $nameOfTheTest.Replace(' ','').Replace('\','')
$pathToPerfCounter = $pathWithInstance
$pathInGraphite = "metrics.Pages." + $pagePath + $counterName
#Invoked like this since otherwise the get-counter [path] does not seem to work
$metricValue = [int] ((Get-Counter "$pathToPerfCounter").countersamples | select -
property cookedvalue).cookedvalue
$metric = ($pathInGraphite + " " + $metricValue + " " + $epochTime)
$writer.WriteLine($metric)
$writer.Flush()
}
}
Unfortunately this code is very slow. It takes about one second for every counter to send a value. Does someone see why it is so slow and how it can be improved?
You're getting one counter at a time, and it takes a second for Get-Counter to get and "Cook" the values. Get-Counter will accept an array of counters, and will sample, "cook" and return them all in that same second. You can speed it up by sampling them all at once, and then parsing the values from the array of results:
$CounterPaths = (
'\\Server1\Memory\Page Faults/sec',
'\\Server1\Memory\Available Bytes'
)
(Measure-Command {
foreach ($CounterPath in $CounterPaths)
{Get-Counter -counter $counterpath}
}).TotalMilliseconds
(Measure-Command {
Get-Counter $CounterPaths
}).TotalMilliseconds
2017.4693
1012.3012
Example:
foreach ($CounterSample in (Get-Counter $CounterPaths).Countersamples)
{
"Path = $($CounterSample.path)"
"Metric = $([int]$CounterSample.CookedValue)"
}
Path = \\Server1\memory\page faults/sec
Metric = 193
Path = \\Server1\memory\available bytes
Metric = 1603678208
Use the Start-Job cmdlet, to create separate threads for each counter.
Here is a simple example of how to take the Counter Paths and pass them into an asynchronous ScriptBlock:
$CounterPathList = (Get-Counter -ListSet Processor).PathsWithInstances.Where({ $PSItem -like '*% Processor Time' });
foreach ($CounterPath in $CounterPathList) {
Start-Job -ScriptBlock { (Get-Counter -Counter $args[0]).CounterSamples.CookedValue; } -ArgumentList $CounterPath;
}
# Call Receive-Job down here, once all jobs are finished
IMPORTANT: The above example uses PowerShell version 4.0's "method syntax" for filtering objects. Please make sure you're running PowerShell version 4.0, or change the Where method to use the traditional Where-Object instead.

Resources