© Frank M. Kromann 2018
Frank M. KromannBeginning PHP and MySQLhttps://doi.org/10.1007/978-1-4302-6044-8_16

16. Networking

Frank M. Kromann1 
(1)
Aliso Viejo, CA, USA
 

You may have turned to this chapter wondering just what PHP could possibly have to offer in regard to networking. After all, aren’t networking tasks largely relegated to languages commonly used for system administration, such as Perl or Python? While such a stereotype might have once painted a fairly accurate picture, these days, incorporating networking features into a web application is commonplace. In fact, web-based applications are regularly used to monitor and even maintain network infrastructures. Furthermore, with the use of the command-line version of PHP. it’s very easy to write advanced scripts for system administration using the favorite language and all the libraries available to do this. Always keen to acknowledge growing user needs, the PHP developers have integrated a pretty impressive array of network-specific functionality.

This chapter is divided into sections covering the following topics:
  • DNS, servers, and services: PHP offers a variety of functions capable of retrieving information about the network internals, DNS, protocols, and Internet-addressing schemes. This section introduces these functions and offers several usage examples.

  • Sending e-mail with PHP: Sending e-mail via a web application is undoubtedly one of the most commonplace features you can find these days, and for good reason. E-mail remains the Internet’s killer application and offers an amazingly efficient means for communicating and maintaining important data and information. This section explains how to easily send messages via a PHP script. Additionally, you’ll learn how to use the PHPMailer library to facilitate more complex e-mail dispatches, such as those involving multiple recipients, HTML formatting, and the inclusion of attachments.

  • Common networking tasks: In this section, you’ll learn how to use PHP to mimic the tasks commonly carried out by command-line tools, including pinging a network address, tracing a network connection, scanning a server’s open ports, and more.

DNS, Services, and Servers

These days, investigating or troubleshooting a network issue often involves gathering a variety of information pertinent to affected clients, servers, and network internals such as protocols, domain name resolution, and IP-addressing schemes. PHP offers a number of functions for retrieving a bevy of information about each subject, each of which is introduced in this section.

DNS

The Domain Name System (DNS) is what allows you to use domain names (e.g., example.com) in place of the corresponding IP address, such as 192.0.34.166. The domain names and their complementary IP addresses are stored on domain name servers, which are interspersed across the globe. Typically, a domain has several types of records associated to it, one mapping the IP address to specific hosts names for the domain, another for directing e-mail, and another for a domain name alias. Network administrators and developers often need to learn more about various DNS records for a given domain. This section introduces a number of standard PHP functions capable of digging up a great deal of information regarding DNS records.

Checking for the Existence of DNS Records

The checkdnsrr() function checks for the existence of DNS records. Its prototype follows:
int checkdnsrr(string host [, string type])
DNS records are checked based on the supplied host value and optional DNS resource record type, returning TRUE if any records are located and FALSE otherwise. Possible record types include the following:
  • A: IPv4 Address record. Responsible for the hostname-to-IPv4 address translation.

  • AAAA: IPv6 Address record. Responsible for the hostname-to-IPv6 address translation.

  • A6: IPv6 Address record. Used to represent IPv6 addresses. Intended to supplant present use of AAAA records for IPv6 mappings.

  • ANY: Looks for any type of record.

  • CNAME: Canonical Name record. Maps an alias to the real domain name.

  • MX: Mail Exchange record. Determines the name and relative preference of a mail server for the host. This is the default setting.

  • NAPTR: Naming Authority Pointer. Allows for non-DNS-compliant names, resolving them to new domains using regular expression rewrite rules. For example, an NAPTR might be used to maintain legacy (pre-DNS) services.

  • NS: Name Server record. Determines the name server for the host.

  • PTR: Pointer record. Maps an IP address to a host.

  • SOA: Start of Authority record. Sets global parameters for the host.

  • SRV: Services record. Denotes the location of various services for the supplied domain.

  • TXT: Text record. Stores additional unformatted information about a host, such as SPF records.

