PowerShell发送LLC发现数据包遇Socket错误,请求问题排查
问题:PowerShell发送LLC数据包报错原因分析
用户无相关经验,编写了一段PowerShell脚本尝试发送LLC发现数据包,脚本内容如下:
# Ensure this script is run as Administrator for raw socket permissions param ( [string]$destMac = "01-19-a7-52-76-96" # Destination MAC address ) # Define LLC Frame Structure $llcHeader = @(0xAA, 0xAA, 0x03) # DSAP, SSAP, Control field # Define Custom LLC Payload $llcPayload = @( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) # Assemble the full LLC frame by appending the payload after the LLC header $llcFrame = $llcHeader + $llcPayload # Convert MAC address to byte array function Convert-MacToBytes { param ([string]$mac) return $mac -split '-' | ForEach-Object { [Convert]::ToByte($_, 16) } } $destMacBytes = Convert-MacToBytes -mac $destMac # Create raw socket and send the frame $socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork, [System.Net.Sockets.SocketType]::Raw, [System.Net.Sockets.ProtocolType]::Raw) $socket.SetSocketOption([System.Net.Sockets.SocketOptionLevel]::Socket, [System.Net.Sockets.SocketOptionName]::Broadcast, $true) # Create byte array for the full Ethernet frame $ethernetFrame = $destMacBytes + $llcFrame # Send the packet try { $socket.Send($ethernetFrame) Write-Output "LLC packet sent successfully." } catch { Write-Output "Failed to send LLC packet: $_" } finally { $socket.Close() }
执行脚本时输出错误信息:
发送LLC数据包失败:调用“Send”方法时传入1个参数出现异常:“由于套接字未连接,且(在数据报套接字上使用sendto调用发送时)未提供地址,因此不允许发送或接收数据的请求”
问题原因及修复方案
核心问题
脚本在套接字配置和发送逻辑上存在3个关键错误,导致无法正确发送二层LLC帧:
错误的地址族与协议类型
你使用了InterNetwork(IPv4)地址族的Raw套接字,这是三层套接字,无法直接构造并发送二层以太网帧。要发送包含LLC的二层帧,必须使用LinkLayer地址族,并指定Ethernet协议类型。未绑定网络接口
Raw套接字发送二层数据前,必须绑定到本地的某个网络适配器,否则系统无法确定从哪个网卡发送数据包。错误的发送方法
未连接的套接字发送数据时,必须使用SendTo方法并指定目标链路层地址,不能直接调用Send方法。
修复后的脚本示例
# Run as Administrator param ( [string]$destMac = "01-19-a7-52-76-96", [int]$interfaceIndex = 3 # 替换为你的网络适配器索引(运行Get-NetAdapter查看) ) # Convert MAC to byte array function Convert-MacToBytes { param ([string]$mac) return $mac -split '-' | ForEach-Object { [Convert]::ToByte($_, 16) } } $destMacBytes = Convert-MacToBytes -mac $destMac # 构建完整以太网帧:目标MAC(6) + 源MAC(6) + EtherType(2: 0x0003对应LLC) + LLC帧 # 注意:替换源MAC为你的网卡实际MAC地址 $srcMacBytes = Convert-MacToBytes -mac "AA-BB-CC-DD-EE-FF" # 你的网卡MAC $etherType = [byte[]]@(0x00, 0x03) # LLC/SNAP对应的EtherType $llcHeader = @(0xAA, 0xAA, 0x03) $llcPayload = @(0x00 * 26) $llcFrame = $llcHeader + $llcPayload $ethernetFrame = $destMacBytes + $srcMacBytes + $etherType + $llcFrame # 创建链路层Raw套接字 $socket = New-Object System.Net.Sockets.Socket( [System.Net.Sockets.AddressFamily]::LinkLayer, [System.Net.Sockets.SocketType]::Raw, [System.Net.Sockets.ProtocolType]::Ethernet ) # 绑定到指定网络接口 $sockAddr = New-Object System.Net.Sockets.SocketAddress([System.Net.Sockets.AddressFamily]::LinkLayer, 16) $sockAddr[2] = [byte]($interfaceIndex -band 0xFF) $sockAddr[3] = [byte](($interfaceIndex -shr 8) -band 0xFF) $socket.Bind($sockAddr) # 使用SendTo发送帧(以太网帧的目标地址已包含在帧内,此处SocketAddress仅为格式要求) try { $null = $socket.SendTo($ethernetFrame, [System.Net.Sockets.SocketFlags]::None, $sockAddr) Write-Output "LLC packet sent successfully." } catch { Write-Output "Failed to send LLC packet: $_" } finally { $socket.Close() }
额外注意事项
- 运行
Get-NetAdapter命令获取你的网络适配器索引,替换脚本中的$interfaceIndex。 - 替换
$srcMacBytes为你的网卡实际MAC地址,否则以太网帧格式不合法。 - 必须以管理员权限运行脚本,否则无法创建Raw套接字。
内容的提问来源于stack exchange,提问作者user2956477
相关产品推荐
相关产品推荐

