Array to array scanning

trying a little bit of array scanning for open ports.

my code looks like below:

/bin/netstat -lntp|\
awk 'BEGIN { split("25 80 2020 6033 6010",q);  } 
$1  == "tcp" { split($4,a,":"); p[a[2]]++;  }  
$1 == "tcp6" { split($4,a,":");p[a[4]]++ } 

END { 
for ( i in q ) { 
if (! q in p ) { printf("%s\n",q)  }   
                  } 
        }'

my input is:

# /bin/netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      4227/mysqld
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      5584/smbd
tcp        0      0 127.0.0.1:5900          0.0.0.0:*               LISTEN      5620/kvm
tcp        0      0 127.0.0.1:5901          0.0.0.0:*               LISTEN      5643/kvm
tcp        0      0 127.0.0.1:5902          0.0.0.0:*               LISTEN      5672/kvm
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      2347/rpcbind
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      4482/sshd
tcp        0      0 0.0.0.0:631             0.0.0.0:*               LISTEN      3513/cupsd
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      4969/exim4
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      31012/3
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      5584/smbd
tcp        0      0 0.0.0.0:46787           0.0.0.0:*               LISTEN      2378/rpc.statd
tcp6       0      0 :::139                  :::*                    LISTEN      5584/smbd
tcp6       0      0 :::111                  :::*                    LISTEN      2347/rpcbind
tcp6       0      0 :::80                   :::*                    LISTEN      11530/apache2
tcp6       0      0 :::22                   :::*                    LISTEN      4482/sshd
tcp6       0      0 :::631                  :::*                    LISTEN      3513/cupsd
tcp6       0      0 ::1:25                  :::*                    LISTEN      4969/exim4
tcp6       0      0 ::1:6010                :::*                    LISTEN      31012/3
tcp6       0      0 :::443                  :::*                    LISTEN      11530/apache2
tcp6       0      0 :::445                  :::*                    LISTEN      5584/smbd
tcp6       0      0 :::57726                :::*                    LISTEN      2378/rpc.statd
#

the output I am looking for is something like

6010 port is not listed in allowed ports, the process is "31012/3" on "tcp6"

thanks

Something like this modification of your approach?

/bin/netstat -lntp |
awk '
  BEGIN {
    split("25 80 2020 6033 6010",q)
  } 
  {
    n=split($4,a,":")
  }
  /^tcp/ && !(a[n] in q) {
    printf "%s port is not listed in allowed ports, the process is \"%s\" on \"%s\"\n", a[n], $NF, $1
  }
'

looks to me great,

but what is "p" here..thanks

---------- Post updated at 05:46 PM ---------- Previous update was at 04:20 PM ----------

I'm getting this when I run your code @Scrutinizer

 port is not listed in allowed ports, the process is "4227/mysqld" on "tcp"
 port is not listed in allowed ports, the process is "5584/smbd" on "tcp"
 port is not listed in allowed ports, the process is "5620/kvm" on "tcp"
 port is not listed in allowed ports, the process is "5643/kvm" on "tcp"
 port is not listed in allowed ports, the process is "5672/kvm" on "tcp"
 port is not listed in allowed ports, the process is "2347/rpcbind" on "tcp"
 port is not listed in allowed ports, the process is "4482/sshd" on "tcp"
 port is not listed in allowed ports, the process is "3513/cupsd" on "tcp"
 port is not listed in allowed ports, the process is "4969/exim4" on "tcp"
 port is not listed in allowed ports, the process is "31012/3" on "tcp"

Try:-

/bin/netstat -lntp | awk '
        BEGIN {
                q["25"]
                q["80"]
                q["2020"]
                q["6033"]
                q["6010"]
        }
        {
                n = split( $4, a, ":" )
        }
        /^tcp/ && ( a[n] in q ) {
                printf "%s port is not listed in allowed ports, the process is \"%s\" on \"%s\"\n", a[n], $NF, $1
        }
'

" p " could probably be a[n]

also, post #4 line maybe should be: /^tcp/ && ! ( a[n] in q ) {[/ICODE]

1 Like

Indeed it should read a[n] rather than p in post#2 . Corrected in post.

learned to initialize array in awk,

@scrutinizer, I tried your code with a[n] as below it didn't give any success,

/^tcp/ && ( a[n] in q ) {
                printf "%s port is not listed in allowed ports, the process is \"%s\" on \"%s\"\n", a[n], $NF, $1
        }

however, the new way to initialize array from @Yoda's code, it worked very well.

my question is , what is the difference between initializing an array in awk like below given 2 options

option #1

split("80 25 443 6010",q)

and

option#2

q["80"]; q["25"]; q["443"];q["6010"]

Anyways, Option#2 worked for me and thanks both Yoda and Scrutinizer

The split statement creates an array whose elements have the values of the substrings (separated by the FS) and consecutive indices starting from 1.
The individual assignments each create an associative array (sometimes also called hash ) element with an individual string index and, here, an empry value. Example:

awk 'BEGIN      {split("80 25 443 6010",Q)
                 for (i in Q) print "index:", i, ", value:", Q
                 q["80"]; q["25"]; q["443"];q["6010"]
                 for (i in q) print "index:", i, ", value:", q
                }
'
index: 1 , value: 80
index: 2 , value: 25
index: 3 , value: 443
index: 4 , value: 6010
index: 25 , value: 
index: 80 , value: 
index: 443 , value: 
index: 6010 , value: 

With a little trick, you can create an associative array from a (separated) string:

awk 'BEGIN      {for (n=split("80 25 443 6010", q); n>0; n--) Q[q[n]] 
                 for (i in Q) print "index:", i, ", value:", Q
                }
index: 25 , value: 
index: 80 , value: 
index: 443 , value: 
index: 6010 , value: 
1 Like

thanks RudiC

perfectly explained... Thanks again.