Consider an example. Suppose you want to verify whether the domain name example.com has a corresponding DNS record:
<?php
    $domain = "example.com";
    $recordexists = checkdnsrr($domain, "ANY");
    if ($recordexists)
      echo "The domain '$domain' has a DNS record!";
    else
      echo "The domain '$domain' does not appear to have a DNS record!";
?>
This returns the following:
The domain 'example.com' exists
You can also use this function to verify the existence of a domain of a supplied mail address:
<?php
    $email = "[email protected]";
    $domain = explode("@",$email);
    $valid = checkdnsrr($domain[1], "MX");
    if($valid)
      echo "The domain has an MX record!";
    else
      echo "Cannot locate MX record for $domain[1]!";
?>
This returns the following:
Cannot locate MX record for example.com!

Changing the record type to ‘A’ will cause the script to return a valid response. This is because the example.com domain has a valid A record but no valid MX (Mail Exchange) records. Keep in mind this isn’t a request for verification of the existence of an MX record. Sometimes network administrators employ other configuration methods to allow for mail resolution without using MX records (because MX records are not mandatory). To err on the side of caution, just check for the existence of the domain without specifically requesting verification of whether an MX record exists.

Further, this doesn’t verify whether an e-mail address actually exists. The only definitive way to make this determination is to send that user an e-mail and ask him to verify the address by clicking a one-time URL. You can learn more about one-time URLs in Chapter 14.

Retrieving DNS Resource Records

The dns_get_record() function returns an array consisting of various DNS resource records pertinent to a specific domain. Its prototype follows:
array dns_get_record(string hostname [, int type [, array &authns, array &addtl]])

By default, dns_get_record() returns all records it can find specific to the supplied domain (hostname); however, you can streamline the retrieval process by specifying a type, the name of which must be prefaced with DNS. This function supports all the types introduced along with checkdnsrr() , in addition to others that will be introduced in a moment. Finally, if you’re looking for a full-blown description of this hostname’s DNS description, you can pass the authns and addtl parameters in by reference, which specify that information pertinent to the authoritative name servers and additional records should also be returned.

Assuming that the supplied hostname is valid and exists, a call to dns_get_record() returns at least four attributes:
  • host: Specifies the name of the DNS namespace to which all other attributes correspond.

  • class: Returns records of class Internet only, so this attribute always reads IN.

  • type: Determines the record type. Depending upon the returned type, other attributes might also be made available.

  • ttl: Calculates the record’s original time-to-live minus the amount of time that has passed since the authoritative name server was queried.

In addition to the types introduced in the section on checkdnsrr() , the following domain record types are made available to dns_get_record() :
  • DNS_ALL: Retrieves all available records, even those that might not be recognized when using the recognition capabilities of your particular operating system. Use this when you want to be absolutely sure that all available records have been retrieved.

  • DNS_ANY: Retrieves all records recognized by your particular operating system.

  • DNS_HINFO: Specifies the operating system and computer type of the host. Keep in mind that this information is not required.

  • DNS_NS: Determines whether the name server is the authoritative answer for the given domain, or whether this responsibility is ultimately delegated to another server.

Just remember that the type names must always be prefaced with DNS_. As an example, suppose you want to learn more about the example.com domain:
<?php
    $result = dns_get_record("example.com");
    print_r($result);
