Files
derp/plugins/cidr.py
user 2e2378d3ee feat: add wave 1 plugins (dns, encode, hash, defang, revshell, cidr)
All pure stdlib, zero external dependencies:
- dns: raw UDP resolver with A/AAAA/MX/NS/TXT/CNAME/PTR/SOA
- encode: base64, hex, URL, ROT13 encode/decode
- hash: md5/sha1/sha256/sha512 generation + type identification
- defang: IOC defanging/refanging for safe sharing
- revshell: reverse shell one-liners for 11 languages
- cidr: subnet calculator with IP membership check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:46:13 +01:00

79 lines
2.3 KiB
Python

"""Plugin: CIDR/subnet calculator."""
from __future__ import annotations
import ipaddress
from derp.plugin import command
@command("cidr", help="Subnet info: !cidr <network> | !cidr contains <net> <ip>")
async def cmd_cidr(bot, message):
"""Calculate subnet properties or check IP membership.
!cidr 192.168.1.0/24
!cidr contains 10.0.0.0/8 10.1.2.3
"""
parts = message.text.split()
if len(parts) < 2:
await bot.reply(message, "Usage: !cidr <network> | !cidr contains <net> <ip>")
return
subcmd = parts[1].lower()
if subcmd == "contains" and len(parts) >= 4:
await _contains(bot, message, parts[2], parts[3])
elif subcmd == "contains":
await bot.reply(message, "Usage: !cidr contains <network> <ip>")
else:
await _info(bot, message, parts[1])
async def _info(bot, message, network_str: str) -> None:
"""Show subnet information."""
try:
net = ipaddress.ip_network(network_str, strict=False)
except ValueError:
await bot.reply(message, f"Invalid network: {network_str}")
return
if isinstance(net, ipaddress.IPv4Network):
host_count = net.num_addresses - 2 if net.prefixlen < 31 else net.num_addresses
parts = [
f"net:{net.network_address}/{net.prefixlen}",
f"range:{net[0]}-{net[-1]}",
f"hosts:{host_count}",
f"mask:{net.netmask}",
f"wildcard:{net.hostmask}",
]
if net.prefixlen < 31:
parts.append(f"broadcast:{net.broadcast_address}")
else:
parts = [
f"net:{net.network_address}/{net.prefixlen}",
f"range:{net[0]}-{net[-1]}",
f"hosts:{net.num_addresses}",
]
await bot.reply(message, " | ".join(parts))
async def _contains(bot, message, network_str: str, ip_str: str) -> None:
"""Check if an IP belongs to a network."""
try:
net = ipaddress.ip_network(network_str, strict=False)
except ValueError:
await bot.reply(message, f"Invalid network: {network_str}")
return
try:
addr = ipaddress.ip_address(ip_str)
except ValueError:
await bot.reply(message, f"Invalid IP: {ip_str}")
return
if addr in net:
await bot.reply(message, f"{addr} is in {net}")
else:
await bot.reply(message, f"{addr} is NOT in {net}")