接下来我们来分析一下MMS协议,该协议比较抽象,从定义上和理解上都比较抽象,只能在实际使用中去熟悉了,这里我们以操作文件的demo示例来理解和分析整个协议。
对MMS会有一个整体的认识:https://blog.csdn.net/sinat_41915699/article/details/119905968
对MMS抓包分析有个整体的认识:https://www.anquanke.com/post/id/186560
https://www.jianshu.com/p/736505163b73
IEC61850建模,认识MMS的建模:https://blog.csdn.net/kof98765/article/details/112903104
https://www.cnblogs.com/shanwenbin/archive/2013/01/18/2865684.html
https://webstore.iec.ch/preview/info_iec61850-90-5%7Bed1.0%7Den.pdf
关于建模的过程我们暂时不做深入研究,针对IEC61850的MMS协议做一定了解后,使用demo中已有的mms示例server_example_files服务端和mms_utility这个客户端示例来做下测试,并简要分析其代码,然后以此来抓包分析整个mms协议。
如果对MMS协议不了解,面对example下面的示例程序会一脸懵,完全不知道怎么运行测试,这里可以简单理解为MMS协议或者说标准通过将一些设备、操作、数据类型等做了面向对象的抽象,将其抽象为类,比如如下这些类:
然后以服务端-客户端的方式将对象的属性和方法提供出来使用,对象本身可能既具备客户端功能也具备服务端功能,将对外提供的能力以服务端形式展示,并通过客户端能力获取其他对象的服务。
有类就需要实例化对象,而对象则提供服务方法,比如文件的服务就提供读文件夹、打开文件、获取、删除和重命名方法,这样就好理解一些了吧,实际上就是将一些人为的操作内容抽象为类,然后类对象提供服务供客户端调用,实际上就像是提供web服务一样,只是将客户可能产生的接口也都通过协议方式进行了抽象,以模型方式提供xml文件,便于后续自行扩展新接口,这些接口都是包含在其协议定义的各个大类中的(就像积木一样,把常见的积木类型都定义好了为几大类,圆的,方的,三角的等等,然后根据已有的图纸或者自行想象去拼很多的积木人或者积木动物之类的,这些人和动物就像是具体业务的堆叠了,目前常见的就是电力场景业务,电力场景需要的设备、网络连接、程序、数据变量、开关电等事件、日志、文件操作等各种需要的操作都定义进去了,实际上是一套可扩展的标准,并不限于电力场景,只是电力场景用的成熟了,用这个积木已经搭出来一套完善的图纸了,各个电力业务场景可以根据这套图纸来复制搭建了,如果不满足场景可能就会扩展积木类型,也就是协议或者标准的更新)。
关于模型的作用也就是这个文章中提到的信息模型与通信协议独立(https://www.jianshu.com/p/736505163b73):IEC61850标准定义了抽象通信服务接口ACSI(Abstract Communication Service Interface)。
ACSI独立于具体的网络底层通信协议(如MMS)和具体的网络类型(如以太网),需要具体网络接口时,只需采用特定通信服务映射SCSM(Specific Communication Service Mapping),由SCSM映射到具体的通信协议栈。SCSM的内容就是根据需求将ACSI信息模型和服务映射到具体的通信协议。IEC61850需要对信息模型进行扩充,升级时,无需改变已采用的底层通信协议,只要改变具体的SCSM即可。
ACSI主要设定了各类服务模型包括连接服务模型、变量访问服务模型、数据传输服务模型、设备控制服务模型、文件传输服务模型、时钟同步服务模型等。这些服务模型定义了通信对象以及如何对这些对象进行访问,实现客户应用端和服务器应用端的通信,完成实时数据的访问和检索、对设备的控制、时间报告和记录、设备的自我描述等。
其中simoleIO_direct_control.cid就是对应的XML协议,这个在建模部分的文章中有提到(https://www.yuque.com/xiaoyao-nhu75/mlgg0k/kfke8akc2gcbq116#VWKxa),这里我们没有具体的标准的文献,只需要先了解相关概念即可,static_model.c就是对应的模型转换后的代码,server_example_files.c就是对应服务的代码,通过分析我们发现其设置的文件存储路径就是vmd-filestore,demo程序在其下创建了test文件,内容也是test,我们后续可以通过mms客户端的代码取打开获取相关文件的一些信息:
如下是对应代码,整体调用还是比较简单,我做了一些简单的注释:
/*
* server_example_files.c
*
* - How to use some special MMS file service features
* - How to control how files file services can be used
*/
#include "iec61850_server.h"
#include "hal_thread.h"
#include
#include
#include
#include
#include "static_model.h"
static int running = 0;
static IedServer iedServer = NULL;
//退出信号处理
void
sigint_handler(int signalId)
{
running = 0;
}
//客户端连接回调
static void
connectionHandler (IedServer self, ClientConnection connection, bool connected, void* parameter)
{
if (connected)
printf("Connection opened\n");
else
printf("Connection closed\n");
}
//文件操作回调,对应不同的服务
static MmsError
fileAccessHandler (void* parameter, MmsServerConnection connection, MmsFileServiceType service,
const char* localFilename, const char* otherFilename)
{
printf("fileAccessHandler: service = %i, local-file: %s other-file: %s\n", service, localFilename, otherFilename);
/* Don't allow client to rename files */
if (service == MMS_FILE_ACCESS_TYPE_RENAME)
return MMS_ERROR_FILE_FILE_ACCESS_DENIED;
/* Don't allow client to delete file "IEDSERVER.BIN" */
if (service == MMS_FILE_ACCESS_TYPE_DELETE) {
if (strcmp(localFilename, "IEDSERVER.BIN") == 0)
return MMS_ERROR_FILE_FILE_ACCESS_DENIED;
}
/* allow all other accesses */
return MMS_ERROR_NONE;
}
int
main(int argc, char** argv)
{
//mms常用端口102
int tcpPort = 102;
if (argc > 1) {
tcpPort = atoi(argv[1]);
}
printf("Using libIEC61850 version %s\n", LibIEC61850_getVersionString());
//创建服务并加载模型
iedServer = IedServer_create(&iedModel);
/* Set the base path for the MMS file services */
//设置文件服务基础路径
MmsServer mmsServer = IedServer_getMmsServer(iedServer);
IedServer_setFilestoreBasepath(iedServer, "./vmd-filestore/");
/* Set a callback handler to control file accesses */
//设置文件处理回调
MmsServer_installFileAccessHandler(mmsServer, fileAccessHandler, NULL);
//设置连接处理回调
IedServer_setConnectionIndicationHandler(iedServer, (IedConnectionIndicationHandler) connectionHandler, NULL);
/* MMS server will be instructed to start listening to client connections. */
//开始tcp服务监听
IedServer_start(iedServer, tcpPort);
if (!IedServer_isRunning(iedServer)) {
printf("Starting server failed! Exit.\n");
IedServer_destroy(iedServer);
exit(-1);
}
running = 1;
signal(SIGINT, sigint_handler);
while (running)
Thread_sleep(100);
/* stop MMS server - close TCP server socket and all client sockets */
//停止mms服务
IedServer_stop(iedServer);
/* Cleanup - free all resources */
//释放资源
IedServer_destroy(iedServer);
return 0;
} /* main() */
mms的一些通用的操作方法接口都做了介绍,根据协议我们也能看懂一部分的使用,除了-h -p这些指定host和端口的操作外,文件部分-f、-g、-x我们接下来就会展示运行并对其抓包分析:
服务端进行如下操作:
#在libiec61850/build/examples/server_example_files目录下
#创建文件夹并进入该目录
mkdir vmd-filestore
#创建test文件并写入内容test或者其它内容
touch test
#之后回到libiec61850/build/examples/server_example_files执行服务程序
./server_example_files
客户端进行测试:
#查看文件列表
$ ./mms_utility -d -i -f
MMS connected.
Server identity:
----------------
vendor: libiec61850.com
model: LIBIEC61850
revision: 1.5.2
Domains present on server:
--------------------------
simpleIOGenericIO
test
#读文件属性
$ ./mms_utility -d -i -g test
MMS connected.
Server identity:
----------------
vendor: libiec61850.com
model: LIBIEC61850
revision: 1.5.2
Domains present on server:
--------------------------
simpleIOGenericIO
FILENAME: test
SIZE: 5
DATE: 20231221052248.000Z
#删除文件
$ ./mms_utility -d -i -x test
MMS connected.
Server identity:
----------------
vendor: libiec61850.com
model: LIBIEC61850
revision: 1.5.2
Domains present on server:
--------------------------
simpleIOGenericIO
File deleted
三组命令各自对应的过程,分析流程参考这里:(https://www.anquanke.com/post/id/186560)。
在其中我们发现了TPTK、COTP以及ISO 8650-1 OIS Association Control Service,其中TPTK属于会话层,COTP属于表示层,ISO 8650-1 OIS Association Control Service也就是ACSE属于应用层,其通常用来确定、维持或终止在两个应用之间的连接。
(2)、四种MMS包,分别是
这里示例查看iec61850_client_example_files即可,这里就不再说代码了,直接抓包看一下
似乎没有远程写文件fileWrite的直接接口,只能get文件后修改本地文件然后再set到远程替换原本的文件。
MMS协议的分析暂时就到这里了,接下来我们再去分析下IEC 101和IEC 104协议。