Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
Bash Scripting
lew~
post Oct 25 2011, 02:39 PM
Post #1
Atomican
Champion




Not sure if this should be in Programming or here.

I have a file with a list of IP addresses, one per line. E.g.:
CODE
$ cat ip-list.txt
10.1.1.1
10.1.1.2
10.1.1.3
10.1.1.4



I want to perform a snmpget against each IP in the file, and write the IP with the output into a new file, e.g.:

CODE
for $IP in ip-list.txt
do
snmpget -v 2c -c string $IP sysName.0


and have the output appear as follows (tab delimited, for example):
CODE
10.1.1.1,host1
10.1.1.2,host2
10.1.1.3,host3
10.1.1.4,host4


For bonus points, return 'null' or similar where no response is received.

In case it's relevant, the output of snmpget looks like this:
CODE
$ snmpget -v 2c -c string n.n.n.n sysName.0
SNMPv2-MIB::sysName.0 = STRING: hostname




I have access to redhat, linux and OS X command lines so i'm sure I have the tools I need, just not sure how to put it together. Managed to grep, sed & cat my way to the clean list of IPs, but haven't worked out this last bit.

Ideas?
Go to the top of the page
 
+Quote Post
sponger
post Oct 25 2011, 07:47 PM
Post #2
Atomican
Guru




A bit ugly but should do it:

CODE
for IP in `cat ip-list.txt`; do
  output=$(snmpget -v 2c -c string $IP sysName.0)
  if [ $? -eq 0 ]; then
    echo $IP,`echo $output | awk '{print $NF}'`
  else
    echo $IP,null
  fi
done
Go to the top of the page
 
+Quote Post
lew~
post Oct 25 2011, 10:03 PM
Post #3
Atomican
Champion




QUOTE (sponger @ Oct 25 2011, 08:17 PM) *
A bit ugly but should do it:

CODE
for IP in `cat ip-list.txt`; do
  output=$(snmpget -v 2c -c string $IP sysName.0)
  if [ $? -eq 0 ]; then
    echo $IP,`echo $output | awk '{print $NF}'`
  else
    echo $IP,null
  fi
done

Thanks sponger, I'll give it a go tomorrow. You're the boss with this stuff, but do you need to 'declare' the IP variable in the first line or anything? I just typed out pseudo-code in the OP, that doesn't necessarily do anything :p


Edit:

Works awesome sponger, thanks!

Where there's no response it prints two lines; the snmpget output and the script output, but that's not a big deal - easy to clean out:
CODE
Timeout: No Response from 10.1.1.1.
10.1.1.1,null


This post has been edited by lew~: Oct 26 2011, 09:22 AM
Go to the top of the page
 
+Quote Post
sponger
post Oct 26 2011, 01:13 PM
Post #4
Atomican
Guru




No prob

That extra output is probably to stderr, so try changing this line:

CODE
output=$(snmpget -v 2c -c string $IP sysName.0 2> /dev/null)


This post has been edited by sponger: Oct 26 2011, 01:14 PM
Go to the top of the page
 
+Quote Post
lew~
post Oct 26 2011, 05:05 PM
Post #5
Atomican
Champion




stderr as opposed to stdout, so that wouldn't impact on the output from the command right? cool.
Edit: It doesn't actually write stderr to the file, so it's all good.


Tried to expand on it, but it only half works. It will do the snmpget and the dig if that fails. But it won't do the nmap or "echo $IP,null". Any ideas?
Does it matter that the nmap output is multiple lines?

CODE
#! /bin/bash

for IP in `cat resolve.txt`; do
        output=$(snmpget -v 2c -c string $IP sysName.0)
        if [ $? -eq 0 ]; then
                echo $IP,`echo $output | awk '{print $NF}'`
        else
        output=$(dig -x $IP +short)
        if [ $? -eq 0 ]; then
                echo $IP,`echo $output | awk '{print $NF}'`
        else
        output=$(nmap -Pn -F -sS -sU -O -T4 -R --max-retries 3 $IP)
        if [ $? -eq 0 ]; then
                echo $IP,`echo $output | awk '{print $NF}'`
        else
                echo $IP,null
        fi
        fi
        fi
done


This post has been edited by lew~: Oct 26 2011, 06:01 PM
Go to the top of the page
 
+Quote Post
sponger
post Oct 26 2011, 06:40 PM
Post #6
Atomican
Guru




Try this:

CODE
for IP in `cat testresolve.txt`; do
  output=$(snmpget -v 2c -c string $IP sysName.0 2> /dev/null)
  if [ $? -eq 0 ]; then
    host=`echo $output | awk '{print $NF}'`
  else
    output=$(dig -x $IP +short 2> /dev/null)
    if [[ $? -eq 0 && $output =~ ([^[:space:]]*)\. ]]; then
      host=${BASH_REMATCH[1]}
    else
      output=$(nmap -Ss -Su -F -O -T4 -R --max-retries 3 $IP 2> /dev/null)
      if [[ $? -eq 0 && $output =~ report\ for\ ([^[:space:]]*)[[:space:]] ]]; then
        host=${BASH_REMATCH[1]}
      else
        host=null
      fi
    fi
  fi
  echo $IP,$host
