2

I am working on PHP application and I need to find out all the ports that have listening status.

Note: fsockopen() works only for established connection.

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
aak
  • 107
  • 1
  • 4
  • 12
  • all ports that "PHP" is listening to, or all ports on your machine? – ArSeN Jan 15 '16 at 16:30
  • all ports that has a listening status on my machine. – aak Jan 15 '16 at 16:38
  • Does your PHP app need this for some reason, or do you just want to see the ports on your machine? If you just want to see them, you can type "netstat -na" in the command terminal, you may also be able to parse that from within PHP using the system( 'netstat -na' ); if you need to. – Rainner Jan 15 '16 at 16:55
  • yes, I just need to use different ports in my application if that existing port is in use(establisted/listening) – aak Jan 15 '16 at 16:59
  • do you only need that for tcp ports or also for raw and udp? – Gordon Jan 15 '16 at 18:47

1 Answers1

2

This should give you a list of listening ports for local ip addresses. I'm using system() here, and the netstat command, make sure your PHP installation can use that function and test the output of netstat from the terminal first to see if it works.

EDIT: Added support for both windows and linux.

function get_listening_ports()
{
    $output  = array();
    $options = ( strtolower( trim( @PHP_OS ) ) === 'linux' ) ? '-atn' : '-an';

    ob_start();
    system( 'netstat '.$options );

    foreach( explode( "\n", ob_get_clean() ) as $line )
    {
        $line  = trim( preg_replace( '/\s\s+/', ' ', $line ) );
        $parts = explode( ' ', $line );

        if( count( $parts ) > 3 )
        {
            $state   = strtolower( array_pop( $parts ) );
            $foreign = array_pop( $parts );
            $local   = array_pop( $parts );

            if( !empty( $state ) && !empty( $local ) )
            {
                $final = explode( ':', $local );
                $port  = array_pop( $final );

                if( is_numeric( $port ) )
                {
                    $output[ $state ][ $port ] = $port;
                }
            }
        }
    }
    return $output;
}

output:

Array
(
    [listen] => Array
        (
            [445] => 445
            [9091] => 9091
            [3306] => 3306
            [587] => 587
            [11211] => 11211
            [139] => 139
            [80] => 80
            [3312] => 3312
            [51413] => 51413
            [22] => 22
            [631] => 631
            [25] => 25
            [443] => 443
            [993] => 993
            [143] => 143
        )

    [syn_recv] => Array
        (
            [80] => 80
        )

    [time_wait] => Array
        (
            [80] => 80
            [51413] => 51413
        )

    [established] => Array
        (
            [22] => 22
            [9091] => 9091
            [80] => 80
            [3306] => 3306
        )

    [fin_wait2] => Array
        (
            [80] => 80
        )

)
Rainner
  • 589
  • 3
  • 7
  • Thanks, that helps. Just need to know about Established and TIME_WAIT status. What command do I need to use and what changes will it require in the code? – aak Jan 15 '16 at 18:04
  • What system is your server running on (windows, linux)? The output of netstat varies, i'll try to update it. – Rainner Jan 15 '16 at 18:20
  • windows. Thanks for your help – aak Jan 15 '16 at 18:22
  • Note that the output can be localized, so this is not easily portable. On my Ubuntu I do not get "established" but "verbunden" and it's not "listening" but "listen" (dunno why only half of it is translated). – Gordon Jan 15 '16 at 18:43
  • Check the edit to the code above, it should work on both windows and linux and has all the non-empty values from the State column added to the output array. – Rainner Jan 15 '16 at 18:52
  • 1
    Another caveat: [`PHP_OS` will give you name of the OS this PHP was build on](http://stackoverflow.com/a/12997081/208809) – Gordon Jan 15 '16 at 19:21
  • @Gordon Thanks for the info, I'll leave it as is, but gave you +1 so others can see it. – Rainner Jan 15 '16 at 19:29
  • you're welcome. on a side note: I'd probably do it like this http://pastebin.com/j1qyuWXe - it's a bit more compact. – Gordon Jan 15 '16 at 19:50