From a08fc163e72aa57e3c9343f9bcfad161104eb842 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Thu, 21 Sep 2023 19:48:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BD=91=E5=85=83=E5=8F=91=E9=80=81?= =?UTF-8?q?=E6=89=A7=E8=A1=8CUPF=20pcap=E6=8A=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/trace/tcpdump.go | 166 ++++++++++++++++++++++++++++++++++++++ lib/routes/routes.go | 3 + 2 files changed, 169 insertions(+) diff --git a/features/trace/tcpdump.go b/features/trace/tcpdump.go index 3ab91274..e3d4c4f4 100644 --- a/features/trace/tcpdump.go +++ b/features/trace/tcpdump.go @@ -2,7 +2,9 @@ package trace import ( "fmt" + "net" "net/http" + "strings" "time" "ems.agt/lib/core/cmd" @@ -21,6 +23,9 @@ var ( UriTcpdumpPcapDownload = config.DefaultUriPrefix + "/traceManagement/{apiVersion}/tcpdumpPcapDownload" CustomUriTcpdumpPcapDownload = config.UriPrefix + "/traceManagement/{apiVersion}/tcpdumpPcapDownload" // decode message api + + UriTcpdumpNeUPFTask = config.DefaultUriPrefix + "/traceManagement/{apiVersion}/tcpdumpNeUPFTask" + CustomUriTcpdumpNeUPFTask = config.UriPrefix + "/traceManagement/{apiVersion}/tcpdumpNeUPFTask" // decode message api ) // NeInfo 网元信息 @@ -104,3 +109,164 @@ func TcpdumpPcapDownload(w http.ResponseWriter, r *http.Request) { ctx.FileAttachment(w, r, localPath, body.FileName) } + +// TcpdumpNeUPFTask 网元UPF发送执行 pcap +func TcpdumpNeUPFTask(w http.ResponseWriter, r *http.Request) { + var body struct { + NeType string `json:"neType"` // 网元类型 + NeId string `json:"neId"` // 网元ID + Cmd string `json:"cmd"` // 命令 + RunType string `json:"runType"` // 执行开始start还是停止stop + } + err := ctx.ShouldBindJSON(r, &body) + if err != nil || body.NeType != "UPF" || body.NeId == "" || body.Cmd == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + neInfo, err := NeInfo(body.NeType, body.NeId) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + + // 开始 + if body.RunType == "start" { + // 创建TCP连接 + conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", neInfo.Ip, 5002)) + if err != nil { + conn.Close() + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + + filePcapName := fmt.Sprintf("tmp_%s_%s.pcap", body.NeType, body.NeId) + cmdStr := fmt.Sprintf("pcap dispatch trace on max 100000 file %s", filePcapName) + + fmt.Fprintln(conn, cmdStr) + + // 读取内容 + time.Sleep(time.Duration(200) * time.Millisecond) + buf := make([]byte, 1024*8) + n, err := conn.Read(buf) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + } else { + str := string(buf[0:n]) + s := strings.Index(str, "pcap dispatch trace:") + if s != -1 { + e := strings.Index(str, "\r\nupfd1#") + str = str[s:e] + } else { + str = fmt.Sprintf("Executed, please stop before proceeding %d", n) + } + ctx.JSON(w, 200, result.OkData(map[string]any{ + "cmd": cmdStr, + "msg": str, + "fileName": filePcapName, + })) + } + conn.Close() + return + } + // 停止 + if body.RunType == "stop" { + // 创建TCP连接 + conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", neInfo.Ip, 5002)) + if err != nil { + conn.Close() + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + + filePcapName := fmt.Sprintf("tmp_%s_%s.pcap", body.NeType, body.NeId) + cmdStr := "pcap dispatch trace off" + + fmt.Fprintln(conn, cmdStr) + + // 读取内容 + time.Sleep(time.Duration(200) * time.Millisecond) + buf := make([]byte, 1024*8) + n, err := conn.Read(buf) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + } else { + str := string(buf[0:n]) + s := strings.Index(str, "pcap dispatch trace:") + if s == -1 { + s = strings.Index(str, "Write ") + } + if s != -1 { + e := strings.Index(str, "\r\nupfd1#") + str = str[s:e] + } else { + str = "No stoppable found" + } + + ctx.JSON(w, 200, result.OkData(map[string]any{ + "cmd": cmdStr, + "msg": str, + "fileName": filePcapName, + })) + } + conn.Close() + return + } + + // 开始 -脚本 + if body.RunType == "start2" { + fileLogName := fmt.Sprintf("tmp_%s_%s.log", body.NeType, body.NeId) + filePcapName := fmt.Sprintf("tmp_%s_%s.pcap", body.NeType, body.NeId) + // 复制文件到网元上 + err := file.FileSCPLocalToNe(neInfo.Ip, "C:\\AMP\\Probject\\ems_backend\\restagent\\backup\\upf_pcap", "/tmp") + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + writeLog := fmt.Sprintf(" >> %s 2>&1 \ncat %s", fileLogName, fileLogName) // 执行信息写入日志文件,放置弹出code 127 + cmdStr := fmt.Sprintf("cd /tmp \nchmod +x upf_pcap\n./upf_pcap '192.168.4.139' 'root' 'Admin123@pl' 'pcap dispatch trace on max 100000 file %s' %s ", fileLogName, writeLog) + + usernameNe := conf.Get("ne.user").(string) // 网元统一用户 + sshHost := fmt.Sprintf("%s@%s", usernameNe, neInfo.Ip) + msg, err := cmd.ExecWithCheck("ssh", sshHost, cmdStr) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + } else { + ctx.JSON(w, 200, result.OkData(map[string]any{ + "cmd": cmdStr, + "msg": msg, + "fileName": filePcapName, + })) + } + return + } + // 停止 -脚本 + if body.RunType == "stop2" { + fileLogName := fmt.Sprintf("tmp_%s_%s.log", body.NeType, body.NeId) + filePcapName := fmt.Sprintf("tmp_%s_%s.pcap", body.NeType, body.NeId) + // cmdStr := "cd /tmp \nexpect /tmp/cat.sh " + err := file.FileSCPLocalToNe(neInfo.Ip, "C:\\AMP\\Probject\\ems_backend\\restagent\\backup\\upf_pcap", "/tmp") + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + writeLog := fmt.Sprintf(" >> %s 2>&1 \ncat %s", fileLogName, fileLogName) // 执行信息写入日志文件,放置弹出code 127 + cmdStr := fmt.Sprintf("cd /tmp \nchmod +x upf_pcap\n./upf_pcap '192.168.4.139' 'root' 'Admin123@pl' 'pcap dispatch trace off' %s ", writeLog) + + usernameNe := conf.Get("ne.user").(string) // 网元统一用户 + sshHost := fmt.Sprintf("%s@%s", usernameNe, neInfo.Ip) + msg, err := cmd.ExecWithCheck("ssh", sshHost, cmdStr) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + } else { + ctx.JSON(w, 200, result.OkData(map[string]any{ + "cmd": cmdStr, + "msg": msg, + "fileName": filePcapName, + })) + } + return + } + + ctx.JSON(w, 200, result.ErrMsg("runType is start or stop")) +} diff --git a/lib/routes/routes.go b/lib/routes/routes.go index c620488a..d371e5b6 100644 --- a/lib/routes/routes.go +++ b/lib/routes/routes.go @@ -248,6 +248,9 @@ func init() { // 网元发送执行 抓包下载pcap文件 Register("POST", trace.UriTcpdumpPcapDownload, trace.TcpdumpPcapDownload, midware.Authorize(nil)) Register("POST", trace.CustomUriTcpdumpPcapDownload, trace.TcpdumpPcapDownload, midware.Authorize(nil)) + // 网元发送执行UPF pcap抓包 + Register("POST", trace.UriTcpdumpNeUPFTask, trace.TcpdumpNeUPFTask, nil) + Register("POST", trace.CustomUriTcpdumpNeUPFTask, trace.TcpdumpNeUPFTask, nil) // file management Register("POST", file.UriFile, file.UploadFile, nil)