done


For each command you add you'll have to work out how to get the host from its output. The original code depended on snmpget only.

If the above doesn't work, show me some output for dig and nmap. I just did some quick tests on a different platform to you (OpenBSD).
Go to the top of the page
 
+Quote Post
lew~
post Nov 2 2011, 10:00 AM
Post #7
Atomican
Champion




Hey sponger, I've had a bit more time to play with this. What you provided works really well, both snmpet and dig outputs are perfect.

I think because of how the NMAP output matching is done, it currently returns the IP address as $host. e.g.:
CODE
10.1.1.1,10.1.1.1


The NMAP output looks like this, with the OS detection section varying depending on what it finds:

CODE
# nmap -Pn -F -sS -sU -O -T4 -R --max-retries 3 10.1.1.1

Starting Nmap 5.35DC1 ( http://nmap.org ) at 2011-11-02 10:02 CST
Nmap scan report for 10.1.1.1
Host is up (0.00090s latency).
Not shown: 100 open|filtered ports, 99 filtered ports
PORT    STATE  SERVICE
x/x closed x
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: switch|firewall|broadband router
Running: producta, productb, productc
OS details: producta, productb, productc

OS detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.78 seconds



OS detection examples:

CODE
# nmap -Pn -F -sS -sU -O -T4 -R --max-retries 3 10.1.1.1 | egrep "OS:|OS details:"
OS:SCAN(V=5.35DC1%D=11/2%OT=21%CT=7%CU=7%PV=Y%DS=4%DC=I%G=Y%TM=4EB08387%P=i
OS:686-redhat-linux-gnu)SEQ(SP=100%GCD=1%ISR=100%TI=BI%TS=7)SEQ(TS=9)SEQ(TI
OS:=RI%TS=8)OPS(O1=M5B4ST11NW0%O2=M5B4ST11NW0%O3=M5B4NNT11NW0%O4=M5B4ST11NW
OS:0%O5=M5B4ST11NW0%O6=M5B4ST11)WIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0
OS:%W6=16A0)ECN(R=N)T1(R=Y%DF=Y%T=41%S=O%A=S+%F=AS%RD=0%Q=)T1(R=Y%DF=Y%T=41
OS:%S=O%A=O%F=AS%RD=0%Q=)T1(R=N)T2(R=N)T3(R=N)T4(R=N)T5(R=Y%DF=Y%T=7F%W=0%S
OS:=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=N)T7(R=N)U1(R=Y%DF=N%T=7F%IPL=164%UN=0%RIPL
OS:=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=N)

CODE
# nmap -Pn -F -sS -sU -O -T4 -R --max-retries 3 10.1.1.2 | egrep "OS:|OS details:"
OS details: producta, productb, productc





Would it be possible to output the "OS details" line if it exists else null?, e.g.:
CODE
10.1.1.1,host1
10.1.1.2,host2
10.1.1.3,OS details: producta, productb, productc
10.1.1.4,host4







Also, the other thing I was wondering is if it would be possible to print the method in between $IP & $host? e.g.
CODE
10.1.1.1,DNS,host1
10.1.1.2,SNMP,host2


I tried adding it in to the host= line but it didn't like my attempted syntax :(



Go to the top of the page
 
+Quote Post
sponger
post Dec 7 2011, 05:42 PM
Post #8
Atomican
Guru




Finally got some time, try this...have cleaned up, haven't tested at all though. You can now pass the filename as an argument, /path/to/script filename

CODE
#!/path/to/bash

[ -e $1 ] && cat $1 | while read IP; do
  output=$(snmpget -v 2c -c string $IP sysName.0 2> /dev/null)
  if [[ $? -eq 0 && $output =~ ([^[:space:]]*)$ ]]; then
    host=${BASH_REMATCH[1]}
  else
    output=$(dig -x $IP +short 2> /dev/null)
    if [[ $? -eq 0 && $output =~ ([^[:space:]]*)\. ]]; then
      host=${BASH_REMATCH[1]}
    else
      output=$(nmap -Ss -Su -F -O -T4 -R --max-retries 3 $IP 2> /dev/null)
      if [ $? -eq 0 ]; then
        host=$(echo "$output" | grep "OS details")          
      else
        host=null
      fi
    fi
  fi
  echo $IP,$host
done


If you don't want "OS details: ", just "producta, productb, productc", replace

CODE
host=$(echo "$output" | grep "OS details")

with

CODE
echo "$output" | while read line; do
  [[ $line =~ ^OS\ details:\ (.*)$ ]] && host=${BASH_REMATCH[1]}
done
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 



Lo-Fi Version Time is now: 30th July 2014 - 12:57 PM