-- FA Control Network Ver. 2.00 do flnet_proto = Proto("FL-net","FA Control Network") TcdStr = { [65000] = "Token", [65001] = "Cyclic", [65002] = "Participation request", [65003] = "Byte block read(request)", [65004] = "Byte block write(request)", [65005] = "Word block read(request)", [65006] = "Word block write(request)", [65007] = "Network parameter read(request)", [65008] = "Network parameter write(request)", [65009] = "Stop command(request)", [65010] = "Operation command(request)", [65011] = "Profile read(request)", [65012] = "Trigger", [65013] = "Log data read(request)", [65014] = "Log clear(request)", [65015] = "Message return(request)", [65016] = "Vendor specific message(request)", [65203] = "Byte block read(response)", [65204] = "Byte block write(response)", [65205] = "Word block read(response)", [65206] = "Word block write(response)", [65207] = "Network parameter read(response)", [65208] = "Network parameter write(response)", [65209] = "Stop command(response)", [65210] = "Operation command(response)", [65211] = "Profile read(response)", [65213] = "Log data read(response)", [65214] = "Log data clear(response)", [65215] = "Message return(response)", [65216] = "Vendor specific message(response)" } local AckStr = { [0] = "", [1] = ", ACK" } local f_h_type = ProtoField.string("fl-net.h_type","H_TYPE") local f_tfl = ProtoField.uint32("fl-net.tfl", "TFL ",base.DEC) local f_sa = ProtoField.uint32("fl-net.sa", "SA ",base.HEX) local f_sna = ProtoField.uint32("fl-net.sa.sna", "SNA",base.DEC,nil,0xFF) local f_da = ProtoField.uint32("fl-net.da", "DA ",base.HEX) local f_dna = ProtoField.uint32("fl-net.da.dna", "DNA",base.DEC,nil,0xFF) local f_v_seq = ProtoField.uint32("fl-net.v_seq", "V_SEQ ",base.DEC) local f_seq = ProtoField.uint32("fl-net.seq", "SEQ ",base.DEC) local f_m_ctl = ProtoField.uint32("fl-net.m_ctl", "M_CTL ",base.HEX) local f_m_ctl_bct = ProtoField.uint32("fl-net.m_ctl.bct","BCT",base.DEC,nil,0x01000000) local f_m_ctl_ppt = ProtoField.uint32("fl-net.m_ctl.ppt","PPT",base.DEC,nil,0x02000000) local f_m_ctl_rpl = ProtoField.uint32("fl-net.m_ctl.rpl","RPL",base.DEC,nil,0x08000000) local f_uls = ProtoField.uint16("fl-net.uls", "ULS ",base.HEX) local f_uls_run = ProtoField.uint16("fl-net.uls.run", "RUN/STOP ",base.DEC,nil,0x8000) local f_uls_alerm = ProtoField.uint16("fl-net.uls.alerm", "ALARM ",base.DEC,nil,0x4000) local f_uls_warn = ProtoField.uint16("fl-net.uls.warnning", "WARNNING ",base.DEC,nil,0x2000) local f_uls_ecode = ProtoField.uint16("fl-net.uls.u_err_code","U_ERR_CODE",base.DEC,nil,0x0FFF) local f_m_sz = ProtoField.uint16("fl-net.m_sz", "M_SZ ",base.DEC_HEX) local f_m_add = ProtoField.uint32("fl-net.m_add", "M_ADD ",base.DEC_HEX) local f_mft = ProtoField.uint8("fl-net.mft", "MFT ",base.DEC) local f_m_rlt = ProtoField.uint8("fl-net.m_rlt", "M_RLT ",base.DEC) local f_tcd = ProtoField.uint16("fl-net.tcd", "TCD ",base.DEC,TcdStr) local f_ver = ProtoField.uint16("fl-net.ver", "VER ",base.DEC) local f_c_ad1 = ProtoField.uint16("fl-net.c_ad1", "C_AD1 ",base.DEC_HEX) local f_c_sz1 = ProtoField.uint16("fl-net.c_sz1", "C_SZ1 ",base.DEC_HEX) local f_c_ad2 = ProtoField.uint16("fl-net.c_ad2", "C_AD2 ",base.DEC_HEX) local f_c_sz2 = ProtoField.uint16("fl-net.c_sz2", "C_SZ2 ",base.DEC_HEX) local f_mode = ProtoField.uint16("fl-net.mode", "MODE ",base.HEX) local f_mode_token = ProtoField.uint16("fl-net.mode.token","TOKEN",base.DEC,nil,0x8000) local f_mode_major = ProtoField.uint16("fl-net.mode.major","MAJOR",base.DEC,nil,0x0F00) local f_mode_minor = ProtoField.uint16("fl-net.mode.minor","MINOR",base.DEC,nil,0x00F0) local f_p_type = ProtoField.uint8("fl-net.p_type", "P_TYPE",base.DEC) local f_pri = ProtoField.uint8("fl-net.pri", "PRI ",base.DEC) local f_cbn = ProtoField.uint8("fl-net.cbn", "CBN ",base.DEC) local f_tbn = ProtoField.uint8("fl-net.tbn", "TBN ",base.DEC) local f_bsize = ProtoField.uint16("fl-net.bsize", "BSIZE ",base.DEC_HEX) local f_lks = ProtoField.uint8("fl-net.lks", "LKS ",base.HEX) local f_lks_ovlp = ProtoField.uint8("fl-net.lks.add_ovlp", "Address overlap detection ",base.DEC,nil,0x80) local f_lks_comp = ProtoField.uint8("fl-net.lks.cm_comp", "Common memory Setting complete ",base.DEC,nil,0x40) local f_lks_valid = ProtoField.uint8("fl-net.lks.cm_valid", "Common memory data valid notification",base.DEC,nil,0x20) local f_lks_err = ProtoField.uint8("fl-net.lks.upper_err","Upper layer operation signal error ",base.DEC,nil,0x10) local f_tw = ProtoField.uint8("fl-net.tw", "TW ",base.DEC) local f_rct = ProtoField.uint16("fl-net.rct", "RCT ",base.DEC) local f_cm1 = ProtoField.bytes("fl-net.cm1","Common memory 1",base.HEX) local f_cm2 = ProtoField.bytes("fl-net.cm2","Common memory 2",base.HEX) local f_msg = ProtoField.bytes("fl-net.msg","Message",base.HEX) local f_ndn = ProtoField.string("fl-net.ndn","NDN") local f_vdn = ProtoField.string("fl-net.vdn","VDN") local f_msn = ProtoField.string("fl-net.msn","MSN") local f_vname = ProtoField.string("fl-net.vname","VNAME") local f_scode = ProtoField.bytes("fl-net.scode","SCODE",base.HEX) flnet_proto.fields = { f_h_type,f_tfl,f_sa,f_sna,f_da,f_dna,f_v_seq,f_seq, f_m_ctl,f_m_ctl_bct,f_m_ctl_ppt,f_m_ctl_rpl, f_uls,f_uls_run,f_uls_alerm,f_uls_warn,f_uls_ecode, f_m_sz,f_m_add,f_mft,f_m_rlt,f_tcd,f_ver, f_c_ad1,f_c_sz1,f_c_ad2,f_c_sz2, f_mode,f_mode_token,f_mode_major,f_mode_minor, f_p_type,f_pri,f_cbn,f_tbn,f_bsize, f_lks,f_lks_ovlp,f_lks_comp,f_lks_valid,f_lks_err, f_tw,f_rct,f_cm1,f_cm2,f_msg,f_ndn,f_vdn,f_msn,f_vname,f_scode } function flnet_proto.dissector(buf,pinfo,root) if (buf(0,4):string() == "FACN") then local tree = root:add(buf(),"FA Control Network") local sna = buf(11,1):uint() local dna = buf(15,1):uint() local m_ctl_rpl = mask(shr(buf(24,1):uint(),3),0x1) local tcd = buf(40,2):uint() local c_ad1 = buf(44,2):uint() local c_sz1 = buf(46,2):uint() local c_ad2 = buf(48,2):uint() local c_sz2 = buf(50,2):uint() local cbn = buf(56,1):uint() local len = buf(58,2):uint() - 0x40 if (TcdStr[tcd] == nil) then if (tcd >= 10000) and (tcd <= 59999) then TcdStr[tcd] = "Transparent message" else TcdStr[tcd] = "Reserved" end end if (tcd == 65001) then info_str = string.format("%3d<=%3d, TCD: %d(%s)%s, CBN/TBN: %d/%d",dna,sna,tcd,TcdStr[tcd],AckStr[m_ctl_rpl],buf(56,1):uint(),buf(57,1):uint()) else info_str = string.format("%3d<=%3d, TCD: %d(%s)",dna,sna,tcd,TcdStr[tcd]) end tree:add(f_h_type,buf(0,4)) tree:add(f_tfl, buf(4,4)) local subtree1 = tree:add(f_sa,buf(8,4)) subtree1:add(f_sna,buf(8,4)) local subtree2 = tree:add(f_da,buf(12,4)) subtree2:add(f_dna,buf(12,4)) tree:add(f_v_seq,buf(16,4)) tree:add(f_seq, buf(20,4)) local subtree3 = tree:add(f_m_ctl,buf(24,4)) subtree3:add(f_m_ctl_bct,buf(24,4)) subtree3:add(f_m_ctl_ppt,buf(24,4)) subtree3:add(f_m_ctl_rpl,buf(24,4)) local subtree4 = tree:add(f_uls,buf(28,2)) subtree4:add(f_uls_run, buf(28,2)) subtree4:add(f_uls_alerm,buf(28,2)) subtree4:add(f_uls_warn, buf(28,2)) subtree4:add(f_uls_ecode,buf(28,2)) tree:add(f_m_sz, buf(30,2)) tree:add(f_m_add,buf(32,4)) tree:add(f_mft, buf(36,1)) tree:add(f_m_rlt,buf(37,1)) tree:add(f_tcd, buf(40,2)) tree:add(f_ver, buf(42,2)) tree:add(f_c_ad1,buf(44,2)) tree:add(f_c_sz1,buf(46,2)) tree:add(f_c_ad2,buf(48,2)) tree:add(f_c_sz2,buf(50,2)) local subtree5 = tree:add(f_mode,buf(52,2)) subtree5:add(f_mode_token,buf(52,2)) subtree5:add(f_mode_major,buf(52,2)) subtree5:add(f_mode_minor,buf(52,2)) tree:add(f_p_type,buf(54,1)) tree:add(f_pri, buf(55,1)) tree:add(f_cbn, buf(56,1)) tree:add(f_tbn, buf(57,1)) tree:add(f_bsize, buf(58,2)) local subtree6 = tree:add(f_lks,buf(60,1)) subtree6:add(f_lks_ovlp, buf(60,1)) subtree6:add(f_lks_comp, buf(60,1)) subtree6:add(f_lks_valid,buf(60,1)) subtree6:add(f_lks_err, buf(60,1)) tree:add(f_tw, buf(61,1)) tree:add(f_rct,buf(62,2)) local idx = 0x40 local sz = len if (tcd==65001) then local sz1 = c_sz1 * 2 local sz2 = c_sz2 * 2 if (m_ctl_rpl ~= 0) then local a_sz = dissector_ack(buf(idx,sz):tvb(),tree) idx = idx + a_sz sz = sz - a_sz end if (cbn==1) then if (sz>0) and (sz1>0) then if (sz1>sz) then local subtree7 = tree:add(f_cm1,buf(idx,sz)) dissector_cmm(buf(idx,sz):tvb(),0,subtree7) idx = idx + sz sz = 0 else local subtree7 = tree:add(f_cm1,buf(idx,sz1)) dissector_cmm(buf(idx,sz1):tvb(),0,subtree7) idx = idx + sz1 sz = sz - sz1 end end if (sz>0) and (sz2>0) then if (sz2>sz) then local subtree8 = tree:add(f_cm2,buf(idx,sz)) dissector_cmm(buf(idx,sz):tvb(),0,subtree8) else local subtree8 = tree:add(f_cm2,buf(idx,sz2)) dissector_cmm(buf(idx,sz2):tvb(),0,subtree8) end end elseif (sz>0) then local ofs = (1024 * (cbn - 1) - sz1) / 2 local subtree8 = tree:add(f_cm2,buf(idx,sz)) dissector_cmm(buf(idx,sz):tvb(),ofs,subtree8) end elseif (tcd==65002) or (tcd==65012) then tree:add(f_ndn,buf(idx,10)) tree:add(f_vdn,buf(idx+10,10)) tree:add(f_msn,buf(idx+20,10)) elseif (tcd==65016) or (tcd==65216) then if (sz>16) then tree:add(f_vname,buf(idx,10)) tree:add(f_scode,buf(idx+10,6)) end idx = idx + 16 sz = sz - 16 tree:add(f_msg,buf(idx,sz)) elseif (sz>0) then tree:add(f_msg,buf(idx,sz)) end pinfo.cols.protocol = "FL-net" pinfo.cols.info = info_str else local data_dis = Dissector.get("data") data_dis:call(buf,pinfo,root) end end local udp_tbl = DissectorTable.get("udp.port") udp_tbl:add(55000,flnet_proto) udp_tbl:add(55001,flnet_proto) udp_tbl:add(55002,flnet_proto) udp_tbl:add(55003,flnet_proto) end function dissector_ack(buf,tree) local idx = 4 local a_num = buf(1,1):uint() local subtree1 = tree:add(buf(0,4 + (a_num * 16)),"ACK Data") local subtree2 = {} subtree1:add(buf(0,1),"ACK.A_VER: ",buf(0,1):uint()) subtree1:add(buf(1,1),"ACK.A_NUM: ",buf(1,1):uint()) for i = 0, a_num - 1 do subtree2[i] = subtree1:add(buf(idx,16),string.format("ACK[%d]",i)) subtree2[i]:add(buf(idx+ 1,1),string.format("ACK[%d].R_STS : %d",i,buf(idx+ 1,1):uint())) subtree2[i]:add(buf(idx+ 2,2),string.format("ACK[%d].R_TCD : %s (%d)",i,TcdStr[buf(idx+2,2):uint()],buf(idx+2,2):uint())) subtree2[i]:add(buf(idx+ 7,1),string.format("ACK[%d].R_NA : %d",i,buf(idx+ 7,1):uint())) subtree2[i]:add(buf(idx+ 8,4),string.format("ACK[%d].R_VSEQ: %d",i,buf(idx+ 8,4):uint())) subtree2[i]:add(buf(idx+12,4),string.format("ACK[%d].R_SEQ : %d",i,buf(idx+12,4):uint())) idx = idx + 16 end return idx end function dissector_cmm(buf,ofs,tree) local idx = 0 local len = buf:len() while (len>0) do tree:add(buf(idx,2),string.format("DATA[%d]: 0x%04x",ofs,buf(idx,2):uint())) ofs = ofs + 1 idx = idx + 2 len = len - 2 end end function shr(val,idx) idx = 2 ^ idx return (val - (val % idx)) / idx end function mask(val,msk) return val % (msk + 1) end