Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

In my php-app I need the list of all IP's connected on port 80. I've chosen to do it this way:

<?php
     $ips = exec("netstat -an |grep 'tcp\|udp' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c", $info);
?>

But it doesn't work on my VPS FreeBSD server. When I start netstat -an a notice appears and no connections are in output:

netstat: kvm not available: /dev/mem: No such file or directory

I tried to add device mem to conf, but I have an empty /usr/src/sys. I got to the point that I need to rebuild the core.))

netstat works correctly when user is root (from console). I haven't had any problems like this on a similar CentOS hosting platform.

Fot resolving /dev/mem: No such file or directory I've tried to do mknod -m 660 /dev/mem c 1 1 but it calls an mknod: /dev/mem: Operation not permitted

I've got the following users pw showuser

owl:*:1000:1003:default:0:0:owl:/home/owl/data:/bin/csh
root:*:0:0::0:0:Charlie &:/root:/bin/csh

Summary:
When I run netstat as owl - it returns an empty list of connections
When I run netstat as root - it returns notice netstat: kvm not available: /dev/mem: No such file or directory and IP's

Can anybody help me? Is there maybe another way that exists for resolving this task? Thank you

share|improve this question
    
Does your netstat have similar group permissions: -r-xr-sr-x 1 root kmem 88780 Aug 23 2007 /usr/bin/netstat ? — It's to be kmem SGIDed to gain needed priveleges when run by non-privileged users. –  poige Apr 28 '13 at 14:28
    
Regarding the empty /usr/src/sys. To rebuild the FreeBSD core on your VPS you need to synchronize the source tree, add the options and devices you want to add to the kernel. This is all described in the FreeBSD handbook: freebsd.org/doc/handbook/makeworld.html –  superuser0 Apr 28 '13 at 14:30
    
i have permission netstat like you wrote for my user –  Andrei Zhamoida Apr 28 '13 at 15:20
    
@AndreiZhamoida, bring ls -l into the studio, please. –  poige Apr 28 '13 at 15:49
    
I've changed group from kmem to wheel but notice is not hide vm# ls -la netstat -r-xr-sr-x 1 root wheel 157616 Apr 28 18:51 netstat –  Andrei Zhamoida Apr 28 '13 at 16:00
show 2 more comments

1 Answer 1

up vote 0 down vote accepted

I believe your cut is not behaving as you expect, since in netstat's output, the IP and port are separated by a dot, not a colon.

I also get a netstat: kvm not available: /dev/mem: No such file or directory error when I run netstat -an within some of the jails I administer, but despite this error, I still get expected results from netstat. I haven't researched why this occurs, so I'm leaning towards thinking that this is a red herring.

In terms of your command line, you can reduce your plumbing by packing more functionality into the awk script:

netstat -an | \
  awk '/^(tcp|udp)/{ip=$5; sub(/.[0-9]+$/,"",ip); list[ip]++;} END{for(ip in list){printf("%7d %s\n",list[ip],ip)}}'

Split up for easier reading, this awk script is:

# Only work on tcp/udp lines...
/^(tcp|udp)/ {
  ip=$5;
  sub(/.[0-9]+$/,"",ip);
  list[ip]++;  # Populate an array of counters-per-IP
}

# After data are gathered, print the results.
END {
  for (ip in list) {
    printf("%7d %s\n",list[ip],ip);
  }
}

But since you're doing this in PHP, I'd do more of this text processing in PHP.

<?php

# Gather our data...
exec("netstat -an", $out);

# Easy access to the output we want (for isset() below)
$permit = array("udp4"=>1,"tcp4"=>1);

foreach ($out as $line) {

  $a = preg_split("/[[:space:]]+/", $line);

  # Only work on tcp4/udp4 lines...
  if (isset($permit[$a[0]])) {
    # Populate an array of counters...
    $ip = substr($a[4], 0, strrpos($a[4],".")-1);
    $list[$ip]++;
  }

}

# And print the results.
foreach ($list as $ip => $count) {
  printf("%7s\t%s\n", $count, $ip);
}

This may seem like more work, but it may actually be faster than spawning a collection of pipes.

Note that you also have the sockstat command in FreeBSD, so building on Chris S's suggestion:

<?php

exec("sockstat -4", $out);

$permit = array("udp4"=>1,"tcp4"=>1);

foreach ($out as $line) {

  $a = preg_split("/[[:space:]]+/", $line);

  if (isset($permit[$a[4]])) {
    preg_match("/^[^:]+/", $a[6], $ip);
    $list[$ip[0]]++;
  }

}

foreach ($list as $ip => $count) {
  printf("%7s\t%s\n", $count, $ip);
}

UPDATE:

I also came across this ancient note about the kvm error. Since routing table information is usually available, you should contact your VPS provider and find out whether they have intentionally restricted your access to routing table data on this host. If you are not in a jail, then I suspect that a post to one of the FreeBSD mailing lists would get results. There's also a ##FreeBSD channel at irc.freenode.net where knowledgeable people often hang out.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.