Metadata-Version: 2.4
Name: pyminitcp
Version: 2.1.0
Summary: A tiny, dependency-free Python library for TCP and UDP connectivity checks with IPv4/IPv6, DNS, detailed error diagnostics, and optional protocol probing.
Home-page: https://github.com/roxy-wi/pyminitcp
Author: Pavel Loginov
Author-email: aidaho@roxy-wi.org
License: MIT
Keywords: tcp udp network check ipv6 ipv4 monitoring
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: System :: Networking
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: requires-python
Dynamic: summary

# pyminitcp

![PyPI version](https://img.shields.io/pypi/v/pyminitcp)
![Build status](https://github.com/roxy-wi/pyminitcp/actions/workflows/ci.yml/badge.svg)
![Python versions](https://img.shields.io/pypi/pyversions/pyminitcp)
![License](https://img.shields.io/pypi/l/pyminitcp)

A tiny, dependency-free Python library for TCP and UDP connectivity checks with IPv4/IPv6, DNS, detailed error diagnostics, and optional protocol probing.

- No dependencies
- IPv4 / IPv6 support
- DNS + connect timing
- UDP payload support
- Detailed error info (`phase`, `errno`)
- Optional banner / protocol probing

---

## Installation

```bash
pip install pyminitcp
```

---

## Usage (CLI)

### TCP check

```bash
pyminitcp example.com 443
```

### UDP check

```bash
pyminitcp example.com 53 --udp
```

---

## Banner / protocol probe

Read data after connect:

```bash
pyminitcp example.com 22 --banner
```

Require banner (fail if not received):

```bash
pyminitcp example.com 22 --banner --require-banner
```

---

## Send data before reading response

### HTTP

```bash
pyminitcp example.com 80 \
  --banner --require-banner \
  --send-data $'HEAD / HTTP/1.0\r\nHost: example.com\r\n\r\n'
```

### Redis

```bash
pyminitcp 127.0.0.1 6379 \
  --banner --require-banner \
  --send-data $'PING\r\n'
```

### Hex payload

```bash
pyminitcp host 12345 --banner --send-hex 50494e470d0a
```

---

## Typical probes

| Service | Port | Options | Request data | Expected banner / response | Notes |
|---|---:|---|---|---|---|
| SSH | 22 | `--banner` | none | `SSH-2.0-...` | Usually sends banner immediately after connect |
| SMTP | 25 | `--banner --require-banner` | none | `220 ...` | Greeting usually arrives without request |
| SMTPS | 465 | `--banner` | none | often none | Usually TLS first, plain banner is not expected |
| FTP | 21 | `--banner --require-banner` | none | `220 ...` | Classic FTP greeting |
| POP3 | 110 | `--banner --require-banner` | none | `+OK ...` | Usually sends greeting immediately |
| IMAP | 143 | `--banner --require-banner` | none | `* OK ...` | Usually sends greeting immediately |
| HTTP | 80 | `--banner --require-banner --send-data $'HEAD / HTTP/1.0\r\nHost: example.com\r\n\r\n'` | `HEAD / HTTP/1.0` | `HTTP/1.0 200 OK` or similar | HTTP does not send banner until request |
| HTTPS | 443 | not suitable for plain banner probe | none | none | Needs TLS probe, not plain TCP banner read |
| Redis | 6379 | `--banner --require-banner --send-data $'PING\r\n'` | `PING\r\n` | `+PONG` | Good lightweight protocol probe |
| Memcached | 11211 | `--banner --require-banner --send-data $'version\r\n'` | `version\r\n` | `VERSION ...` | Simple text command |
| MySQL | 3306 | `--banner` | none | handshake packet | Response is binary, banner may be unreadable text |
| PostgreSQL | 5432 | `--banner` or custom request | none | usually none | Better with a protocol-specific probe |
| DNS over UDP | 53 | `--udp --hex-payload <dns_query_hex>` | DNS query | binary response | Best used with a real DNS query payload |
| NTP over UDP | 123 | `--udp --hex-payload <ntp_query_hex>` | NTP request | binary response | Response is binary |
| Custom TCP service | custom | `--banner` or `--banner --send-data ...` | service-specific | service-specific | Useful for app protocols with text replies |

---

## CLI options

```text
--udp               Use UDP instead of TCP
--timeout           Timeout (seconds)

--banner            Read response after connect
--require-banner    Fail if banner is not received
--read-bytes        Bytes to read (default: 1024)

--send-data         Send text before reading response
--send-hex          Send hex payload before reading response

--json              Output JSON
```

---

## Python usage

### TCP

```python
from pyminitcp import tcp_check

result = tcp_check("example.com", 443)
print(result)
```

### TCP + banner

```python
result = tcp_check(
    "example.com",
    80,
    banner=True,
    require_banner=True,
    request_data=b"HEAD / HTTP/1.0\r\nHost: example.com\r\n\r\n"
)
```

---

## Result fields

```json
{
  "status": 1,
  "resp_time": 0.012,
  "error": "",
  "family": "AF_INET",
  "sockaddr": ["142.250.74.238", 443],
  "namelookup_time": 0.001,
  "connect_time": 0.010,
  "phase": null,
  "errno_code": null,
  "errno_name": null,
  "os_error": null,
  "banner": "HTTP/1.1 200 OK"
}
```

---

## Error model

Errors include detailed diagnostics:

| Field | Description |
|---|---|
| `phase` | `resolve` / `connect` / `send` / `recv` |
| `errno_code` | OS error code |
| `errno_name` | e.g. `ECONNREFUSED` |
| `os_error` | human-readable OS message |

### Example errors

#### Connection refused

```json
{
  "phase": "connect",
  "errno_name": "ECONNREFUSED"
}
```

#### DNS failure

```json
{
  "phase": "resolve"
}
```

#### Banner timeout

```json
{
  "phase": "recv",
  "error": "Timed out waiting for banner"
}
```

---

## Notes

- TCP check = L4 connectivity
- Banner probe = L7-style check
- UDP check expects response (request/response model)
- Some UDP services do not reply — use carefully

---

## License

MIT
