Skip to main content
Glama
danohn

mcpcap

by danohn

analyze_dns_packets

Analyze DNS traffic in PCAP files to identify queries, responses, and patterns. Upload files via URL or local path for structured DNS protocol analysis.

Instructions

Analyze DNS 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 DNS packet analysis results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pcap_fileYes

Implementation Reference

  • Main handler function for the 'analyze_dns_packets' MCP tool. Includes input/output schema in docstring and delegates to base analyze_packets method.
    def analyze_dns_packets(self, pcap_file: str) -> dict[str, Any]:
        """
        Analyze DNS 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 DNS packet analysis results
        """
        return self.analyze_packets(pcap_file)
  • Registration of the analyze_dns_packets tool in the MCP server at line 51: self.mcp.tool(module.analyze_dns_packets). Part of the _register_tools method.
    def _register_tools(self) -> None:
        """Register all available tools with the MCP server."""
        # Register tools for each loaded module
        for module_name, module in self.modules.items():
            if module_name == "dns":
                self.mcp.tool(module.analyze_dns_packets)
            elif module_name == "dhcp":
                self.mcp.tool(module.analyze_dhcp_packets)
            elif module_name == "icmp":
                self.mcp.tool(module.analyze_icmp_packets)
            elif module_name == "capinfos":
                self.mcp.tool(module.analyze_capinfos)
            elif module_name == "tcp":
                self.mcp.tool(module.analyze_tcp_connections)
                self.mcp.tool(module.analyze_tcp_anomalies)
                self.mcp.tool(module.analyze_tcp_retransmissions)
                self.mcp.tool(module.analyze_traffic_flow)
  • Core analysis logic for DNS packets: loads PCAP, filters DNS packets, analyzes them, generates stats.
    def _analyze_protocol_file(self, pcap_file: str) -> dict[str, Any]:
        """Perform the actual DNS packet analysis on a local PCAP file."""
        try:
            packets = rdpcap(pcap_file)
            dns_packets = [pkt for pkt in packets if pkt.haslayer(DNS)]
    
            if not dns_packets:
                return {
                    "file": pcap_file,
                    "total_packets": len(packets),
                    "dns_packets_found": 0,
                    "message": "No DNS packets found in this capture",
                }
    
            # Apply max_packets limit if specified
            packets_to_analyze = dns_packets
            limited = False
            if self.config.max_packets and len(dns_packets) > self.config.max_packets:
                packets_to_analyze = dns_packets[: self.config.max_packets]
                limited = True
    
            packet_details = []
            for i, pkt in enumerate(packets_to_analyze, 1):
                packet_info = self._analyze_dns_packet(pkt, i)
                packet_details.append(packet_info)
    
            # Generate statistics
            stats = self._generate_statistics(packet_details)
    
            result = {
                "file": pcap_file,
                "analysis_timestamp": datetime.now().isoformat(),
                "total_packets_in_file": len(packets),
                "dns_packets_found": len(dns_packets),
                "dns_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} DNS 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,
            }
  • Base class method that handles local and remote PCAP file processing, dispatching to _analyze_protocol_file.
    def analyze_packets(self, pcap_file: str) -> dict[str, Any]:
        """Analyze packets from a PCAP file (local or remote).
    
        Args:
            pcap_file: Path to local PCAP file or HTTP URL to remote PCAP file
    
        Returns:
            A structured dictionary containing packet analysis results
        """
        # Check if this is a remote URL or local file
        if pcap_file.startswith(("http://", "https://")):
            return self._handle_remote_analysis(pcap_file)
        else:
            return self._handle_local_analysis(pcap_file)
    
    def _handle_remote_analysis(self, pcap_url: str) -> dict[str, Any]:
        """Handle remote PCAP file analysis."""
        try:
            # Download remote file to temporary location
            with tempfile.NamedTemporaryFile(suffix=".pcap", delete=False) as tmp_file:
                temp_path = tmp_file.name
    
            local_path = self._download_pcap_file(pcap_url, temp_path)
            result = self._analyze_protocol_file(local_path)
    
            # Clean up temporary file
            try:
                os.unlink(local_path)
            except OSError:
                pass  # Ignore cleanup errors
    
            return result
    
        except Exception as e:
            return {
                "error": f"Failed to download PCAP file '{pcap_url}': {str(e)}",
                "pcap_url": pcap_url,
            }
    
    def _handle_local_analysis(self, pcap_file: str) -> dict[str, Any]:
        """Handle local PCAP file analysis."""
        # Validate file exists
        if not os.path.exists(pcap_file):
            return {
                "error": f"PCAP file not found: {pcap_file}",
                "pcap_file": pcap_file,
            }
    
        # Validate file extension
        if not pcap_file.lower().endswith((".pcap", ".pcapng", ".cap")):
            return {
                "error": f"File '{pcap_file}' is not a supported PCAP file (.pcap/.pcapng/.cap)",
                "pcap_file": pcap_file,
            }
    
        try:
            return self._analyze_protocol_file(pcap_file)
        except Exception as e:
            return {
                "error": f"Failed to analyze PCAP file '{pcap_file}': {str(e)}",
                "pcap_file": pcap_file,
            }

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/danohn/mcpcap'

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