?>
A sampling of the returned information follows:
Array
(
    [0] => Array
        (
            [host] => example.com
            [class] => IN
            [ttl] => 3600
            [type] => SOA
            [mname] => sns.dns.icann.org
            [rname] => noc.dns.icann.org
            [serial] => 2018013021
            [refresh] => 7200
            [retry] => 3600
            [expire] => 1209600
            [minimum-ttl] => 3600
        )
    [1] => Array
        (
            [host] => example.com
            [class] => IN
            [ttl] => 25742
            [type] => NS
            [target] => a.iana-servers.net
        )
    [2] => Array
        (
            [host] => example.com
            [class] => IN
            [ttl] => 25742
            [type] => NS
            [target] => b.iana-servers.net
        )
    [3] => Array
        (
            [host] => example.com
            [class] => IN
            [ttl] => 25742
            [type] => AAAA
            [ipv6] => 2606:2800:220:1:248:1893:25c8:1946
        )
    [4] => Array
        (
            [host] => example.com
            [class] => IN
            [ttl] => 25742
            [type] => A
            [ip] => 93.184.216.34
        )
    [5] => Array
        (
            [host] => example.com
            [class] => IN
            [ttl] => 60
            [type] => TXT
            [txt] => v=spf1 -all
            [entries] => Array
                (
                    [0] => v=spf1 -all
                )
        )
    [6] => Array
        (
            [host] => example.com
            [class] => IN
            [ttl] => 60
            [type] => TXT
            [txt] => $Id: example.com 4415 2015-08-24 20:12:23Z davids $
            [entries] => Array
                (
                    [0] => $Id: example.com 4415 2015-08-24 20:12:23Z davids $
                )
        )
)
If you were only interested in the address records, you could execute the following:
<?php
    $result = dns_get_record("example.com", DNS_A);
    print_r($result);
?>
This returns the following:
Array (
  [0] => Array (
    [host] => example.com
    [type] => A
    [ip] => 192.0.32.10
    [class] => IN
    [ttl] => 169679 )
)

Retrieving MX Records

The getmxrr() function retrieves the MX records for the domain specified by hostname. Its prototype follows:
boolean getmxrr(string hostname, array &mxhosts [, array &weight])
The MX records for the host specified by hostname are added to the array specified by mxhosts. If the optional input parameter weight is supplied, the corresponding weight values will be placed there; these refer to the hit prevalence assigned to each server identified by record. An example follows:
<?php
    getmxrr("wjgilmore.com", $mxhosts);
    print_r($mxhosts);
?>
This returns the following output:
Array ( [0] => aspmx.l.google.com)

Services

Although we often use the word Internet in a generalized sense, referring to it in regard to chatting, reading, or downloading the latest version of some game, what we’re actually referring to is one or several Internet services that collectively define this communication platform. Examples of these services include HTTP, HTTPS, FTP, POP3, IMAP, and SSH. For various reasons (an explanation of which is beyond the scope of this book), each service commonly operates on a particular communications port. For example, HTTP’s default port is 80, and SSH’s default port is 22. These days, the widespread need for firewalls at all levels of a network makes knowledge of such matters quite important. Two PHP functions, getservbyname() and getservbyport() , are available for learning more about services and their corresponding port numbers.

Retrieving a Service’s Port Number

The getservbyname() function returns the port number of a specified service. Its prototype follows:
int getservbyname(string service, string protocol)
The service corresponding to service must be specified using the same name as that found in the /etc/services file or C:WindowsSystem32driversetc on a Windows system. The protocol parameter specifies whether you’re referring to the tcp or udp component of this service. Consider an example:
<?php
    echo "HTTP's default port number is: ".getservbyname("http", "tcp");
?>
This returns the following:
HTTP's default port number is: 80

Retrieving a Port Number’s Service Name

The getservbyport() function returns the name of the service corresponding to the supplied port number. Its prototype follows:
string getservbyport(int port, string protocol)
The protocol parameter specifies whether you’re referring to the tcp or the udp component of the service. Consider an example:
<?php
    echo "Port 80's default service is: ".getservbyport(80, "tcp");
?>
This returns the following:
Port 80's default service is: www

Establishing Socket Connections

In today’s networked environment, you’ll often want to query services, both local and remote. This is often done by establishing a socket connection with that service. This section demonstrates how this is accomplished, using the fsockopen() function . Its prototype follows:
resource fsockopen(string target, int port [, int errno [, string errstring
                   [, float timeout]]])

The fsockopen() function establishes a connection to the resource designated by target on port, returning error information to the optional parameters errno and errstring. The optional parameter timeout sets a time limit, in seconds, on how long the function will attempt to establish the connection before failing.

