<?php
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../includes/functions.php';

$page_title   = 'Port Check – Check if a Port is Open';
$page_desc    = 'Free Port Check: verify if a specific TCP port is open or closed on any server – from Düsseldorf, Germany on ipcheck.tools.';
$page_current = 'port-check';

$query   = trim(strip_tags($_GET['host'] ?? ''));
$port    = isset($_GET['port']) ? (int)$_GET['port'] : null;
$results = [];
$error   = '';
$ip      = '';

$known_ports = [
    21 => 'FTP', 22 => 'SSH', 25 => 'SMTP', 53 => 'DNS',
    80 => 'HTTP', 110 => 'POP3', 143 => 'IMAP', 443 => 'HTTPS',
    465 => 'SMTPS', 587 => 'SMTP (TLS)', 993 => 'IMAPS', 995 => 'POP3S',
    1433 => 'MSSQL', 3306 => 'MySQL', 3389 => 'RDP', 5432 => 'PostgreSQL',
    6379 => 'Redis', 8080 => 'HTTP-Alt', 8443 => 'HTTPS-Alt', 27017 => 'MongoDB',
];

if ($query && $port) {
    if ($port < 1 || $port > 65535) {
        $error = 'Invalid port. Allowed range: 1–65535.';
    } else {
        $host = preg_replace('/^https?:\/\//i', '', $query);
        $host = explode('/', $host)[0];
        if (filter_var($host, FILTER_VALIDATE_IP)) {
            $ip = $host;
        } else {
            $ip = @gethostbyname($host);
            if ($ip === $host) { $error = 'Could not resolve host.'; $ip = ''; }
        }
        if ($ip && !$error) {
            set_time_limit(10);
            $start = microtime(true);
            $fp    = @fsockopen($ip, $port, $errno, $errstr, 3);
            $ms    = round((microtime(true) - $start) * 1000, 1);
            if ($fp) { fclose($fp); $results = ['status' => 'open', 'ms' => $ms]; }
            else { $results = ['status' => 'closed', 'ms' => $ms, 'error' => $errstr]; }
        }
    }
}

$dangerous_ports = [
    3306  => ['name' => 'MySQL',      'warn' => 'A publicly accessible MySQL database is a significant security risk. Attackers can perform brute-force attacks or exploit known vulnerabilities. MySQL should only be accessible internally or via SSH tunnel.'],
    5432  => ['name' => 'PostgreSQL', 'warn' => 'PostgreSQL should never be directly accessible from the internet. Bind the service to 127.0.0.1 or use a firewall to block port 5432.'],
    27017 => ['name' => 'MongoDB',    'warn' => 'A publicly accessible MongoDB is extremely dangerous – many instances without authentication have already been compromised. Secure immediately with firewall rules.'],
    6379  => ['name' => 'Redis',      'warn' => 'Redis has no authentication by default. A public Redis port allows full data access and can be exploited for server takeover.'],
    3389  => ['name' => 'RDP',        'warn' => 'An open RDP port is a common target for brute-force and ransomware attacks. Restrict access via firewall or use a VPN.'],
    1433  => ['name' => 'MSSQL',      'warn' => 'Microsoft SQL Server should not be directly accessible from the internet. Use a firewall and restrict access to trusted IPs.'],
];

