Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/ffsshhttiikk/opencode-agents-skills --skill subnetting명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | subnetting |
| description | IP subnetting and network segmentation |
| category | networking |
| difficulty | intermediate |
| tags | ["ip","subnet","network","cidr","routing"] |
| author | OpenCode Community |
| version | 1 |
| last_updated | 2024-01-15T00:00:00.000Z |
I am Subnetting, the practice of dividing a larger network into smaller, manageable network segments. I enable efficient IP address allocation, improve network performance through broadcast domain reduction, and enhance security through network segmentation. I use CIDR (Classless Inter-Domain Routing) notation to define network boundaries. I help network administrators optimize address space utilization, implement security boundaries, and create hierarchical routing structures. I work with IPv4 and IPv6 addressing schemes, implementing variable length subnet masks (VLSM) for flexible network designs. I enable organizations to build scalable, secure, and manageable network infrastructures.
CIDR Notation: IP address with prefix length (e.g., 192.168.1.0/24)
Subnet Mask: 32-bit value separating network and host portions
Network Address: All host bits set to 0
Broadcast Address: All host bits set to 1
Usable Hosts: 2^(host_bits) - 2 (network + broadcast)
VLSM: Variable Length Subnet Masking for flexible subnet sizes
Supernetting/Route Aggregation: Combining multiple subnets into larger networks
Private Address Ranges: RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
import ipaddress
from typing import List, Tuple, Optional
from dataclasses import dataclass
from enum import Enum
class IPVersion(Enum):
IPv4 = 4
IPv6 = 6
@dataclass
class SubnetInfo:
network: str
netmask: str
prefix_length: int
version: IPVersion
num_addresses: int
usable_hosts: int
network_address: str
broadcast_address: str
first_usable: str
last_usable: str
cidr: str
binary_netmask: str
classful_class: Optional[str] = None
class SubnetCalculator:
def __init__(self):
pass
def calculate(self, cidr: str) -> SubnetInfo:
"""Calculate all subnet information from CIDR notation"""
net = ipaddress.ip_network(cidr, strict=False)
version = IPVersion.IPv4 if net.version == 4 else IPVersion.IPv6
first_usable = net.network_address + version == IPVersion.IPv4 net.network_address
last_usable = net.broadcast_address - version == IPVersion.IPv4 net.broadcast_address -
num_addresses = net.num_addresses
usable_hosts = (, num_addresses - ) version == IPVersion.IPv4 num_addresses -
SubnetInfo(
network=(net.network_address),
netmask=(net.netmask),
prefix_length=net.prefixlen,
version=version,
num_addresses=num_addresses,
usable_hosts=usable_hosts,
network_address=(net.network_address),
broadcast_address=(net.broadcast_address),
first_usable=(first_usable),
last_usable=(last_usable),
cidr=(net),
binary_netmask=._to_binary(net.netmask),
classful_class=._get_classful_class(net.network_address) version == IPVersion.IPv4
)
() -> :
.join( octet netmask.packed).rstrip()
() -> []:
first_octet = (ip.packed[])
<= first_octet <= :
<= first_octet <= :
<= first_octet <= :
<= first_octet <= :
<= first_octet <= :
() -> [SubnetInfo]:
net = ipaddress.ip_network(cidr, strict=)
new_prefix:
prefix_length = new_prefix
num_subnets:
current_prefix = net.prefixlen
needed_bits = (num_subnets - ).bit_length()
prefix_length = current_prefix + needed_bits
:
ValueError()
subnets = []
subnet net.subnets(new_prefix=prefix_length):
subnets.append(.calculate((subnet)))
subnets
() -> [SubnetInfo]:
nets = [ipaddress.ip_network(n, strict=) n networks]
summarized = (ipaddress.collapse_addresses(nets))
[.calculate((s)) s summarized]
() -> [SubnetInfo]:
net1 = ipaddress.ip_network(cidr1, strict=)
net2 = ipaddress.ip_network(cidr2, strict=)
combined = (ipaddress.collapse_addresses([net1, net2]))
(combined) == :
.calculate((combined[]))
() -> :
ipaddress.ip_network(subnet, strict=).subnet_of(
ipaddress.ip_network(parent, strict=)
)
() -> SubnetInfo:
needed_bits = (num_hosts + ).bit_length()
prefix_length = - needed_bits
prefer_largest:
prefix_length = (, prefix_length - )
network = ipaddress.IPv4Network(, strict=)
.calculate((network))
() -> [SubnetInfo]:
net = ipaddress.ip_network(starting_cidr, strict=)
sorted_reqs = (host_requirements, reverse=)
subnets = []
current_address = (net.network_address)
req sorted_reqs:
needed_hosts = req + net.version == req +
needed_bits = (needed_hosts - ).bit_length()
prefix_length = - needed_bits
subnet_size = ** needed_bits
subnet = ipaddress.IPv4Network(
,
strict=
)
subnets.append(.calculate((subnet)))
current_address += subnet_size
subnets
() -> :
packed = ipaddress.ip_address(ip).packed
.join( byte packed)
() -> [, ]:
net = ipaddress.ip_network(cidr, strict=)
((net.network_address), (net.broadcast_address))
__name__ == :
calc = SubnetCalculator()
()
info = calc.calculate()
()
()
()
()
()
()
()
subnets = calc.subnet_into(, new_prefix=)
i, subnet (subnets):
()
()
()
requirements = [, , , , ]
vlsm_subnets = calc.calculate_vlsm(requirements)
i, subnet (vlsm_subnets):
()
import socket
import subprocess
import concurrent.futures
from typing import List, Dict
from dataclasses import dataclass
from datetime import datetime
from subnetting import SubnetCalculator
@dataclass
class HostInfo:
ip: str
hostname: str
mac_address: str = "Unknown"
status: str = "unknown"
response_time_ms: float = 0.0
open_ports: List[int] = None
last_seen: datetime = None
class NetworkScanner:
def __init__(self, timeout: float = 1.0, max_workers: int = 100):
self.timeout = timeout
self.max_workers = max_workers
self.calculator = SubnetCalculator()
def ping_host(self, ip: str) -> bool:
"""Check if host is reachable via ICMP"""
try:
subprocess.run(
['ping', '-c', , , , ip],
capture_output=,
timeout=
)
:
() -> :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout .timeout)
result = sock.connect_ex((ip, port))
sock.close()
result ==
() -> :
:
hostname = socket.gethostbyaddr(ip)[]
hostname
:
() -> [HostInfo]:
info = .calculator.calculate(cidr)
hosts = []
i (, info.num_addresses - ):
ip = (info.network_address + i)
.ping_host(ip):
host_info = HostInfo(
ip=ip,
hostname=.get_hostname(ip),
status=,
last_seen=datetime.now()
)
ports:
host_info.open_ports = .scan_ports(ip, ports)
hosts.append(host_info)
hosts
() -> []:
open_ports = []
concurrent.futures.ThreadPoolExecutor(max_workers=) executor:
futures = {
executor.submit(.scan_port, ip, port): port
port ports
}
future concurrent.futures.as_completed(futures):
port = futures[future]
:
future.result():
open_ports.append(port)
:
(open_ports)
() -> [, ]:
common_ports = {
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
:
}
open_ports = .scan_ports(ip, (common_ports.keys()))
{port: common_ports[port] port open_ports}
() -> :
report = []
report.append( * )
report.append()
report.append( * )
report.append()
report.append()
report.append()
online_hosts = [h h hosts h.status == ]
report.append()
host (online_hosts, key= x: socket.inet_aton(x.ip)):
report.append( * )
report.append()
report.append()
report.append()
host.open_ports:
report.append()
port host.open_ports:
report.append()
.join(report)
__name__ == :
scanner = NetworkScanner()
()
hosts = scanner.scan_network(, [, , , ])
report = scanner.generate_report(hosts)
(report)
package main
import (
"fmt"
"os/exec"
"strings"
"net"
"bytes"
"encoding/csv"
)
type Route struct {
Destination string
Gateway string
Genmask string
Flags string
Metric int
Ref int
Use int
Interface string
}
type RoutingTable struct {
routes []Route
}
func (rt *RoutingTable) Parse() error {
output, err := exec.Command("route", "-n").Output()
if err != nil {
return fmt.Errorf("failed to get routing table: %w", err)
}
lines := strings.Split(string(output), "\n")
rt.routes = make([]Route, 0)
for _, line := range lines[1:] {
if strings.TrimSpace(line) == "" || strings.HasPrefix(line, "Kernel") {
continue
}
fields := strings.Fields(line)
if len(fields) < 8 {
continue
}
route := Route{
Destination: fields[0],
Gateway: fields[1],
Genmask: fields[],
Flags: fields[],
}
fmt.Sscanf(fields[], , &route.Metric)
fmt.Sscanf(fields[], , &route.Ref)
fmt.Sscanf(fields[], , &route.Use)
route.Interface = fields[]
rt.routes = (rt.routes, route)
}
}
GetRouteForDestination(destination ) *Route {
destIP := net.ParseIP(destination)
bestMatch *Route
bestPrefixLen
i := rt.routes {
route := &rt.routes[i]
routeNet := net.ParseIP(route.Destination)
routeMask := net.ParseIP(route.Genmask)
prefixLen :=
j := routeIP := routeIP {
maskByte := routeMask[j]
k := ; k < ; k++ {
maskByte&(<<(-k)) != {
prefixLen++
}
}
}
match :=
i := destIP {
(destIP[i] & routeMask[i]) != (routeNet[i] & routeMask[i]) {
match =
}
}
match && prefixLen > bestPrefixLen {
bestPrefixLen = prefixLen
bestMatch = route
}
}
bestMatch
}
AddRoute(destination, gateway, netmask, , metric ) {
cmd := exec.Command(, , , destination, , netmask, , gateway, , fmt.Sprintf(, metric), )
cmd.Run()
}
DeleteRoute(destination, netmask ) {
cmd := exec.Command(, , , destination, , netmask)
cmd.Run()
}
ExportToCSV(filename ) {
file, err := os.Create(filename)
err != {
err
}
file.Close()
writer := csv.NewWriter(file)
writer.Flush()
headers := []{, , , , , , , }
writer.Write(headers)
_, route := rt.routes {
row := []{
route.Destination,
route.Gateway,
route.Genmask,
route.Flags,
fmt.Sprintf(, route.Metric),
fmt.Sprintf(, route.Ref),
fmt.Sprintf(, route.Use),
route.Interface,
}
writer.Write(row)
}
}
(, , ) {
_, ipNet, err := net.ParseCIDR(cidr)
err != {
, , err
}
networkAddress := ipNet.IP.String()
broadcast := (net.IP, (ipNet.IP))
i := ipNet.IP {
broadcast[i] = ipNet.IP[i] | ^ipNet.Mask[i]
}
broadcastAddress := broadcast.String()
networkAddress, broadcastAddress,
}
{
rt := &RoutingTable{}
err := rt.Parse(); err != {
fmt.Printf(, err)
}
fmt.Println()
fmt.Println()
_, route := rt.routes {
fmt.Printf(,
route.Destination, route.Gateway, route.Genmask, route.Interface)
}
route := rt.GetRouteForDestination()
route != {
fmt.Printf(,
route.Gateway, route.Interface)
}
}