The first example shows how to establish a port 80 connection to www.example.com using fsockopen() and how to output the index page:
<?php
    // Establish a port 80 connection with www.example.com
    $http = fsockopen("www.example.com",80);
    // Send a request to the server
    $req = "GET / HTTP/1.1 ";
    $req .= "Host: www.example.com ";
    $req .= "Connection: Close ";
    fputs($http, $req);
    // Output the request results
    while(!feof($http)) {
        echo fgets($http, 1024);
    }
    // Close the connection
    fclose($http);
?>
This returns the following output:
HTTP/1.1 200 OK
Cache-Control: max-age=604800
Content-Type: text/html
Date: Sun, 25 Feb 2018 23:12:08 GMT
Etag: "1541025663+gzip+ident"
Expires: Sun, 04 Mar 2018 23:12:08 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Server: ECS (sea/5557)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1270
Connection: close
<!doctype html>
<html>
<head>
    <title>Example Domain</title>
    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 50px;
        background-color: #fff;
        border-radius: 1em;
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        body {
            background-color: #fff;
        }
        div {
            width: auto;
            margin: 0 auto;
            border-radius: 0;
            padding: 1em;
        }
    }
    </style>
</head>
<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is established to be used for illustrative examples in documents . You may use this
    domain in examples without prior coordination or asking for permission.</p>
    <p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

The output shows the complete response from the server (headers and body). Using PHP to retrieve content via an HTTP-based service can be done with a single function call to file_get_contents() which only returns the body part, but for other services that follow a protocol not known to PHP, it’s necessary to use the socket function and manually build the support and shown in the above example.

The second example, shown in Listing 16-1, demonstrates how to use fsockopen() to build a rudimentary port scanner.
<?php
    // Give the script enough time to complete the task
    ini_set("max_execution_time", 120);
    // Define scan range
    $rangeStart = 0;
    $rangeStop = 1024;
    // Which server to scan?
    $target = "localhost";
    // Build an array of port values
    $range =range($rangeStart, $rangeStop);
    echo "<p>Scan results for $target</p>";
    // Execute the scan
    foreach ($range as $port) {
        $result = @fsockopen($target, $port,$errno,$errstr,1);
        if ($result) echo "<p>Socket open at port $port</p>";
    }
?>
Listing 16-1

Creating a Port Scanner with fsockopen()

Scanning my local machine using this script produces the following output:
Scan results for localhost
Socket open at port 22
Socket open at port 80
Socket open at port 631

Note that running the scan of a remote computer will most likely cause the requests to be blocked by the firewall.

