使用go编译upnp程序 在armv7 上运行
1 go 编译环境准备
sudo apt update
sudo apt install -y golang
2 下载upnp 代码库
非常适合学习:网络协议、XML/SOAP、并发、命令行工具设计
场景 命令示例
查看可用设备 upnpctl -v list
开放 80 端口(HTTP) upnpctl add 80
开放 22 端口(SSH)并设置描述 upnpctl add --desc "SSH Access" 22
开放 8080→8080(外部=内部) upnpctl add 8080
开放 8080→80(外部=8080,内部=80) upnpctl add 8080:80
删除 80 端口映射 upnpctl rem 80
指定设备和协议 upnpctl add --id a1b2c --type udp 53
3 环境编译时对包地址进行修改
点击查看代码
package main
import (
"crypto/sha1"
"encoding/hex"
"flag"
"fmt"
"net"
"os"
"strconv"
"strings"
"./upnp" //改成本地地址
)
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -o upnpctl main.go
在做不交叉编译时,开始目标程序写成了upnpc 在测试命令的时候 无法执行upnpctl ,经AI提示,需要将目标程序名改成upnpctl
5 UPnP 工作流程图(简化)
[用户执行] upnpctl add 3000
↓
[发现设备] SSDP M-SEARCH → 接收响应 → 解析 XML → 得到 IGD 列表
↓
[选择设备] 根据 --id 或唯一设备 → 获取 IGD 实例
↓
[构造 SOAP]
- 外部端口: 3000
- 内部端口: 3000
- 内部IP: 192.168.1.100
- 协议: TCP
- 描述: upnpctl v0.0.0
↓
[发送请求] POST 到 http://192.168.1.1:5000/ctl/IPConn
↓
[路由器响应] 200 OK → 端口映射成功!
↓
[反馈用户] "Done"
将可执行程序放置在/tmp/mnt中无法执行的原因:
/tmp/mnt # ./upnpctl -v list
/bin/sh: ./upnpctl: Permission denied
在嵌入式 Linux 中,/tmp/mnt 无法执行而 /etc_rw 可以,核心原因是文件系统挂载属性限制或权限配置差异,其中挂载时的 noexec 选项是最常见的罪魁祸首。以下是分步骤的原因分析与排查解决方案:
一、核心原因(按概率从高到低)
- /tmp/mnt 所在文件系统被挂载为 noexec(最常见)
嵌入式 Linux 中,/tmp 通常是临时文件系统(tmpfs),或 /mnt 挂载的外部存储(如 SD 卡、U 盘)被显式添加了 noexec 选项 —— 该选项会禁止任何程序在该目录下执行,即使文件本身有执行权限,也会报 Permission denied。
对比:/etc_rw 通常是系统分区(如 jffs2、ubifs)挂载时带 exec 权限,因此允许执行。 - 文件本身的执行权限未正确设置
虽然可能性低于挂载选项,但需确认:
/tmp/mnt/upnpctl 是否缺少可执行权限(如 -rw-r--r-- 而非 -rwxr-xr-x);
若文件是从 Windows 复制而来,是否被设置了不可执行的属性(如通过 cp 复制时未保留权限)。 - 文件系统类型不支持执行(如 vfat/ntfs)
若 /tmp/mnt 挂载的是 vfat(U 盘 / SD 卡) 或 ntfs 等 Windows 文件系统,这些文件系统本身不支持 Linux 的执行权限位(x 位),即使手动 chmod +x 也无效,会默认禁止执行。
对比:/etc_rw 是 Linux 原生文件系统(jffs2、ubifs、ext4),支持权限位,因此可执行。

浙公网安备 33010602011771号