python3使用libpcap给ESL命令添加日志记录

操作系统 :CentOS 7.6_x64
FreeSWITCH版本 :1.10.9
python版本:3.9.12
libpcap版本:1.11.0b7
FreeSWITCH的ESL模块用起来很方便,可以控制FreeSWITCH实现具体业务需求,但该模块没有提供ESL命令执行日志,不便于排查问题,本文展示一种使用python3基于libpcap实现ESL命令执行日志的方法,并提供示例代码及相关资源下载途径。

一、背景描述

日常开发过程中观察到:通过ESL发送给FreeSWITCH的命令,在freeswitch.log中找不到记录。

查看代码发现,确实没有相关记录(mod_event_socket.c文件):

static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)

分析后发现,大概有以下几个方法:

  • 1、通过修改FreeSWITCH源代码实现

文件: mod_event_socket.c
入口: api_exec

可通过switch_log_printf函数来实现。

  • 2、使用tcpdump抓取
    因EventSocket模块使用的是基于TCP的文本协议,且未加密,默认端口8021,可以通过tcpdump抓取event socket服务端口获取命令记录。

示例如下:

复制代码
tcpdump tcp dst port 8021 -w test1.pcap
  • 3、使用python3基于libpcap实现
    底层原理和tcpdump一样,只是基于libpcap使用python3进行实现,会灵活很多,这也是本文终点描述的方法,具体实现在后续展开。

二、具体实现

本文基于python3.9.12实现,CentOS 7环境编译及使用python3.9.12,可参考这篇文章:
https://www.cnblogs.com/MikeZhang/p/centos7-install-py39-20220704.html

关键点如下:

1、实时抓取网卡数据

可基于libpcap实时抓取网卡数据,具体可参考我之前写的文章:

https://www.cnblogs.com/MikeZhang/p/pythonUseLibpcap20221029.html

2、解析IP头获取源地址

需要获取发送ESL命令机器的源地址以便排查问题,IP数据包里面包含有源地址,python中解析IP头的示例如下:

复制代码
ipInfo = struct.unpack('!BBHHHBBH4s4s',bytes(p[14:34]))
srcIp = socket.inet_ntoa(ipInfo[-2])
dstIp = socket.inet_ntoa(ipInfo[-1])

3、解析TCP头获取具体数据

具体的ESL命令在TCP的数据部分保存,可通过解析TCP头获取ESL数据的起始下标,进而获取数据,示例如下:

复制代码
tcpInfo = struct.unpack('!HHLLBBH',bytes(p[34:50]))
tcpHdrLen = (tcpInfo[4] >> 4) * 4
offset = 34 + tcpHdrLen
data = bytes(p[offset:tlen])

4、使用logging模块进行记录

可使用python自带的日志模块记录ESL命令记录,并进行存盘,便于后续查看。

示例如下:

复制代码
logger.info("(%s,%s)" % (srcIp,data))

logger可在main函数中实现,指定具体的存盘文件,如果只是想控制台查看,则可以这样实现:

复制代码
logger = logging.getLogger()

...

logging.basicConfig(
    level=logging.DEBUG, # DEBUG,INFO,WARNING,ERROR,CRITICAL
    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
    datefmt='%a, %d %b %Y %H:%M:%S'
)

基于上述关键点,可以实现ESL命令的日志记录,示例如下(eslLogTest1.py):

完整代码可从如下渠道获取:
关注微信公众号(聊聊博文,文末可扫码)后回复 20231125 获取。

三、运行效果

可使用ESL发送命令,然后用python脚本进行记录。发送ESL命令可使用ESL库,python3.9.12版本的ESL编译及使用,可参考这篇文章:
https://www.cnblogs.com/MikeZhang/p/py39esl-20230424.html
也可直接使用socket,示例如下(sendcmd1.py):

复制代码
import socket,time

def doCmd(sock,cmd):
    print(cmd)
    sock.send(cmd + b'\r\n\r\n')

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
sock.connect(('192.168.137.32', 8021))  
sock.send(b'auth ClueCon\r\n\r\n')
doCmd(sock,b'bgapi originate user/1000 &echo')
time.sleep(10)
doCmd(sock,b'bgapi hupall')

发送命令后,使用python实时记录的运行效果如下:

运行效果视频可从如下渠道获取:
关注微信公众号(聊聊博文,文末可扫码)后回复 2023112501 获取。

四、资源获取

本文涉及资源,可以从如下途径获取:

关注微信公众号(聊聊博文,文末可扫码)后回复 20231125 获取。

好,就这么多了,希望对你有帮助。

相关推荐
Psycho_MrZhang14 分钟前
高并发服务设计思路
python
多米Domi01137 分钟前
0x3f 第21天 三更java进阶1-35 hot100普通数组
java·python·算法·leetcode·动态规划
小程故事多_801 小时前
从零吃透PyTorch,最易懂的入门全指南
人工智能·pytorch·python
Keep_Trying_Go2 小时前
基于无监督backbone无需训练的类别无关目标统计CountingDINO算法详解
人工智能·python·算法·多模态·目标统计
weixin_433179332 小时前
python - for循环,字符串,元组基础
开发语言·python
^哪来的&永远~2 小时前
Python 轻量级 UI:EEG 与 fNIRS 预处理图形界面
python·可视化·功能连接·eeg·mne·fnirs·eeglab
AI大佬的小弟3 小时前
Python基础(11):Python中函数参数的进阶模式详解
python·lambda函数·函数的参数解释·函数的参数进阶·位置参数·关键词参数·匿名函数与普通函数
智算菩萨3 小时前
Python可以做哪些小游戏——基于Python 3.13最新特性的游戏开发全指南(15万字超长文章,强烈建议收藏阅读)
python·pygame
智航GIS3 小时前
9.1 多线程入门
java·开发语言·python
nvd113 小时前
FastMCP 开发指南: 5分钟入门
人工智能·python