A far lazier means for accomplishing the same task involves using a program execution command such as system() and the wonderful free software package Nmap ( https://nmap.org/ ). This method is demonstrated in the “Common Networking Tasks” section.

Mail

The powerful Mail feature of PHP is so darned useful, and needed in so many web applications, that this section is likely to be one of the more popular sections of this chapter, if not the whole book. In this section, you’ll learn how to send e-mail using PHP’s popular mail() function , including how to control headers, include attachments, and carry out other commonly desired tasks.

This section introduces the relevant configuration directives, describes PHP’s mail() function , and concludes with several examples highlighting this function’s many usage variations.

Configuration Directives

There are five configuration directives pertinent to PHP’s mail() function . Pay close attention to the descriptions because each is platform-specific.

SMTP = string

Scope: PHP_INI_ALL; Default value: localhost

The SMTP directive sets the Mail Transfer Agent (MTA) for PHP’s Windows platform version of the mail function. Note that this is only relevant to the Windows platform because Unix platform implementations of this function are actually just wrappers around that operating system’s mail function. Instead, the Windows implementation depends on a socket connection made to either a local or a remote MTA, defined by this directive.

sendmail_from = string

Scope: PHP_INI_ALL; Default value: NULL

The sendmail_from directive sets the From field and the return path of the message header.

sendmail_path = string

Scope: PHP_INI_SYSTEM ; Default value: the default sendmail path

The sendmail_path directive sets the path to the sendmail binary if it’s not in the system path, or if you’d like to pass additional arguments to the binary. By default, this is set to the following:
sendmail -t -i

Keep in mind that this directive only applies to the Unix platform. Windows depends upon establishing a socket connection to an SMTP server specified by the SMTP directive on port smtp_port.

smtp_port = integer

Scope: PHP_INI_ALL; Default value: 25

The smtp_port directive sets the port used to connect to the server specified by the SMTP directive.

mail.force_extra_parameters = string

Scope: PHP_INI_SYSTEM; Default value: NULL

You can use the mail.force_extra_parameters directive to pass additional flags to the sendmail binary. Note that any parameters passed here will replace those passed in via the mail() function’s addl_params parameter .

Sending E-mail Using a PHP Script

E-mail can be sent through a PHP script in amazingly easy fashion, using the mail() function . Its prototype follows:
boolean mail(string to, string subject, string message [, string addl_headers [, string addl_params]])

The mail() function can send an e-mail with a subject and a message to one or several recipients. You can tailor many of the e-mail properties using the addl_headers parameter; you can even modify your SMTP server’s behavior by passing extra flags via the addl_params parameter. Note that the function does not validate the contents of the addl_headers parameter. Adding multiple newlines will break the e-mail. Make sure you only add valid headers.

On the Unix platform, PHP’s mail() function is dependent upon the sendmail MTA. If you’re using an alternative MTA (e.g., qmail), you need to use that MTA’s sendmail wrappers. PHP’s Windows implementation of the function depends upon establishing a socket connection to an MTA designated by the SMTP configuration directive, introduced in the previous section.

The remainder of this section is devoted to numerous examples highlighting the many capabilities of this simple yet powerful function.

Sending a Plain-Text E-mail

Sending the simplest of e-mails is trivial using the mail() function , done using just the three required parameters, in addition to the fourth parameter, which allows you to identify a sender. Here’s an example:
<?php
    mail("[email protected]", "This is a subject", "This is the mail body",
           "From:[email protected] ");
?>

Take particular note of how the sender address is set, including the (carriage return plus line feed) characters. Neglecting to format the address in this manner will produce unexpected results or cause the function to fail altogether.

Taking Advantage of PHPMailer

While it’s possible to use the mail() function to perform more complex operations such as sending to multiple recipients, annoying users with HTML-formatted e-mail, or including attachments, doing so can be a tedious and error-prone process. However, the PHPMailer library ( https://github.com/PHPMailer/PHPMailer ) make such tasks a breeze.

Installing PHPMailer
Installing this library is easy, and it’s done with the composer tool, described earlier. Either add the following line to your composer.json file and run composer update in that directory:
"phpmailer/phpmailer": "~6.0"
You can also runn the following command line to install the files:
composer require phpmailer/phpmailer
This will install the files in your local vendor folder and the files are ready to use. The output from the instalPackage operations: 1 install, 11 updates, 0 removals
  - Updating symfony/polyfill-mbstring (v1.6.0 => v1.7.0): Downloading (100%)
  - Updating symfony/translation (v3.4.1 => v4.0.4): Downloading (100%)
  - Updating php-http/discovery (1.3.0 => 1.4.0): Downloading (100%)
  - Updating symfony/event-dispatcher (v2.8.32 => v2.8.34): Downloading (100%)
  - Installing phpmailer/phpmailer (v6.0.3): Downloading (100%)
  - Updating geoip/geoip dev-master (1f94041 => b82fe29):  Checking out b82fe29281
  - Updating nesbot/carbon dev-master (926aee5 => b1ab4a1):  Checking out b1ab4a10fc
  - Updating ezyang/htmlpurifier dev-master (5988f29 => c1167ed):  Checking out c1167edbf1
  - Updating guzzlehttp/guzzle dev-master (501c7c2 => 748d67e):  Checking out 748d67e23a
  - Updating paypal/rest-api-sdk-php dev-master (81c2c17 => 219390b):  Checking out 219390b793
  - Updating piwik/device-detector dev-master (caf2d15 => 319d108):  Checking out 319d108899
  - Updating twilio/sdk dev-master (e9bc80c => d33971d):  Checking out d33971d26a
phpmailer/phpmailer suggests installing league/oauth2-google (Needed for Google XOAUTH2 authentication)
phpmailer/phpmailer suggests installing hayageek/oauth2-yahoo (Needed for Yahoo XOAUTH2 authentication)
phpmailer/phpmailer suggests installing stevenmaguire/oauth2-microsoft (Needed for Microsoft XOAUTH2 authentication)lation will look similar to this:
Sending an E-mail with PHPMailer
Using the PHPMailer classes require the use of two namespaces and then inclusion of the composer’s autoload.php script. Any script that uses this functionality should include these lines at the top:
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;
//Load composer's autoloader
require 'vendor/autoload.php';
The process of sending an email starts with instatioation of the PHPMailer class:
$mail = new PHPMailer(true);        // True indicates that exceptions are used.

With the $mail object you can now add sender address, one or more receipients, specify the SMTP host. etc.

If your web server has access to an SMTP server on localhost without authentication, you can use a simple script like this to send an e-mail:
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;
//Load composer's autoloader
require 'autoload.php';
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = "localhost";
$mail->setFrom('[email protected]', 'Web Site');
$mail->addAddress('[email protected]');
$mail->Subject = 'Thank you for the order';
$mail->Body = "Your package will ship out asap!";
$mail->send();
?>

In order to send the mail to multiple receipients, you can keep calling the addAddress() method for each receipient. The object also supports addCC() and addBCC() methods.

If your mail server requires authentication, you can tweak the configuration with the following lines:
$mail->isSMTP();                                      // Set mailer to use SMTP
$mail->Host = 'smtp1.example.com;smtp2.example.com';  // Specify main and backup SMTP servers
$mail->SMTPAuth = true;                               // Enable SMTP authentication
$mail->Username = '[email protected]';                 // SMTP username
$mail->Password = 'secret';                           // SMTP password
$mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587;                                    // TCP port to connect to
So far the e-mail message contains only plain text. In order to change it to include HTML content, you would need to call the isHTML() method with the parameter true.
$mail->isHTML(true);

Note its possible to assign a HTML string to the Body property, and it’s good practice to also include a value for the AltBody property. The AltBody property will be the version the user will see if the e-mail is rendered in a client that’s not capable of rendering HTML messages.

Finally, adding attachments are also very simple. The method addAttachment() takes a filename with the full path and will attach the file to the message. Calling addAttachment() multiple times will allow for attachment of multiple files. Note that some mail systems restrict the total size of e-mails, and might even filter out e-mails with executables or other file types known to carry malware. It might be simpler to include a link to where the user can download the file.

Common Networking Tasks

Although various command-line applications have long been capable of performing the networking tasks demonstrated in this section, offering a means for carrying them out via the Web certainly can be useful. Although the command-line counterparts are far more powerful and flexible, viewing such information via the Web is at times simply more convenient. Whatever the reason, it’s likely you could put to good use some of the applications found in this section.

Note

Several examples in this section use the system() function . This function is introduced in Chapter 10.

Pinging a Server

Verifying a server’s connectivity is a commonplace administration task. The following example shows you how to do so using PHP:
<?php
    // Which server to ping?
    $server = "www.example.com";
    // Ping the server how many times?
    $count = 3;
    // Perform the task
    echo "<pre>";
    system("ping -c {$count} {$server}");
    echo "</pre>";
?>

The preceding code should be fairly straightforward. Using a fixed number of counts in the ping request will cause the ping command to terminate when that is reached, and the output will then be returned to PHP and passed back to the client.

Sample output follows:
PING www.example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=60 time=0.798 ms
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=60 time=0.846 ms
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=3 ttl=60 time=0.828 ms
--- www.example.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2027ms
rtt min/avg/max/mdev = 0.798/0.824/0.846/0.019 ms

PHP’s program execution functions are great because they allow you to take advantage of any program installed on the server that has the appropriate permissions assigned.

Creating a Port Scanner

The introduction of fsockopen() earlier in this chapter is accompanied by a demonstration of how to create a port scanner. However, like many of the tasks introduced in this section, this can be accomplished much more easily using one of PHP’s program execution functions. The following example uses PHP’s system() function and the Nmap (network mapper) tool :
<?php
    $target = "localhost";
    echo "<pre>";
    system("nmap {$target}");
    echo "</pre>";
?>
A snippet of the sample output follows:
Starting Nmap 6.40 ( http://nmap.org ) at 2018-02-25 19:00 PST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00042s latency).
Other addresses for localhost (not scanned): 127.0.0.1
Not shown: 991 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
25/tcp   open  smtp
53/tcp   open  domain
80/tcp   open  http
443/tcp  open  https
3306/tcp open  mysql
5432/tcp open  postgresql
8080/tcp open  http-proxy
9000/tcp open  cslistener
Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds

The listed port numbers indicate what the web server has access to on the host. The firewall might prevent access to any of these ports from the Internet.

Creating a Subnet Converter

You’ve probably at one time scratched your head trying to figure out some obscure network configuration issue. Most commonly, the culprit for such woes seems to center on a faulty or an unplugged network cable. Perhaps the second most common problem is a mistake made when calculating the necessary basic network ingredients: IP addressing, subnet mask, broadcast address, network address, and the like. To remedy this, a few PHP functions and bitwise operations can be coaxed into doing the calculations for you. When provided an IP address and a bitmask, Listing 16-2 calculates several of these components.
<form action="listing16-2.php" method="post">
<p>
IP Address:<br />
<input type="text" name="ip[]" size="3" maxlength="3" value="" />.
<input type="text" name="ip[]" size="3" maxlength="3" value="" />.
<input type="text" name="ip[]" size="3" maxlength="3" value="" />.
<input type="text" name="ip[]" size="3" maxlength="3" value="" />
</p>
<p>
Subnet Mask:<br />
<input type="text" name="sm[]" size="3" maxlength="3" value="" />.
<input type="text" name="sm[]" size="3" maxlength="3" value="" />.
<input type="text" name="sm[]" size="3" maxlength="3" value="" />.
<input type="text" name="sm[]" size="3" maxlength="3" value="" />
</p>
<input type="submit" name="submit" value="Calculate" />
</form>
<?php
    if (isset($_POST['submit'])) {
        // Concatenate the IP form components and convert to IPv4 format
        $ip = implode('.', $_POST['ip']);
        $ip = ip2long($ip);
        // Concatenate the netmask form components and convert to IPv4 format
        $netmask = implode('.', $_POST['sm']);
        $netmask = ip2long($netmask);
        // Calculate the network address
        $na = ($ip & $netmask);
        // Calculate the broadcast address
        $ba = $na | (~$netmask);
        // Number of hosts
        $h = ip2long(long2ip($ba)) - ip2long(long2ip($na));
        // Convert the addresses back to the dot-format representation and display
        echo "Addressing Information: <br />";
        echo "<ul>";
        echo "<li>IP Address: ". long2ip($ip)."</li>";
        echo "<li>Subnet Mask: ". long2ip($netmask)."</li>";
        echo "<li>Network Address: ". long2ip($na)."</li>";
        echo "<li>Broadcast Address: ". long2ip($ba)."</li>";
        echo "<li>Total Available Hosts: ".($h - 1)."</li>";
        echo "<li>Host Range: ". long2ip($na + 1)." -  ".
              long2ip($ba - 1)."</li>";
       echo "</ul>";
    }
?>
Listing 16-2

A Subnet Converter

Consider an example. If you supply 192.168.1.101 as the IP address and 255.255.255.0 as the subnet mask, you should see the output shown in Figure 16-1.
../images/314623_5_En_16_Chapter/314623_5_En_16_Fig1_HTML.jpg
Figure 16-1

Calculating network addressing

Summary

Many of PHP’s networking capabilities won’t soon replace those tools already offered on the command line or other well-established clients. Nonetheless, as PHP’s command-line capabilities continue to gain traction, it’s likely you’ll quickly find a use for some of the material presented in this chapter, perhaps the e-mail dispatch capabilities if nothing else.

The next chapter introduces the session functions. Sessions are used to store data between requests.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.174.168