$info_ports = [
    80  => ['links' => [['url' => '/en/ssl-check.php?host='.urlencode($query), 'icon' => 'ti-lock', 'label' => 'SSL Check'], ['url' => '/en/headers.php?url='.urlencode($query), 'icon' => 'ti-eye', 'label' => 'HTTP Headers']], 'info' => 'HTTP is active. Port 80 is unencrypted – a redirect to HTTPS (port 443) should be configured.'],
    443 => ['links' => [['url' => '/en/ssl-check.php?host='.urlencode($query), 'icon' => 'ti-lock', 'label' => 'SSL Check'], ['url' => '/en/headers.php?url='.urlencode('https://'.$query), 'icon' => 'ti-eye', 'label' => 'HTTP Headers']], 'info' => 'HTTPS is active. Check the SSL certificate for validity and security configuration.'],
    22  => ['links' => [['url' => '/en/ip-lookup.php?ip='.urlencode($ip), 'icon' => 'ti-world-search', 'label' => 'IP Lookup']], 'info' => 'SSH is open. Make sure only key-based authentication is allowed and root login is disabled.'],
    25  => ['links' => [['url' => '/en/blacklist.php?ip='.urlencode($ip), 'icon' => 'ti-shield-search', 'label' => 'Blacklist Check']], 'info' => 'SMTP is open. Check if the mail server is listed on spam blacklists.'],
    587 => ['links' => [['url' => '/en/blacklist.php?ip='.urlencode($ip), 'icon' => 'ti-shield-search', 'label' => 'Blacklist Check']], 'info' => 'SMTP Submission (TLS) is open. This port is used for sending email from mail clients.'],
    53  => ['links' => [['url' => '/en/dns-lookup.php?domain='.urlencode($query), 'icon' => 'ti-search', 'label' => 'DNS Lookup']], 'info' => 'DNS is open. Make sure the DNS server does not allow recursive queries from external IPs (open resolver).'],
];

require_once __DIR__ . '/header.php';
?>

<div class="hero">
  <div class="hero-label">Tool</div>
  <div class="hero-title">Port Check</div>
  <div class="hero-sub">
    Check if a port is open · Location:
    <img src="https://flagcdn.com/20x15/de.png" width="20" height="15" alt="DE"
         style="vertical-align:middle; border-radius:2px; margin:0 3px;">
    Düsseldorf, Germany
  </div>
  <form method="GET" action="/en/port-check.php" onsubmit="startLoading()">
    <div class="input-group" style="max-width:660px;">
      <input class="input-text" type="text" name="host"
             value="<?= h($query) ?>"
             placeholder="Domain or IP, e.g. example.com or 8.8.8.8"
             required />
      <input class="input-text" type="number" name="port"
             value="<?= h($port) ?>"
             placeholder="Port"
             min="1" max="65535"
             style="width:100px; flex-shrink:0;"
             required />
      <button type="submit" class="btn btn-primary" id="check-btn">
        <span id="btn-content"><i class="ti ti-plug"></i> Check</span>
        <span id="btn-spinner" style="display:none; align-items:center; gap:8px;">
          <svg style="animation:apple-spin 1s linear infinite;" viewBox="0 0 24 24" width="18" height="18">
            <circle cx="12" cy="12" r="9" fill="none" stroke="rgba(147,197,253,0.2)" stroke-width="2.5"/>
            <path d="M12 3 A9 9 0 0 1 21 12" fill="none" stroke="#93c5fd" stroke-width="2.5" stroke-linecap="round"/>
          </svg>
          Checking...
        </span>
      </button>
    </div>
  </form>
</div>

