Skip to main content
Glama
mcpcap

mcpacket

by mcpcap

analyze_dhcp_packets

Parse PCAP files to extract and analyze DHCP packets, revealing device addresses, lease durations, and server configurations for network troubleshooting.

Instructions

Analyze DHCP packets from a PCAP file and return comprehensive analysis results.

FILE UPLOAD LIMITATION: This MCP tool cannot process files uploaded through Claude's web interface. Files must be accessible via URL or local file path.

SUPPORTED INPUT FORMATS:

  • Remote files: "https://example.com/capture.pcap"

  • Local files: "/absolute/path/to/capture.pcap"

UNSUPPORTED:

  • Files uploaded through Claude's file upload feature

  • Base64 file content

  • Relative file paths

Args: pcap_file: HTTP URL or absolute local file path to PCAP file

Returns: A structured dictionary containing DHCP packet analysis results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pcap_fileYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main tool handler for analyze_dhcp_packets. This is the public method registered as an MCP tool. It delegates to self.analyze_packets(pcap_file) from the base class, which handles local and remote PCAP files.
    def analyze_dhcp_packets(self, pcap_file: str) -> dict[str, Any]:
        """
        Analyze DHCP packets from a PCAP file and return comprehensive analysis results.
    
        FILE UPLOAD LIMITATION: This MCP tool cannot process files uploaded through
        Claude's web interface. Files must be accessible via URL or local file path.
    
        SUPPORTED INPUT FORMATS:
        - Remote files: "https://example.com/capture.pcap"
        - Local files: "/absolute/path/to/capture.pcap"
    
        UNSUPPORTED:
        - Files uploaded through Claude's file upload feature
        - Base64 file content
        - Relative file paths
    
        Args:
            pcap_file: HTTP URL or absolute local file path to PCAP file
    
        Returns:
            A structured dictionary containing DHCP packet analysis results
        """
        return self.analyze_packets(pcap_file)
  • The actual protocol-specific analysis implementation (_analyze_protocol_file). Reads PCAP with scapy, filters BOOTP/DHCP packets, analyzes each packet, generates statistics, and applies max_packets limits.
    def _analyze_protocol_file(self, pcap_file: str) -> dict[str, Any]:
        """Perform the actual DHCP packet analysis on a local PCAP file."""
        try:
            packets = rdpcap(pcap_file)
            dhcp_packets = [pkt for pkt in packets if pkt.haslayer(BOOTP)]
    
            if not dhcp_packets:
                return {
                    "file": pcap_file,
                    "total_packets": len(packets),
                    "dhcp_packets_found": 0,
                    "message": "No DHCP packets found in this capture",
                }
    
            # Apply max_packets limit if specified
            packets_to_analyze = dhcp_packets
            limited = False
            if self.config.max_packets and len(dhcp_packets) > self.config.max_packets:
                packets_to_analyze = dhcp_packets[: self.config.max_packets]
                limited = True
    
            packet_details = []
            for i, pkt in enumerate(packets_to_analyze, 1):
                packet_info = self._analyze_dhcp_packet(pkt, i)
                packet_details.append(packet_info)
    
            # Generate statistics
            stats = self._generate_statistics(packet_details)
    
            result = {
                "file": pcap_file,
                "total_packets": len(packets),
                "dhcp_packets_found": len(dhcp_packets),
                "dhcp_packets_analyzed": len(packet_details),
                "statistics": stats,
                "packets": packet_details,
            }
    
            # Add information about packet limiting
            if limited:
                result["note"] = (
                    f"Analysis limited to first {self.config.max_packets} DHCP packets due to --max-packets setting"
                )
    
            return result
    
        except Exception as e:
            return {
                "error": f"Error reading PCAP file '{pcap_file}': {str(e)}",
                "file": pcap_file,
            }
  • Per-packet DHCP analysis (_analyze_dhcp_packet). Extracts IP/UDP info, BOOTP fields (op, xid, IPs, MAC), and parses DHCP options (message type, lease time, server ID, etc.).
    def _analyze_dhcp_packet(self, packet, packet_num: int) -> dict[str, Any]:
        """Analyze a single DHCP packet and extract relevant information."""
        info = {
            "packet_number": packet_num,
            "timestamp": packet.time,
        }
    
        # Basic IP information
        if packet.haslayer(IP):
            ip_layer = packet[IP]
            info.update(
                {
                    "src_ip": ip_layer.src,
                    "dst_ip": ip_layer.dst,
                }
            )
    
        # UDP information
        if packet.haslayer(UDP):
            udp_layer = packet[UDP]
            info.update(
                {
                    "src_port": udp_layer.sport,
                    "dst_port": udp_layer.dport,
                }
            )
    
        # BOOTP/DHCP information
        if packet.haslayer(BOOTP):
            bootp_layer = packet[BOOTP]
            info.update(
                {
                    "op": "Request" if bootp_layer.op == 1 else "Reply",
                    "transaction_id": f"0x{bootp_layer.xid:08x}",
                    "client_ip": str(bootp_layer.ciaddr),
                    "your_ip": str(bootp_layer.yiaddr),
                    "server_ip": str(bootp_layer.siaddr),
                    "relay_ip": str(bootp_layer.giaddr),
                    "client_mac": bootp_layer.chaddr[:6].hex(":"),
                }
            )
    
        # DHCP options analysis
        if packet.haslayer(DHCP):
            dhcp_layer = packet[DHCP]
            dhcp_info = self._parse_dhcp_options(dhcp_layer.options)
            info.update(dhcp_info)
    
        return info
  • DHCP options parser (_parse_dhcp_options). Maps message-type codes to names (DISCOVER, OFFER, etc.) and extracts key options like lease_time, server_id, subnet_mask, router, DNS, etc.
    def _parse_dhcp_options(self, options) -> dict[str, Any]:
        """Parse DHCP options and return structured information."""
        dhcp_info = {"options": {}}
    
        # DHCP message type mappings
        message_types = {
            1: "DISCOVER",
            2: "OFFER",
            3: "REQUEST",
            4: "DECLINE",
            5: "ACK",
            6: "NAK",
            7: "RELEASE",
            8: "INFORM",
        }
    
        for opt in options:
            if isinstance(opt, tuple) and len(opt) == 2:
                key, value = opt
    
                if key == "message-type":
                    dhcp_info["message_type"] = message_types.get(
                        value, f"Unknown({value})"
                    )
                    dhcp_info["message_type_code"] = value
                elif key == "lease_time":
                    dhcp_info["lease_time"] = value
                    dhcp_info["options"]["lease_time"] = f"{value} seconds"
                elif key == "renewal_time":
                    dhcp_info["renewal_time"] = value
                    dhcp_info["options"]["renewal_time"] = f"{value} seconds"
                elif key == "rebinding_time":
                    dhcp_info["rebinding_time"] = value
                    dhcp_info["options"]["rebinding_time"] = f"{value} seconds"
                elif key == "server_id":
                    dhcp_info["server_id"] = str(value)
                elif key == "subnet_mask":
                    dhcp_info["options"]["subnet_mask"] = str(value)
                elif key == "router":
                    dhcp_info["options"]["router"] = str(value)
                elif key == "name_server":
                    dhcp_info["options"]["dns_servers"] = str(value)
                elif key == "requested_addr":
                    dhcp_info["requested_ip"] = str(value)
                elif key == "client_id":
                    if isinstance(value, bytes):
                        dhcp_info["client_id"] = value.hex(":")
                    else:
                        dhcp_info["client_id"] = str(value)
                elif key == "param_req_list":
                    dhcp_info["options"]["parameter_request_list"] = list(value)
                else:
                    # Store other options as strings
                    dhcp_info["options"][key] = str(value)
    
        return dhcp_info
  • Tool registration in the MCP server. Located in server.py line 56: self.mcp.tool(module.analyze_dhcp_packets) registers the DHCP packet analysis tool when the 'dhcp' module is loaded.
    self.mcp.tool(module.analyze_dhcp_packets)
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses the file upload limitation and return type, but does not mention other behavioral traits like read-only nature, size limits, or error handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear sections (purpose, limitation, formats, args, returns). Slightly redundant in repeating file upload limitation, but front-loaded with purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with an output schema, the description covers input constraints thoroughly. Lacks details on analysis results, but output schema likely provides that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 0% coverage; the description fully explains the pcap_file parameter's meaning, format requirements (URL or absolute path), and unsupported formats, adding substantial value beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool analyzes DHCP packets from a PCAP file, with a specific verb and resource. It distinguishes from sibling tools that analyze other packet types (DNS, ICMP, SIP, etc.).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly lists supported input formats (URL or absolute local path) and unsupported formats (Claude file upload, base64, relative paths), providing clear when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mcpcap/mcpacket'

If you have feedback or need assistance with the MCP directory API, please join our Discord server