Skip to content

Commit 234f493

Browse files
committed
fix(agent): Win7 default IPv4 adapter resolution and NetConnectionID mapping
1 parent 5fd45e9 commit 234f493

2 files changed

Lines changed: 99 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ python -m agent.main --config configs\agent.json
160160

161161
1. WMI `DefaultIPGateway`
162162
2. 若本机存在 `Get-NetRoute` cmdlet:PowerShell 默认路由,再 `Get-NetIPConfiguration`(避免仅按系统版本误判,Win7 兼容模式误报为 6.2+ 时不会误调)
163-
3. WMI `Win32_IP4RouteTable`(默认路由的 `InterfaceIndex` → 网卡名,Win7 不依赖 `IPAddress` 字符串反查
163+
3. WMI `Win32_IP4RouteTable`(默认路由的 `InterfaceIndex` 先对齐 `NICConfiguration`,再用其 `Index``NetworkAdapter``NetConnectionID`Win7 上路由 ifIndex 常与 `NetworkAdapter.InterfaceIndex` 不一致
164164
4. `route print -4` + WMI 反查
165165

166166
再用 `netsh interface ipv4` 应用配置:

agent/network_config.py

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,54 @@ def _wmic_multivalue_tokens(s: str) -> List[str]:
103103
return out
104104

105105

106+
def _wmic_netconnectionid_for_adapter_index(adapter_index: int) -> Tuple[Optional[str], str]:
107+
"""Win32_NetworkAdapter.Index(与 NICConfiguration.Index 一致)→ NetConnectionID。"""
108+
try:
109+
p = subprocess.run(
110+
[
111+
"wmic",
112+
"path",
113+
"Win32_NetworkAdapter",
114+
"where",
115+
"Index=%d" % adapter_index,
116+
"get",
117+
"NetConnectionID,NetEnabled",
118+
"/format:list",
119+
],
120+
capture_output=True,
121+
text=True,
122+
creationflags=_subprocess_flags(),
123+
)
124+
except OSError as e:
125+
return None, "wmic adapter Index=%s: %s" % (adapter_index, e)
126+
if p.returncode != 0:
127+
return None, (p.stderr or p.stdout or "wmic adapter failed").strip()[:300]
128+
enabled_name: Optional[str] = None
129+
any_name: Optional[str] = None
130+
for row in _parse_wmic_list(p.stdout or ""):
131+
nid = row.get("netconnectionid", "").strip()
132+
if not nid:
133+
continue
134+
net = row.get("netenabled", "").strip().lower() in ("true", "1")
135+
if net:
136+
enabled_name = nid
137+
break
138+
if any_name is None:
139+
any_name = nid
140+
if enabled_name:
141+
return enabled_name, "adapter.Index=%d" % adapter_index
142+
if any_name:
143+
return any_name, "adapter.Index=%d (NetEnabled=false)" % adapter_index
144+
return None, "no NetConnectionID for adapter.Index=%d" % adapter_index
145+
146+
106147
def _wmic_nic_name_for_index(idx: int) -> Tuple[Optional[str], str]:
148+
"""
149+
将「路由表 / NICConfiguration 使用的 InterfaceIndex」解析为 netsh 用的连接名(NetConnectionID)。
150+
151+
Win7 上 Win32_NetworkAdapter.InterfaceIndex 常与路由表 ifIndex 不一致,故在直接匹配失败后,
152+
用 Win32_NetworkAdapterConfiguration.InterfaceIndex → Index → Win32_NetworkAdapter。
153+
"""
107154
try:
108155
p2 = subprocess.run(
109156
[
@@ -130,8 +177,57 @@ def _wmic_nic_name_for_index(idx: int) -> Tuple[Optional[str], str]:
130177
continue
131178
nid = row.get("netconnectionid", "").strip()
132179
if nid:
133-
return nid, "wmic"
134-
return None, "NetConnectionID not found for index %s" % idx
180+
return nid, "wmic NetworkAdapter.InterfaceIndex"
181+
182+
try:
183+
pc = subprocess.run(
184+
[
185+
"wmic",
186+
"path",
187+
"Win32_NetworkAdapterConfiguration",
188+
"where",
189+
"InterfaceIndex=%d" % idx,
190+
"get",
191+
"Index,IPEnabled",
192+
"/format:list",
193+
],
194+
capture_output=True,
195+
text=True,
196+
creationflags=_subprocess_flags(),
197+
timeout=30,
198+
)
199+
except OSError as e:
200+
return None, "NetConnectionID not found for ifIndex %s (direct); NICConfig: %s" % (idx, e)
201+
if pc.returncode != 0:
202+
return None, "NetConnectionID not found for ifIndex %s (direct); NICConfig query: %s" % (
203+
idx,
204+
(pc.stderr or pc.stdout or "").strip()[:300],
205+
)
206+
cfg_rows = list(_parse_wmic_list(pc.stdout or ""))
207+
adapter_indices: List[int] = []
208+
for row in cfg_rows:
209+
ie = row.get("ipenabled", "").strip().lower()
210+
if ie not in ("true", "1"):
211+
continue
212+
m = re.search(r"\d+", row.get("index", ""))
213+
if m:
214+
adapter_indices.append(int(m.group()))
215+
if not adapter_indices:
216+
for row in cfg_rows:
217+
m = re.search(r"\d+", row.get("index", ""))
218+
if m:
219+
adapter_indices.append(int(m.group()))
220+
seen = set()
221+
ordered: List[int] = []
222+
for i in adapter_indices:
223+
if i not in seen:
224+
seen.add(i)
225+
ordered.append(i)
226+
for ai in ordered:
227+
name, why = _wmic_netconnectionid_for_adapter_index(ai)
228+
if name:
229+
return name, "wmic NICConfig.InterfaceIndex=%d → %s" % (idx, why)
230+
return None, "NetConnectionID not found for ifIndex %s (direct + NICConfig.Index fallback)" % idx
135231

136232

137233
def _interface_from_wmi_default_gateway() -> Tuple[Optional[str], str]:

0 commit comments

Comments
 (0)