mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-26 18:22:23 +02:00
feat: add search_fields action to PacketAnalysisTool for real-time field lookup
This commit is contained in:
parent
32c3b4cd35
commit
2a34d0ef58
@ -89,8 +89,63 @@ class PacketAnalysisTool(BaseTool):
|
|||||||
total packets scanned, it can hide results when used
|
total packets scanned, it can hide results when used
|
||||||
with -Y. Prefer piping to head -10 or rely on -Y
|
with -Y. Prefer piping to head -10 or rely on -Y
|
||||||
alone instead.
|
alone instead.
|
||||||
|
|
||||||
|
Instead of analysis, you can also search tshark's field registry directly:
|
||||||
|
{"action": "search_fields", "query": "ospf"}
|
||||||
|
This returns matching field names, types, and descriptions from tshark.
|
||||||
|
Use this to find correct field names before constructing tshark_args.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _search_fields(cls, query: str) -> str:
|
||||||
|
"""
|
||||||
|
Search tshark field registry via `tshark -G fields | grep -i <query>`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
query: Search term
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
JSON string with matching fields.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
grep = subprocess.Popen(
|
||||||
|
["grep", "-i", query, "-"],
|
||||||
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.DEVNULL, text=True,
|
||||||
|
)
|
||||||
|
tshark = subprocess.Popen(
|
||||||
|
["tshark", "-G", "fields"],
|
||||||
|
stdout=grep.stdin, stderr=subprocess.DEVNULL, text=True,
|
||||||
|
)
|
||||||
|
stdout, _ = grep.communicate(timeout=30)
|
||||||
|
tshark.wait(timeout=30)
|
||||||
|
except Exception as e:
|
||||||
|
return json.dumps({"error": f"tshark query failed: {e}"})
|
||||||
|
|
||||||
|
results = []
|
||||||
|
seen = set()
|
||||||
|
for line in stdout.splitlines():
|
||||||
|
parts = line.split("\t")
|
||||||
|
if len(parts) >= 3 and parts[0] == "F":
|
||||||
|
name = parts[2]
|
||||||
|
if name not in seen:
|
||||||
|
seen.add(name)
|
||||||
|
results.append({
|
||||||
|
"field": name,
|
||||||
|
"type": parts[3] if len(parts) > 3 else "",
|
||||||
|
"protocol": parts[4] if len(parts) > 4 else "",
|
||||||
|
"description": parts[7] if len(parts) > 7 else "",
|
||||||
|
})
|
||||||
|
if len(results) >= 40:
|
||||||
|
break
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"query": query,
|
||||||
|
"count": len(results),
|
||||||
|
"fields": results,
|
||||||
|
"hint": "Use the 'field' values in tshark_args with -e",
|
||||||
|
}, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _load_valid_tshark_fields(cls) -> set:
|
def _load_valid_tshark_fields(cls) -> set:
|
||||||
"""
|
"""
|
||||||
@ -161,7 +216,7 @@ class PacketAnalysisTool(BaseTool):
|
|||||||
if invalid_fields:
|
if invalid_fields:
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
"error": f"Invalid tshark field names: {', '.join(invalid_fields)}",
|
"error": f"Invalid tshark field names: {', '.join(invalid_fields)}",
|
||||||
"hint": "Use packet_analysis_skills tool to look up valid field names for the protocol",
|
"hint": 'Use {"action": "search_fields", "query": "<protocol>"} to look up valid field names',
|
||||||
"invalid_fields": invalid_fields,
|
"invalid_fields": invalid_fields,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -169,9 +224,11 @@ class PacketAnalysisTool(BaseTool):
|
|||||||
|
|
||||||
def _run(
|
def _run(
|
||||||
self,
|
self,
|
||||||
project_id: str,
|
project_id: str | None = None,
|
||||||
link_id: str,
|
link_id: str | None = None,
|
||||||
tshark_args: str,
|
tshark_args: str | None = None,
|
||||||
|
action: str | None = None,
|
||||||
|
query: str | None = None,
|
||||||
run_manager: CallbackManagerForToolRun | None = None,
|
run_manager: CallbackManagerForToolRun | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
@ -181,11 +238,17 @@ class PacketAnalysisTool(BaseTool):
|
|||||||
project_id: UUID of the GNS3 project
|
project_id: UUID of the GNS3 project
|
||||||
link_id: UUID of the link to analyze
|
link_id: UUID of the link to analyze
|
||||||
tshark_args: tshark command arguments (after '-r <pcap>')
|
tshark_args: tshark command arguments (after '-r <pcap>')
|
||||||
|
action: "search_fields" to query tshark field registry instead
|
||||||
|
query: Search term for action="search_fields" (e.g., "ospf")
|
||||||
run_manager: LangChain run manager (unused)
|
run_manager: LangChain run manager (unused)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: tshark output
|
str: tshark output
|
||||||
"""
|
"""
|
||||||
|
# Field search mode: query tshark directly without capture
|
||||||
|
if action == "search_fields":
|
||||||
|
return self._search_fields(query or "")
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"PacketAnalysisTool invoked: project_id={project_id}, "
|
f"PacketAnalysisTool invoked: project_id={project_id}, "
|
||||||
f"link_id={link_id}, tshark_args={tshark_args}"
|
f"link_id={link_id}, tshark_args={tshark_args}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user