<div class="wrap">

  <div class="ad-slot"><ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-8287576653347400" data-ad-slot="2715725452" data-ad-format="auto" data-full-width-responsive="true"></ins><script>(adsbygoogle = window.adsbygoogle || []).push({});</script></div>

  <?php if ($error): ?>
    <div class="alert alert-danger"><i class="ti ti-alert-circle"></i><span><?= h($error) ?></span></div>

  <?php elseif ($results): ?>

    <div class="stat-grid">
      <div class="stat">
        <div class="stat-val" style="color:<?= $results['status'] === 'open' ? 'var(--green)' : 'var(--red)' ?>; font-size:16px;">
          <?= $results['status'] === 'open' ? 'Open' : 'Closed' ?>
        </div>
        <div class="stat-key">Status</div>
      </div>
      <div class="stat">
        <div class="stat-val" style="font-family:var(--font-mono);"><?= h($port) ?></div>
        <div class="stat-key">Port</div>
      </div>
      <div class="stat">
        <div class="stat-val" style="font-size:13px;"><?= $known_ports[$port] ?? 'Unknown' ?></div>
        <div class="stat-key">Service</div>
      </div>
      <div class="stat">
        <div class="stat-val" style="font-family:var(--font-mono);"><?= $results['ms'] ?> ms</div>
        <div class="stat-key">Response time</div>
      </div>
    </div>

    <div class="grid2">
      <div class="card <?= $results['status'] === 'open' ? 'card-green' : 'card-blue' ?>">
        <div class="card-title">
          <i class="ti <?= $results['status'] === 'open' ? 'ti-plug' : 'ti-plug-x' ?>"></i>
          Port <?= h($port) ?> is <?= $results['status'] === 'open' ? 'open' : 'closed' ?>
        </div>
        <div class="data-row"><span class="dk">Host</span><span class="dv mono"><?= h($query) ?></span></div>
        <div class="data-row"><span class="dk">IP Address</span><span class="dv mono blue"><?= h($ip) ?></span></div>
        <div class="data-row"><span class="dk">Port</span><span class="dv mono"><?= h($port) ?></span></div>
        <div class="data-row"><span class="dk">Service</span><span class="dv"><?= $known_ports[$port] ?? '–' ?></span></div>
        <div class="data-row"><span class="dk">Response time</span><span class="dv mono"><?= $results['ms'] ?> ms</span></div>
        <div class="data-row">
          <span class="dk">Status</span>
          <span class="dv" style="color:<?= $results['status'] === 'open' ? 'var(--green)' : 'var(--red)' ?>; font-weight:600;">
            <?= $results['status'] === 'open' ? '✓ Open – port is reachable' : '✗ Closed – port not reachable' ?>
          </span>
        </div>
      </div>

      <div class="card">
        <div class="card-title"><i class="ti ti-info-circle"></i> What does this mean?</div>
        <?php if ($results['status'] === 'open'): ?>
          <?php if (isset($dangerous_ports[$port])): ?>
          <div class="alert alert-danger" style="margin-bottom:12px;">
            <i class="ti ti-alert-triangle"></i>
            <div>
              <strong>Security warning: <?= $dangerous_ports[$port]['name'] ?> publicly reachable!</strong><br>
              <span style="font-size:12px;"><?= $dangerous_ports[$port]['warn'] ?></span>
            </div>
          </div>
          <?php elseif (isset($info_ports[$port])): ?>
          <p style="font-size:13px; color:var(--text3); line-height:1.7; margin-bottom:12px;"><?= $info_ports[$port]['info'] ?></p>
          <div style="display:flex; gap:8px; flex-wrap:wrap;">
            <?php foreach ($info_ports[$port]['links'] as $link): ?>
            <a href="<?= $link['url'] ?>" class="btn btn-primary" style="font-size:12px; padding:6px 14px;">
              <i class="ti <?= $link['icon'] ?>"></i> <?= $link['label'] ?>
            </a>
            <?php endforeach; ?>
          </div>
          <?php else: ?>
          <p style="font-size:13px; color:var(--text3); line-height:1.7;">Port <strong><?= h($port) ?></strong><?php if (isset($known_ports[$port])): ?> (<strong><?= $known_ports[$port] ?></strong>)<?php endif; ?> is reachable from our server in Düsseldorf. The service is running and accepting connections.</p>
          <div style="margin-top:12px;">
            <a href="/en/ip-lookup.php?ip=<?= urlencode($ip) ?>" class="btn btn-primary" style="font-size:12px; padding:6px 14px;">
              <i class="ti ti-world-search"></i> IP Lookup
            </a>
          </div>
          <?php endif; ?>
        <?php else: ?>
          <p style="font-size:13px; color:var(--text3); line-height:1.7;">Port <strong><?= h($port) ?></strong> is not reachable. Possible reasons: the service is not running, a firewall is blocking the port, or the port is intentionally closed.</p>
        <?php endif; ?>
      </div>
    </div>

    <div class="card">
      <div class="card-title"><i class="ti ti-list"></i> Quick check common ports</div>
      <div style="display:flex; flex-wrap:wrap; gap:8px;">
        <?php foreach ([80, 443, 22, 21, 25, 587, 3306, 5432, 3389, 8080] as $p): ?>
        <a href="/en/port-check.php?host=<?= urlencode($query) ?>&port=<?= $p ?>"
           class="copy-btn" style="margin-top:0; <?= $p == $port ? 'background:#1e3a1e; border-color:#2d5a2d; color:var(--green);' : '' ?>">
          <strong><?= $p ?></strong> <span style="color:var(--text4); font-size:11px;"><?= $known_ports[$p] ?></span>
        </a>
        <?php endforeach; ?>
      </div>
    </div>

  <?php else: ?>
    <div class="alert alert-info">
      <i class="ti ti-info-circle"></i>
      <span>Enter a domain or IP address and a port number to check. Tests are performed from <strong>Düsseldorf, Germany</strong>. Please only test servers you own or have explicit permission to test.</span>
    </div>

    <div class="card">
      <div class="card-title"><i class="ti ti-list"></i> Common ports</div>
      <table class="result-table">
        <thead><tr><th>Port</th><th>Service</th><th>Description</th></tr></thead>
        <tbody>
          <?php $descs = [21=>'File transfer',22=>'Secure shell access',25=>'Send email',53=>'Domain resolution',80=>'Websites (unencrypted)',110=>'Retrieve email',143=>'Email (IMAP)',443=>'Websites (encrypted)',465=>'Email (SSL)',587=>'Email (TLS)',993=>'IMAP encrypted',995=>'POP3 encrypted',1433=>'Microsoft SQL Server',3306=>'MySQL database',3389=>'Windows Remote Desktop',5432=>'PostgreSQL database',6379=>'Redis cache',8080=>'Alternative web server',8443=>'Alternative HTTPS',27017=>'MongoDB database'];
          foreach ($known_ports as $p => $name): ?>
          <tr>
            <td class="mono" style="color:var(--blue-dim);"><?= $p ?></td>
            <td style="color:var(--text2);"><?= $name ?></td>
            <td style="font-size:11px; color:var(--text4);"><?= $descs[$p] ?? '–' ?></td>
          </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    </div>
  <?php endif; ?>

  <div class="alert alert-warn" style="font-size:12px;">
    <i class="ti ti-shield"></i>
    <span>Please only check servers and services that you own or have explicit permission to test. Unauthorized port scanning may be illegal.</span>
  </div>

  <div class="ad-slot"><ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-8287576653347400" data-ad-slot="2715725452" data-ad-format="auto" data-full-width-responsive="true"></ins><script>(adsbygoogle = window.adsbygoogle || []).push({});</script></div>

  <div class="tools-row">
    <a href="/en/"               class="tool-btn"><i class="ti ti-home"></i><span>My IP</span></a>
    <a href="/en/port-check.php" class="tool-btn current"><i class="ti ti-plug"></i><span>Port Check</span></a>
    <a href="/en/ping.php"       class="tool-btn"><i class="ti ti-activity"></i><span>Ping Test</span></a>
    <a href="/en/ssl-check.php"  class="tool-btn"><i class="ti ti-lock"></i><span>SSL Check</span></a>
    <a href="/en/blacklist.php"  class="tool-btn"><i class="ti ti-shield-search"></i><span>Blacklist</span></a>
  </div>

  <div class="seo-box">
    <h2>What is a Port Check?</h2>
    <p>A port check verifies whether a specific TCP port on a server is reachable from the outside. Ports are like doors to a server – each service listens on a specific port: web servers on port 80 (HTTP) and 443 (HTTPS), mail servers on port 25 (SMTP), SSH on port 22. If a port is closed, either the service is not running or a firewall is blocking access.</p>
  </div>

<style>@keyframes apple-spin { from { transform:rotate(0deg); } to { transform:rotate(360deg); } }</style>
<script>
function startLoading() {
  document.getElementById('btn-content').style.display = 'none';
  document.getElementById('btn-spinner').style.display = 'inline-flex';
}
</script>

<?php require_once __DIR__ . '/footer.php'; ?>
