analyze_dhcp_packets
Analyze DHCP packets from PCAP files to identify network configuration issues and security vulnerabilities. Supports local file paths or remote URLs for packet capture analysis.
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
| Name | Required | Description | Default |
|---|---|---|---|
| pcap_file | Yes |
Implementation Reference
- src/mcpcap/modules/dhcp.py:19-41 (handler)Main handler function for the 'analyze_dhcp_packets' tool. Delegates to analyze_packets after validation.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)
- src/mcpcap/core/server.py:52-53 (registration)Registers the analyze_dhcp_packets tool with the MCP server using FastMCP.elif module_name == "dhcp": self.mcp.tool(module.analyze_dhcp_packets)
- src/mcpcap/modules/dhcp.py:43-94 (helper)Core helper function that performs the actual PCAP reading, filtering DHCP packets, analyzing them, and generating statistics.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, }
- src/mcpcap/modules/dhcp.py:95-143 (helper)Helper function to analyze individual DHCP packets, extracting IP, UDP, BOOTP, and DHCP option information.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
- src/mcpcap/modules/dhcp.py:145-200 (helper)Helper function to parse and structure DHCP options from packets.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