mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 22:58:20 +00:00
Modbus analyser, added support: FC=20,21
This commit is contained in:
parent
e8f4c7bc3d
commit
c58c6791c5
5 changed files with 611 additions and 21 deletions
|
@ -688,6 +688,274 @@ event modbus_write_multi_response(c:connection,is_orig:bool,tid:count,pid:count,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#REQUEST FC=20
|
||||||
|
event modbus_read_reference_request(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,refCount:count,t:int_vec)
|
||||||
|
{
|
||||||
|
|
||||||
|
local k:file;
|
||||||
|
local m:file;
|
||||||
|
local ftime:string;
|
||||||
|
local src:string;
|
||||||
|
local dst:string;
|
||||||
|
local src_p:string;
|
||||||
|
local dst_p:string;
|
||||||
|
|
||||||
|
|
||||||
|
k=open_for_append (string_cat(path,"f20_new.log"));
|
||||||
|
m=open_for_append (string_cat(path,"fall_new.log"));
|
||||||
|
ftime=strftime("%F %T",network_time());
|
||||||
|
|
||||||
|
src= cat(c$id$orig_h);
|
||||||
|
dst=cat(c$id$resp_h);
|
||||||
|
src_p=cat(c$id$orig_p);
|
||||||
|
dst_p=cat(c$id$resp_p);
|
||||||
|
|
||||||
|
#according to the specification, this FC usually has 4xxxx offset in the memory map
|
||||||
|
#local prefix_ref:count;
|
||||||
|
#prefix_ref=ref+40000;
|
||||||
|
|
||||||
|
|
||||||
|
local text=string_cat(ftime,"\t",src,"\t",dst,"\t",src_p, "\t REQUEST \t",cat(tid), "\t",cat(pid),"\t", cat(uid),"\t",cat(fc),"\t",cat(refCount),"\t",cat(t),"\n");
|
||||||
|
|
||||||
|
write_file(k,text);
|
||||||
|
write_file(m,text);
|
||||||
|
|
||||||
|
close(k);
|
||||||
|
close(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#RESPONSE FC=20
|
||||||
|
event modbus_read_reference_response(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,byteCount:count,t:int_vec)
|
||||||
|
{
|
||||||
|
|
||||||
|
local k:file;
|
||||||
|
local m:file;
|
||||||
|
local ftime:string;
|
||||||
|
local src:string;
|
||||||
|
local dst:string;
|
||||||
|
local src_p:string;
|
||||||
|
local dst_p:string;
|
||||||
|
|
||||||
|
|
||||||
|
k=open_for_append (string_cat(path,"f20_new.log"));
|
||||||
|
m=open_for_append (string_cat(path,"fall_new.log"));
|
||||||
|
ftime=strftime("%F %T",network_time());
|
||||||
|
|
||||||
|
src= cat(c$id$orig_h);
|
||||||
|
dst=cat(c$id$resp_h);
|
||||||
|
src_p=cat(c$id$orig_p);
|
||||||
|
dst_p=cat(c$id$resp_p);
|
||||||
|
|
||||||
|
#according to the specification, this FC usually has 4xxxx offset in the memory map
|
||||||
|
#local prefix_ref:count;
|
||||||
|
#prefix_ref=ref+40000;
|
||||||
|
|
||||||
|
|
||||||
|
local text=string_cat(ftime,"\t",src,"\t",dst,"\t",src_p, "\t RESPONSE \t",cat(tid), "\t",cat(pid),"\t", cat(uid),"\t",cat(fc),"\t",cat(byteCount),"\t",cat(t),"\n");
|
||||||
|
|
||||||
|
write_file(k,text);
|
||||||
|
write_file(m,text);
|
||||||
|
|
||||||
|
close(k);
|
||||||
|
close(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#REQUEST FC=20 (for single reference)
|
||||||
|
event modbus_read_single_reference_request(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,refType:count,refNumber:count,wordCount:count)
|
||||||
|
{
|
||||||
|
|
||||||
|
local k:file;
|
||||||
|
local m:file;
|
||||||
|
local ftime:string;
|
||||||
|
local src:string;
|
||||||
|
local dst:string;
|
||||||
|
local src_p:string;
|
||||||
|
local dst_p:string;
|
||||||
|
|
||||||
|
|
||||||
|
k=open_for_append (string_cat(path,"f20_singles_new.log"));
|
||||||
|
m=open_for_append (string_cat(path,"fall_new.log"));
|
||||||
|
ftime=strftime("%F %T",network_time());
|
||||||
|
|
||||||
|
src= cat(c$id$orig_h);
|
||||||
|
dst=cat(c$id$resp_h);
|
||||||
|
src_p=cat(c$id$orig_p);
|
||||||
|
dst_p=cat(c$id$resp_p);
|
||||||
|
|
||||||
|
#according to the specification, this FC usually has 4xxxx offset in the memory map
|
||||||
|
#local prefix_ref:count;
|
||||||
|
#prefix_ref=ref+40000;
|
||||||
|
|
||||||
|
|
||||||
|
local text=string_cat(ftime,"\t",src,"\t",dst,"\t",src_p, "\t REQUEST \t",cat(tid), "\t",cat(pid),"\t", cat(uid),"\t",cat(fc),"\t",cat(refType),"\t",cat(refNumber),"\t",cat(wordCount),"\n");
|
||||||
|
|
||||||
|
write_file(k,text);
|
||||||
|
write_file(m,text);
|
||||||
|
|
||||||
|
close(k);
|
||||||
|
close(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#RESPONSE FC=20 (for single reference)
|
||||||
|
event modbus_read_single_reference_response(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,byteCount:count,refType:count,t:int_vec)
|
||||||
|
{
|
||||||
|
|
||||||
|
local k:file;
|
||||||
|
local m:file;
|
||||||
|
local ftime:string;
|
||||||
|
local src:string;
|
||||||
|
local dst:string;
|
||||||
|
local src_p:string;
|
||||||
|
local dst_p:string;
|
||||||
|
|
||||||
|
|
||||||
|
k=open_for_append (string_cat(path,"f20_singles_new.log"));
|
||||||
|
m=open_for_append (string_cat(path,"fall_new.log"));
|
||||||
|
ftime=strftime("%F %T",network_time());
|
||||||
|
|
||||||
|
src= cat(c$id$orig_h);
|
||||||
|
dst=cat(c$id$resp_h);
|
||||||
|
src_p=cat(c$id$orig_p);
|
||||||
|
dst_p=cat(c$id$resp_p);
|
||||||
|
|
||||||
|
#according to the specification, this FC usually has 4xxxx offset in the memory map
|
||||||
|
#local prefix_ref:count;
|
||||||
|
#prefix_ref=ref+40000;
|
||||||
|
|
||||||
|
|
||||||
|
local text=string_cat(ftime,"\t",src,"\t",dst,"\t",src_p, "\t RESPONSE \t",cat(tid), "\t",cat(pid),"\t", cat(uid),"\t",cat(fc),"\t",cat(byteCount),"\t",cat(refType),"\t",cat(t),"\n");
|
||||||
|
|
||||||
|
write_file(k,text);
|
||||||
|
write_file(m,text);
|
||||||
|
|
||||||
|
close(k);
|
||||||
|
close(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#REQUEST FC=21
|
||||||
|
event modbus_write_reference_request(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,byteCount:count,t:int_vec)
|
||||||
|
{
|
||||||
|
|
||||||
|
local k:file;
|
||||||
|
local m:file;
|
||||||
|
local ftime:string;
|
||||||
|
local src:string;
|
||||||
|
local dst:string;
|
||||||
|
local src_p:string;
|
||||||
|
local dst_p:string;
|
||||||
|
|
||||||
|
|
||||||
|
k=open_for_append (string_cat(path,"f21_new.log"));
|
||||||
|
m=open_for_append (string_cat(path,"fall_new.log"));
|
||||||
|
ftime=strftime("%F %T",network_time());
|
||||||
|
|
||||||
|
src= cat(c$id$orig_h);
|
||||||
|
dst=cat(c$id$resp_h);
|
||||||
|
src_p=cat(c$id$orig_p);
|
||||||
|
dst_p=cat(c$id$resp_p);
|
||||||
|
|
||||||
|
#according to the specification, this FC usually has 4xxxx offset in the memory map
|
||||||
|
#local prefix_ref:count;
|
||||||
|
#prefix_ref=ref+40000;
|
||||||
|
|
||||||
|
|
||||||
|
local text=string_cat(ftime,"\t",src,"\t",dst,"\t",src_p, "\t REQUEST \t",cat(tid), "\t",cat(pid),"\t", cat(uid),"\t",cat(fc),"\t",cat(byteCount),"\t",cat(t),"\n");
|
||||||
|
|
||||||
|
write_file(k,text);
|
||||||
|
write_file(m,text);
|
||||||
|
|
||||||
|
close(k);
|
||||||
|
close(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#RESPONSE FC=21
|
||||||
|
event modbus_read_reference_response(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,byteCount:count,t:int_vec)
|
||||||
|
{
|
||||||
|
|
||||||
|
local k:file;
|
||||||
|
local m:file;
|
||||||
|
local ftime:string;
|
||||||
|
local src:string;
|
||||||
|
local dst:string;
|
||||||
|
local src_p:string;
|
||||||
|
local dst_p:string;
|
||||||
|
|
||||||
|
|
||||||
|
k=open_for_append (string_cat(path,"f21_new.log"));
|
||||||
|
m=open_for_append (string_cat(path,"fall_new.log"));
|
||||||
|
ftime=strftime("%F %T",network_time());
|
||||||
|
|
||||||
|
src= cat(c$id$orig_h);
|
||||||
|
dst=cat(c$id$resp_h);
|
||||||
|
src_p=cat(c$id$orig_p);
|
||||||
|
dst_p=cat(c$id$resp_p);
|
||||||
|
|
||||||
|
#according to the specification, this FC usually has 4xxxx offset in the memory map
|
||||||
|
#local prefix_ref:count;
|
||||||
|
#prefix_ref=ref+40000;
|
||||||
|
|
||||||
|
|
||||||
|
local text=string_cat(ftime,"\t",src,"\t",dst,"\t",src_p, "\t RESPONSE \t",cat(tid), "\t",cat(pid),"\t", cat(uid),"\t",cat(fc),"\t",cat(byteCount),"\t",cat(t),"\n");
|
||||||
|
|
||||||
|
write_file(k,text);
|
||||||
|
write_file(m,text);
|
||||||
|
|
||||||
|
close(k);
|
||||||
|
close(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#REQUEST/RESPONSE FC=20 (for single reference)
|
||||||
|
event modbus_write_single_reference(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,refType:count,refNumber:count,wordCount:count,t:int_vec)
|
||||||
|
{
|
||||||
|
|
||||||
|
local k:file;
|
||||||
|
local m:file;
|
||||||
|
local ftime:string;
|
||||||
|
local src:string;
|
||||||
|
local dst:string;
|
||||||
|
local src_p:string;
|
||||||
|
local dst_p:string;
|
||||||
|
|
||||||
|
|
||||||
|
k=open_for_append (string_cat(path,"f21_singles_new.log"));
|
||||||
|
m=open_for_append (string_cat(path,"fall_new.log"));
|
||||||
|
ftime=strftime("%F %T",network_time());
|
||||||
|
|
||||||
|
src= cat(c$id$orig_h);
|
||||||
|
dst=cat(c$id$resp_h);
|
||||||
|
src_p=cat(c$id$orig_p);
|
||||||
|
dst_p=cat(c$id$resp_p);
|
||||||
|
|
||||||
|
#according to the specification, this FC usually has 4xxxx offset in the memory map
|
||||||
|
#local prefix_ref:count;
|
||||||
|
#prefix_ref=ref+40000;
|
||||||
|
|
||||||
|
|
||||||
|
local text=string_cat(ftime,"\t",src,"\t",dst,"\t",src_p, "\t REQUEST/RESPONSE \t",cat(tid), "\t",cat(pid),"\t", cat(uid),"\t",cat(fc),"\t",cat(refType),"\t",cat(refNumber),"\t",cat(wordCount),"\t",cat(t),"\n");
|
||||||
|
|
||||||
|
write_file(k,text);
|
||||||
|
write_file(m,text);
|
||||||
|
|
||||||
|
close(k);
|
||||||
|
close(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#REQUEST FC=22
|
#REQUEST FC=22
|
||||||
event modbus_mask_write_request(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,ref:count,andMask:count,orMask:count)
|
event modbus_mask_write_request(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,ref:count,andMask:count,orMask:count)
|
||||||
{
|
{
|
||||||
|
|
11
src/Modbus.h
11
src/Modbus.h
|
@ -46,6 +46,17 @@ public:
|
||||||
|| modbus_force_coils_request
|
|| modbus_force_coils_request
|
||||||
|| modbus_force_coils_response
|
|| modbus_force_coils_response
|
||||||
|
|
||||||
|
|| modbus_read_reference_request
|
||||||
|
|| modbus_read_reference_response
|
||||||
|
|
||||||
|
|| modbus_read_single_reference_request
|
||||||
|
|| modbus_read_single_reference_response
|
||||||
|
|
||||||
|
|| modbus_write_reference_request
|
||||||
|
|| modbus_write_reference_response
|
||||||
|
|
||||||
|
|| modbus_write_single_reference
|
||||||
|
|
||||||
|| modbus_write_multi_request
|
|| modbus_write_multi_request
|
||||||
|| modbus_write_multi_response
|
|| modbus_write_multi_response
|
||||||
|
|
||||||
|
|
|
@ -6650,10 +6650,26 @@ event modbus_force_coils_request%(c:connection,is_orig:bool,tid:count,pid:count,
|
||||||
event modbus_write_multi_request%(c:connection,is_orig:bool,t:int_vec,tid:count,pid:count,uid:count,fc:count,ref:count,wCount:count,bCount:count,len:count%);
|
event modbus_write_multi_request%(c:connection,is_orig:bool,t:int_vec,tid:count,pid:count,uid:count,fc:count,ref:count,wCount:count,bCount:count,len:count%);
|
||||||
|
|
||||||
|
|
||||||
|
#Event that passes modbus request function code=20
|
||||||
|
event modbus_read_reference_request%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,refCount:count,t:int_vec%);
|
||||||
|
|
||||||
|
#Event that passes modbus request function code=20 for single reference
|
||||||
|
event modbus_read_single_reference_request%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,refType:count,refNumber:count,wordCount:count%);
|
||||||
|
|
||||||
|
|
||||||
|
#Event that passes modbus request function code=21
|
||||||
|
event modbus_write_reference_request%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,byteCount:count,t:int_vec%);
|
||||||
|
|
||||||
|
|
||||||
|
#Event that passes modbus request/response function code=21 for single reference
|
||||||
|
event modbus_write_single_reference%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,refType:count,refNumber:count,wordCount:count,t:int_vec%);
|
||||||
|
|
||||||
#Event that passes modbus request function code=22
|
#Event that passes modbus request function code=22
|
||||||
event modbus_mask_write_request%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,ref:count,andMask:count,orMask:count%);
|
event modbus_mask_write_request%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,ref:count,andMask:count,orMask:count%);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#Event that passes modbus request function code=23
|
#Event that passes modbus request function code=23
|
||||||
event modbus_read_write_request%(c:connection,is_orig:bool,t:int_vec,tid:count,pid:count,uid:count,fc:count,refRead:count,wcRead:count,refWrite:count,wcWrite:count,bCount:count,len:count%);
|
event modbus_read_write_request%(c:connection,is_orig:bool,t:int_vec,tid:count,pid:count,uid:count,fc:count,refRead:count,wcRead:count,refWrite:count,wcWrite:count,bCount:count,len:count%);
|
||||||
|
|
||||||
|
@ -6693,6 +6709,16 @@ event modbus_force_coils_response%(c:connection,is_orig:bool,tid:count,pid:count
|
||||||
event modbus_write_multi_response%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,ref:count,wcount:count,len:count%);
|
event modbus_write_multi_response%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,ref:count,wcount:count,len:count%);
|
||||||
|
|
||||||
|
|
||||||
|
#Event that passes modbus response function code=20
|
||||||
|
event modbus_read_reference_response%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,byteCount:count,t:int_vec%);
|
||||||
|
|
||||||
|
#Event that passes modbus response function code=20 for single reference
|
||||||
|
event modbus_read_single_reference_response%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,byteCount:count,refType:count,t:int_vec%);
|
||||||
|
|
||||||
|
#Event that passes modbus response function code=21
|
||||||
|
event modbus_write_reference_response%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,byteCount:count,t:int_vec%);
|
||||||
|
|
||||||
|
|
||||||
#Event that passes modbus response function code=22
|
#Event that passes modbus response function code=22
|
||||||
event modbus_mask_write_response%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,ref:count,andMask:count,orMask:count%);
|
event modbus_mask_write_response%(c:connection,is_orig:bool,tid:count,pid:count,uid:count,fc:count,ref:count,andMask:count,orMask:count%);
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,161 @@ function deliver_WriteMultiRegReq( writeMulti: WriteMultipleRegistersRequest, ti
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
#REQUEST FC=20
|
||||||
|
function deliver_ReadReferenceReq(tid:uint16, pid:uint16, uid: uint8, fc: uint8,refCount:uint8,reference:Reference[]): bool
|
||||||
|
%{
|
||||||
|
|
||||||
|
|
||||||
|
VectorVal * t=new VectorVal( new VectorType(base_type(TYPE_INT)));
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < (${reference}->size()); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
Val* r=new Val((${reference[i].refType}),TYPE_INT);
|
||||||
|
t->Assign(i,r,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
Val* k=new Val((${reference[i].refNumber}),TYPE_INT);
|
||||||
|
t->Assign(i,k,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
Val* l=new Val((${reference[i].wordCount}),TYPE_INT);
|
||||||
|
t->Assign(i,l,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( ::modbus_read_reference_request )
|
||||||
|
{
|
||||||
|
|
||||||
|
BifEvent::generate_modbus_read_reference_request(
|
||||||
|
connection()->bro_analyzer(),
|
||||||
|
connection()->bro_analyzer()->Conn(),
|
||||||
|
is_orig(),tid,pid,uid,fc,refCount,t);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
#REQUEST FC=20 (to read single reference)
|
||||||
|
function deliver_ReadSingleReferenceReq(tid:uint16,pid:uint16,uid:uint8,fc:uint8,refType:uint8,refNumber:uint32,wordCount:uint16): bool
|
||||||
|
%{
|
||||||
|
|
||||||
|
if ( ::modbus_read_single_reference_request)
|
||||||
|
{
|
||||||
|
BifEvent::generate_modbus_read_single_reference_request(
|
||||||
|
connection()->bro_analyzer(),
|
||||||
|
connection()->bro_analyzer()->Conn(),
|
||||||
|
is_orig(),tid,pid,uid,fc,refType,refNumber,wordCount);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#RESPONSE FC=20 (to read single reference)
|
||||||
|
function deliver_ReadSingleReferenceRes(tid:uint16, pid:uint16, uid: uint8, fc: uint8,byteCount:uint8,refType:uint8,ref:ReferenceResponse): bool
|
||||||
|
%{
|
||||||
|
|
||||||
|
|
||||||
|
VectorVal * t=new VectorVal( new VectorType(base_type(TYPE_INT)));
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < (${ref.registerValue}->size()); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
Val* r=new Val(((*ref->registerValue())[i]),TYPE_INT);
|
||||||
|
t->Assign(i,r,0,OP_ASSIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( ::modbus_read_single_reference_response )
|
||||||
|
{
|
||||||
|
|
||||||
|
BifEvent::generate_modbus_read_single_reference_response(
|
||||||
|
connection()->bro_analyzer(),
|
||||||
|
connection()->bro_analyzer()->Conn(),
|
||||||
|
is_orig(),tid,pid,uid,fc,byteCount,refType,t);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#REQUEST FC=21
|
||||||
|
function deliver_WriteReferenceReq(tid:uint16,pid:uint16,uid:uint8,fc:uint8,byteCount:uint8,reference:ReferenceWithData[]): bool
|
||||||
|
%{
|
||||||
|
|
||||||
|
|
||||||
|
VectorVal * t=new VectorVal( new VectorType(base_type(TYPE_INT)));
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < (${reference}->size()); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
Val* r=new Val((${reference[i].refType}),TYPE_INT);
|
||||||
|
t->Assign(i,r,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
Val* k=new Val((${reference[i].refNumber}),TYPE_INT);
|
||||||
|
t->Assign(i,k,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
Val* n=new Val((${reference[i].wordCount}),TYPE_INT);
|
||||||
|
t->Assign(i,n,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
for (unsigned int j=0; j<(${reference[i].registerValue}->size());++j)
|
||||||
|
{
|
||||||
|
k=new Val((${reference[i].registerValue[j]}),TYPE_INT);
|
||||||
|
t->Assign(i,k,0,OP_ASSIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( ::modbus_write_reference_request )
|
||||||
|
{
|
||||||
|
|
||||||
|
BifEvent::generate_modbus_write_reference_request(
|
||||||
|
connection()->bro_analyzer(),
|
||||||
|
connection()->bro_analyzer()->Conn(),
|
||||||
|
is_orig(),tid,pid,uid,fc,byteCount,t);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#RESPONSE FC=21 (to write single reference)
|
||||||
|
function deliver_WriteSingleReference(tid:uint16, pid:uint16, uid: uint8, fc: uint8,refType:uint8,refNumber:uint32,wordCount:uint16,ref:ReferenceWithData): bool
|
||||||
|
%{
|
||||||
|
|
||||||
|
|
||||||
|
VectorVal * t=new VectorVal( new VectorType(base_type(TYPE_INT)));
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < (${ref.registerValue}->size()); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
Val* r=new Val(((*ref->registerValue())[i]),TYPE_INT);
|
||||||
|
t->Assign(i,r,0,OP_ASSIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( ::modbus_write_single_reference)
|
||||||
|
{
|
||||||
|
|
||||||
|
BifEvent::generate_modbus_write_single_reference(
|
||||||
|
connection()->bro_analyzer(),
|
||||||
|
connection()->bro_analyzer()->Conn(),
|
||||||
|
is_orig(),tid,pid,uid,fc,refType,refNumber,wordCount,t);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
#REQUEST FC=22
|
#REQUEST FC=22
|
||||||
function deliver_MaskWriteRegReq(tid:uint16,pid:uint16,uid:uint8,fc:uint8,ref:uint16,andMask:uint16,orMask:uint16): bool
|
function deliver_MaskWriteRegReq(tid:uint16,pid:uint16,uid:uint8,fc:uint8,ref:uint16,andMask:uint16,orMask:uint16): bool
|
||||||
%{
|
%{
|
||||||
|
@ -405,6 +560,88 @@ function deliver_WriteMultiRegRes(tid:uint16,pid:uint16,uid:uint8,fc:uint8, ref:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#RESPONSE FC=20
|
||||||
|
function deliver_ReadReferenceRes(tid:uint16,pid:uint16,uid:uint8,fc:uint8,byteCount:uint8,reference:ReferenceResponse[]): bool
|
||||||
|
%{
|
||||||
|
|
||||||
|
|
||||||
|
VectorVal * t=new VectorVal( new VectorType(base_type(TYPE_INT)));
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < (${reference}->size()); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
Val* r=new Val((${reference[i].byteCount}),TYPE_INT);
|
||||||
|
t->Assign(i,r,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
Val* k=new Val((${reference[i].refType}),TYPE_INT);
|
||||||
|
t->Assign(i,k,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
for (unsigned int j=0; j<(${reference[i].registerValue}->size());++j)
|
||||||
|
{
|
||||||
|
k=new Val((${reference[i].registerValue[j]}),TYPE_INT);
|
||||||
|
t->Assign(i,k,0,OP_ASSIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( ::modbus_read_reference_response )
|
||||||
|
{
|
||||||
|
|
||||||
|
BifEvent::generate_modbus_read_reference_response(
|
||||||
|
connection()->bro_analyzer(),
|
||||||
|
connection()->bro_analyzer()->Conn(),
|
||||||
|
is_orig(),tid,pid,uid,fc,byteCount,t);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
#RESPONSE FC=21
|
||||||
|
function deliver_WriteReferenceRes(tid:uint16,pid:uint16,uid:uint8,fc:uint8,byteCount:uint8,reference:ReferenceWithData[]): bool
|
||||||
|
%{
|
||||||
|
|
||||||
|
|
||||||
|
VectorVal * t=new VectorVal( new VectorType(base_type(TYPE_INT)));
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < (${reference}->size()); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
Val* r=new Val((${reference[i].refType}),TYPE_INT);
|
||||||
|
t->Assign(i,r,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
Val* k=new Val((${reference[i].refNumber}),TYPE_INT);
|
||||||
|
t->Assign(i,k,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
Val* n=new Val((${reference[i].wordCount}),TYPE_INT);
|
||||||
|
t->Assign(i,n,0,OP_ASSIGN);
|
||||||
|
|
||||||
|
for (unsigned int j=0; j<(${reference[i].registerValue}->size());++j)
|
||||||
|
{
|
||||||
|
k=new Val((${reference[i].registerValue[j]}),TYPE_INT);
|
||||||
|
t->Assign(i,k,0,OP_ASSIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( ::modbus_write_reference_response )
|
||||||
|
{
|
||||||
|
|
||||||
|
BifEvent::generate_modbus_write_reference_response(
|
||||||
|
connection()->bro_analyzer(),
|
||||||
|
connection()->bro_analyzer()->Conn(),
|
||||||
|
is_orig(),tid,pid,uid,fc,byteCount,t);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#RESPONSE FC=22
|
#RESPONSE FC=22
|
||||||
function deliver_MaskWriteRegRes(tid:uint16,pid:uint16,uid:uint8,fc:uint8,ref:uint16,andMask:uint16,orMask:uint16): bool
|
function deliver_MaskWriteRegRes(tid:uint16,pid:uint16,uid:uint8,fc:uint8,ref:uint16,andMask:uint16,orMask:uint16): bool
|
||||||
%{
|
%{
|
||||||
|
|
|
@ -112,19 +112,42 @@ type ModbusTCP_TransportHeader = record {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type Reference = record {
|
type Reference (header:ModbusTCP_TransportHeader) = record {
|
||||||
refType: uint8;
|
refType: uint8;
|
||||||
refNumber: uint32;
|
refNumber: uint32;
|
||||||
wordCount: uint16;
|
wordCount: uint16;
|
||||||
|
}
|
||||||
|
&let {
|
||||||
|
deliver: bool =$context.flow.deliver_ReadSingleReferenceReq(header.tid,header.pid,header.uid,header.fc,refType,refNumber,wordCount);
|
||||||
};
|
};
|
||||||
|
|
||||||
type ReferenceWithData = record {
|
|
||||||
|
type ReferenceWithData (header:ModbusTCP_TransportHeader) = record {
|
||||||
refType: uint8;
|
refType: uint8;
|
||||||
refNumber: uint32;
|
refNumber: uint32;
|
||||||
wordCount: uint16;
|
wordCount: uint16;
|
||||||
registerValue: uint16[wordCount] &length = 2*wordCount; # TODO: check that the array length is calculated correctly
|
registerValue: uint16[wordCount] &length = 2*wordCount; # TODO: check that the array length is calculated correctly
|
||||||
|
}
|
||||||
|
&let {
|
||||||
|
deliver: bool =$context.flow.deliver_WriteSingleReference(header.tid,header.pid,header.uid,header.fc,refType,refNumber,wordCount,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
#Dina modified
|
||||||
|
type ReferenceResponse(header:ModbusTCP_TransportHeader)=record{
|
||||||
|
byteCount:uint8;
|
||||||
|
refType:uint8;
|
||||||
|
registerValue:uint16[wordCount];
|
||||||
|
}
|
||||||
|
&let {
|
||||||
|
wordCount : uint8 = byteCount/2;
|
||||||
|
|
||||||
|
deliver: bool =$context.flow.deliver_ReadSingleReferenceRes(header.tid,header.pid,header.uid,header.fc,byteCount,refType,this);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
type Exception(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
type Exception(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
||||||
code: uint8;
|
code: uint8;
|
||||||
}&let {
|
}&let {
|
||||||
|
@ -147,8 +170,8 @@ type ModbusTCP_RequestPDU = record {
|
||||||
READ_EXCEPTION_STATUS -> readExceptionStatus: ReadExceptionStatusRequest(header.len-2,header);
|
READ_EXCEPTION_STATUS -> readExceptionStatus: ReadExceptionStatusRequest(header.len-2,header);
|
||||||
# Class 2
|
# Class 2
|
||||||
FORCE_MULTIPLE_COILS -> forceMultipleCoils: ForceMultipleCoilsRequest(header.len-2,header);
|
FORCE_MULTIPLE_COILS -> forceMultipleCoils: ForceMultipleCoilsRequest(header.len-2,header);
|
||||||
READ_GENERAL_REFERENCE -> readGeneralReference: ReadGeneralReferenceRequest(header.len-2);
|
READ_GENERAL_REFERENCE -> readGeneralreference: ReadGeneralReferenceRequest(header.len-2,header);
|
||||||
WRITE_GENERAL_REFERENCE -> writeGeneralReference: WriteGeneralReferenceRequest(header.len-2);
|
WRITE_GENERAL_REFERENCE -> writeGeneralReference: WriteGeneralReferenceRequest(header.len-2,header);
|
||||||
MASK_WRITE_REGISTER -> maskWriteRegister: MaskWriteRegisterRequest(header.len-2,header);
|
MASK_WRITE_REGISTER -> maskWriteRegister: MaskWriteRegisterRequest(header.len-2,header);
|
||||||
READ_WRITE_REGISTERS -> readWriteRegisters: ReadWriteRegistersRequest(header.len-2,header);
|
READ_WRITE_REGISTERS -> readWriteRegisters: ReadWriteRegistersRequest(header.len-2,header);
|
||||||
READ_FIFO_QUEUE -> readFIFOQueue: ReadFIFOQueueRequest(header.len-2,header);
|
READ_FIFO_QUEUE -> readFIFOQueue: ReadFIFOQueueRequest(header.len-2,header);
|
||||||
|
@ -251,6 +274,8 @@ deliver: bool =$context.flow.deliver_ReadExceptStatReq(header.tid,header.pid,hea
|
||||||
};
|
};
|
||||||
|
|
||||||
# Class 2 requests
|
# Class 2 requests
|
||||||
|
|
||||||
|
#REQUEST FC=15
|
||||||
type ForceMultipleCoilsRequest(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
type ForceMultipleCoilsRequest(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
||||||
referenceNumber: uint16;
|
referenceNumber: uint16;
|
||||||
bitCount: uint16 &check(bitCount <= 800);
|
bitCount: uint16 &check(bitCount <= 800);
|
||||||
|
@ -261,20 +286,30 @@ type ForceMultipleCoilsRequest(len: uint16,header:ModbusTCP_TransportHeader) = r
|
||||||
deliver: bool =$context.flow.deliver_ForceMultiCoilsReq(header.tid,header.pid,header.uid,header.fc,referenceNumber,bitCount,byteCount,coils);
|
deliver: bool =$context.flow.deliver_ForceMultiCoilsReq(header.tid,header.pid,header.uid,header.fc,referenceNumber,bitCount,byteCount,coils);
|
||||||
};
|
};
|
||||||
|
|
||||||
type ReadGeneralReferenceRequest(len: uint16) = record {
|
#REQUEST FC=20
|
||||||
|
type ReadGeneralReferenceRequest(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
||||||
byteCount: uint8;
|
byteCount: uint8;
|
||||||
references: Reference[referenceCount] &length = byteCount;
|
references: Reference(header)[referenceCount] &length = byteCount;
|
||||||
} &let {
|
} &let {
|
||||||
referenceCount: uint8 = byteCount/7;
|
referenceCount: uint8 = byteCount/7;
|
||||||
|
|
||||||
|
deliver: bool =$context.flow.deliver_ReadReferenceReq(header.tid,header.pid,header.uid,header.fc,referenceCount,references);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type WriteGeneralReferenceRequest(len: uint16) = record {
|
|
||||||
|
#REQUEST FC=21
|
||||||
|
type WriteGeneralReferenceRequest(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
||||||
byteCount: uint8;
|
byteCount: uint8;
|
||||||
references: ReferenceWithData[] &until($input.length() == 0) &length = byteCount;
|
references: ReferenceWithData(header)[] &until($input.length() == 0) &length = byteCount;
|
||||||
} &length = len;
|
} &length = len,
|
||||||
|
&let {
|
||||||
|
deliver: bool =$context.flow.deliver_WriteReferenceReq(header.tid,header.pid,header.uid,header.fc,byteCount,references);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#REQUEST FC=22
|
#REQUESTeFC=22
|
||||||
type MaskWriteRegisterRequest(len: uint16,header: ModbusTCP_TransportHeader) = record {
|
type MaskWriteRegisterRequest(len: uint16,header: ModbusTCP_TransportHeader) = record {
|
||||||
referenceNumber: uint16;
|
referenceNumber: uint16;
|
||||||
andMask: uint16;
|
andMask: uint16;
|
||||||
|
@ -323,8 +358,8 @@ type ModbusTCP_ResponsePDU = record {
|
||||||
WRITE_SINGLE_REGISTER -> writeSingleRegister: WriteSingleRegisterResponse(header.len-2,header);
|
WRITE_SINGLE_REGISTER -> writeSingleRegister: WriteSingleRegisterResponse(header.len-2,header);
|
||||||
READ_EXCEPTION_STATUS -> readExceptionStatus: ReadExceptionStatusResponse(header.len-2,header);
|
READ_EXCEPTION_STATUS -> readExceptionStatus: ReadExceptionStatusResponse(header.len-2,header);
|
||||||
FORCE_MULTIPLE_COILS -> forceMultipleCoils: ForceMultipleCoilsResponse(header.len-2,header);
|
FORCE_MULTIPLE_COILS -> forceMultipleCoils: ForceMultipleCoilsResponse(header.len-2,header);
|
||||||
READ_GENERAL_REFERENCE -> readGeneralReference: ReadGeneralReferenceResponse(header.len-2);
|
READ_GENERAL_REFERENCE -> readGeneralReference: ReadGeneralReferenceResponse(header.len-2,header);
|
||||||
WRITE_GENERAL_REFERENCE -> writeGeneralReference: WriteGeneralReferenceResponse(header.len-2);
|
WRITE_GENERAL_REFERENCE -> writeGeneralReference: WriteGeneralReferenceResponse(header.len-2,header);
|
||||||
MASK_WRITE_REGISTER -> maskWriteRegister: MaskWriteRegisterResponse(header.len-2,header);
|
MASK_WRITE_REGISTER -> maskWriteRegister: MaskWriteRegisterResponse(header.len-2,header);
|
||||||
READ_WRITE_REGISTERS -> readWriteRegisters: ReadWriteRegistersResponse(header.len-2,header);
|
READ_WRITE_REGISTERS -> readWriteRegisters: ReadWriteRegistersResponse(header.len-2,header);
|
||||||
READ_FIFO_QUEUE -> readFIFOQueue: ReadFIFOQueueResponse(header.len-2,header);
|
READ_FIFO_QUEUE -> readFIFOQueue: ReadFIFOQueueResponse(header.len-2,header);
|
||||||
|
@ -450,18 +485,31 @@ deliver: bool =$context.flow.deliver_ForceMultiCoilsRes(header.tid,header.pid,he
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
type ReadGeneralReferenceResponse(len: uint16) = record {
|
|
||||||
|
###RESPONSE FC=20
|
||||||
|
type ReadGeneralReferenceResponse(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
||||||
byteCount: uint8;
|
byteCount: uint8;
|
||||||
references: bytestring &length = byteCount;
|
#references: bytestring &length = byteCount;
|
||||||
} &length = len;
|
#Dina modified
|
||||||
|
references:ReferenceResponse (header) [] &until($input.length()==0) &length=byteCount;
|
||||||
|
} &length = len,
|
||||||
|
&let{
|
||||||
|
deliver: bool =$context.flow.deliver_ReadReferenceRes(header.tid,header.pid,header.uid,header.fc,byteCount,references);
|
||||||
|
};
|
||||||
|
|
||||||
type WriteGeneralReferenceResponse(len: uint16) = record {
|
###RESPONSE FC=21
|
||||||
|
type WriteGeneralReferenceResponse(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
||||||
byteCount: uint8;
|
byteCount: uint8;
|
||||||
references: ReferenceWithData[] &until($input.length() == 0) &length = byteCount;
|
references: ReferenceWithData(header)[] &until($input.length() == 0) &length = byteCount;
|
||||||
} &length = len;
|
} &length = len,
|
||||||
|
&let {
|
||||||
|
deliver: bool =$context.flow.deliver_WriteReferenceRes(header.tid,header.pid,header.uid,header.fc,byteCount,references);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
###RESPONSE FC=22
|
|
||||||
|
###RESPOeSE FC=22
|
||||||
type MaskWriteRegisterResponse(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
type MaskWriteRegisterResponse(len: uint16,header:ModbusTCP_TransportHeader) = record {
|
||||||
referenceNumber: uint16;
|
referenceNumber: uint16;
|
||||||
andMask: uint16;
|
andMask: uint16;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue