靶机服务端(适用于Linux系统控制靶机的情况)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

573 lines
22 KiB

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.BACnet;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace EGFramework{
public class EGBacnet : IEGFramework, IModule,IProtocolSend,IProtocolReceived
{
public BacnetClient BacnetClient;
// All the present Bacnet Device List
public Dictionary<uint,BacnetAddress> DevicesList = new Dictionary<uint,BacnetAddress>();
public Encoding StringEncoding { set; get; } = Encoding.ASCII;
public ConcurrentQueue<ResponseMsg> ResponseMsgs { set; get; } = new ConcurrentQueue<ResponseMsg>();
public void Init()
{
this.EGRegisterSendAction(request=>{
if(request.protocolType == ProtocolType.Bacnet){
if(request.req.ToProtocolData() != "" && request.req.ToProtocolData() != null){
this.SendStringData(request.sender,request.req.ToProtocolData());
}
if(request.req.ToProtocolByteData().Length > 0 && request.req.ToProtocolByteData() != null){
this.SendByteData(request.sender,request.req.ToProtocolByteData());
}
}
});
StartIPV4();
}
public void StartIPV4(int port = 0xBAC0)
{
// Bacnet on UDP/IP/Ethernet
BacnetClient = new BacnetClient(new BacnetIpUdpProtocolTransport(port, false));
BacnetClient.Start(); // go
BacnetClient.OnIam += new BacnetClient.IamHandler(OnIam);
BacnetClient.WhoIs();
// Or Bacnet Ethernet
// bacnet_client = new BacnetClient(new BacnetEthernetProtocolTransport("Connexion au réseau local"));
// Send WhoIs in order to get back all the Iam responses :
/* Optional Remote Registration as A Foreign Device on a BBMD at @192.168.1.1 on the default 0xBAC0 port
bacnet_client.RegisterAsForeignDevice("192.168.1.1", 60);
Thread.Sleep(20);
bacnet_client.RemoteWhoIs("192.168.1.1");
*/
}
public void StartIPV6(int port = 0xBAC0){
//Bacnet on IPV6
BacnetClient = new BacnetClient(new BacnetIpV6UdpProtocolTransport(port));
BacnetClient.Start(); // go
BacnetClient.OnIam += new BacnetClient.IamHandler(OnIam);
BacnetClient.WhoIs();
}
public void StartMSTP(string serialPort = "COM4",int baudRate = 38400){
// Bacnet Mstp on COM4 à 38400 bps, own master id 8
BacnetClient = new BacnetClient(new BacnetMstpProtocolTransport(serialPort, baudRate, 8));
BacnetClient.Start(); // go
BacnetClient.OnIam += new BacnetClient.IamHandler(OnIam);
BacnetClient.WhoIs();
}
public void OnIam(BacnetClient sender, BacnetAddress adr, uint device_id, uint max_apdu, BacnetSegmentations segmentation, ushort vendor_id)
{
lock (DevicesList)
{
// Not already in the list
if(DevicesList.ContainsKey(device_id)){
DevicesList[device_id]=adr;
}else{
DevicesList.Add(device_id,adr); // add it
}
if(!IsWaitForIam){
WaitForIamResponse();
}
}
}
public bool IsWaitForIam { set; get; } = false;
public async void WaitForIamResponse(){
IsWaitForIam = true;
await Task.Delay(2000);
EG.Print("-----Get device----");
string serializeData = JsonConvert.SerializeObject(new EGBacnetWhoIsResponse(DevicesList.Keys.ToList()));
this.ResponseMsgs.Enqueue(new ResponseMsg(serializeData,StringEncoding.GetBytes(serializeData),"Who Is",ProtocolType.Bacnet));
IsWaitForIam = false;
}
public bool ReadProperty(BacnetAddress bacnetAddress, EGBacnetRequest bacnetData, out IList<BacnetValue> Value)
{
IList<BacnetValue> NoScalarValue;
Value = new List<BacnetValue>();
// Property Read
if (BacnetClient.ReadPropertyRequest(bacnetAddress, new BacnetObjectId(bacnetData.ObjectTypes, bacnetData.RegisterAddress), bacnetData.PropertyIds, out NoScalarValue)==false)
return false;
Value = NoScalarValue;
return true;
}
public bool WriteProperty(BacnetAddress bacnetAddress,EGBacnetRequest bacnetData)
{
// Property Write
BacnetValue[] NoScalarValue = { new BacnetValue(bacnetData.Value) };
//GD.Print("ValueType is " + bacnetData.ValueType+"|" +bacnetData.Value.GetType());
if (BacnetClient.WritePropertyRequest(bacnetAddress, new BacnetObjectId(bacnetData.ObjectTypes, bacnetData.RegisterAddress), bacnetData.PropertyIds, NoScalarValue) == false)
return false;
return true;
}
public bool ExecuteBacnetData(EGBacnetRequest bacnetRequest){
bool executeResult = false;
EG.Print("Execute bacnet request");
if(bacnetRequest.OperateCode == EGBacnetOperateCode.WhoIsRequest){
EG.Print("Request for Who Is");
BacnetClient.WhoIs();
return true;
}
if(!DevicesList.ContainsKey(bacnetRequest.DeviceId)){
return false;
}
BacnetAddress address = DevicesList[bacnetRequest.DeviceId];
IList<BacnetValue> bacnetValueQuery = null;
switch(bacnetRequest.OperateCode){
case EGBacnetOperateCode.ReadPropertyRequest:
executeResult = ReadProperty(address,bacnetRequest,out bacnetValueQuery);
break;
case EGBacnetOperateCode.WritePropertyRequest:
executeResult = WriteProperty(address,bacnetRequest);
break;
}
EGBacnetResponse response = new EGBacnetResponse(bacnetRequest,bacnetValueQuery);
response.IsSuccess = executeResult;
string serializeData = JsonConvert.SerializeObject(response);
this.ResponseMsgs.Enqueue(new ResponseMsg(serializeData,StringEncoding.GetBytes(serializeData),bacnetRequest.DeviceId.ToString(),ProtocolType.Bacnet));
return executeResult;
}
public EGBacnetWhoIsResponse WhoIs(){
return new EGBacnetWhoIsResponse(DevicesList.Keys.ToList());
}
public EGBacnetResponse ReadRegisterProperty(EGBacnetRequest bacnetRequest){
bool executeResult = false;
try
{
BacnetAddress address = DevicesList[bacnetRequest.DeviceId];
IList<BacnetValue> bacnetValueQuery = null;
switch(bacnetRequest.OperateCode){
case EGBacnetOperateCode.ReadPropertyRequest:
executeResult = ReadProperty(address,bacnetRequest,out bacnetValueQuery);
break;
}
EG.Print(bacnetValueQuery[0].Value.GetType());
EGBacnetResponse response = new EGBacnetResponse(bacnetRequest,bacnetValueQuery);
response.IsSuccess = executeResult;
return response;
}
catch (System.Exception e)
{
EGBacnetResponse response = new EGBacnetResponse(bacnetRequest);
response.IsSuccess = executeResult;
response.FailedReason = e.ToString();
return response;
}
}
public EGBacnetResponse WriteRegisterProperty(EGBacnetRequest bacnetRequest){
bool executeResult = false;
try
{
if(bacnetRequest.ValueType != BacnetApplicationTags.BACNET_APPLICATION_TAG_NULL){
bacnetRequest.Value = bacnetRequest.Value.ConvertBacnetValueType(bacnetRequest.ValueType);
}
EG.Print(bacnetRequest.Value.GetType());
BacnetAddress address = DevicesList[bacnetRequest.DeviceId];
switch(bacnetRequest.OperateCode){
case EGBacnetOperateCode.WritePropertyRequest:
executeResult = WriteProperty(address,bacnetRequest);
break;
}
EGBacnetResponse response = new EGBacnetResponse(bacnetRequest);
response.IsSuccess = executeResult;
return response;
}
catch (System.Exception e)
{
EGBacnetResponse response = new EGBacnetResponse(bacnetRequest);
response.IsSuccess = executeResult;
response.FailedReason = e.ToString();
return response;
}
}
public EGBacnetResponseReadMulti ReadRegisterMulti(EGBacnetRequestReadMulti bacnetRequest){
bool executeResult = false;
try
{
if(!DevicesList.ContainsKey(bacnetRequest.DeviceId)){
return new EGBacnetResponseReadMulti(){
FailedReason = "Device " + bacnetRequest.DeviceId + " is offline!"
};
}
BacnetAddress address = DevicesList[bacnetRequest.DeviceId];
List<EGBacnetRegisterValueInfo> resultSet = new List<EGBacnetRegisterValueInfo>();
switch(bacnetRequest.OperateCode){
case EGBacnetOperateCode.ReadMultiRequest:
foreach(EGBacnetRegisterInfo info in bacnetRequest.RegisterInfos){
EGBacnetRegisterValueInfo result = ReadRegisterOne(address,info);
resultSet.Add(result);
}
executeResult = true;
break;
}
EGBacnetResponseReadMulti response = new EGBacnetResponseReadMulti(resultSet);
response.IsSuccess = executeResult;
return response;
}
catch (System.Exception e)
{
return new EGBacnetResponseReadMulti(){
FailedReason = e.ToString()
};
}
}
public EGBacnetRegisterValueInfo ReadRegisterOne(BacnetAddress bacnetAddress, EGBacnetRegisterInfo registerInfo){
EGBacnetRegisterValueInfo value = new EGBacnetRegisterValueInfo(){
ObjectTypes = registerInfo.ObjectTypes,
RegisterAddress = registerInfo.RegisterAddress,
PropertyIds = registerInfo.PropertyIds
};
IList<BacnetValue> NoScalarValue;
try
{
bool IsSuccess = BacnetClient.ReadPropertyRequest(bacnetAddress, new BacnetObjectId(registerInfo.ObjectTypes, registerInfo.RegisterAddress), registerInfo.PropertyIds, out NoScalarValue);
if(IsSuccess){
value.IsSuccess = true;
value.Value = NoScalarValue[0];
}
}
catch (System.Exception e)
{
EG.Print(e);
throw;
}
return value;
}
public void SendByteData(string destination, byte[] data)
{
try
{
string DataJson = StringEncoding.GetString(data);
SendStringData(destination,DataJson);
}
catch (System.Exception)
{
throw;
}
}
public void SendStringData(string destination, string data)
{
try
{
EGBacnetRequest bacnetData = JsonConvert.DeserializeObject<EGBacnetRequest>(data);
ExecuteBacnetData(bacnetData);
}
catch (System.Exception e)
{
EG.Print("Error:"+e);
throw;
}
}
public void SetEncoding(Encoding textEncoding)
{
this.StringEncoding = textEncoding;
}
public ConcurrentQueue<ResponseMsg> GetReceivedMsg()
{
return this.ResponseMsgs;
}
public IArchitecture GetArchitecture()
{
return EGArchitectureImplement.Interface;
}
}
#region Who Is
public class EGBacnetWhoIsResponse : IResponse,IRequest
{
public string FunctionCode { set; get; } = "WhoIsResponse";
public List<uint> DevicesList = new List<uint>();
public EGBacnetWhoIsResponse(){
}
public EGBacnetWhoIsResponse(List<uint> devicesList){
this.DevicesList = devicesList;
}
public bool TrySetData(string protocolData, byte[] protocolBytes)
{
try
{
EGBacnetWhoIsResponse response = JsonConvert.DeserializeObject<EGBacnetWhoIsResponse>(protocolData);
if(response.FunctionCode != FunctionCode){
return false;
}
this.DevicesList = response.DevicesList;
//throw new System.NotImplementedException();
return true;
}
catch (System.Exception e)
{
EG.Print("Who is error:"+ e);
return false;
}
}
public string ToProtocolData()
{
return JsonConvert.SerializeObject(this,Formatting.Indented);
}
public byte[] ToProtocolByteData()
{
return null;
}
}
#endregion
#region Read&Write One Register
public class EGBacnetRequest : IRequest,IResponse{
public string FunctionCode { set; get; } = "OperateRequest";
public EGBacnetOperateCode OperateCode { set; get; }
public uint DeviceId { set; get; }
public BacnetObjectTypes ObjectTypes { set; get; }
public uint RegisterAddress { set; get; }
public BacnetPropertyIds PropertyIds { set; get; }
public object Value { set; get; }
public BacnetApplicationTags ValueType { set; get; }
public byte[] ToProtocolByteData()
{
return null;
}
public string ToProtocolData()
{
return JsonConvert.SerializeObject(this,Formatting.Indented);
}
public bool TrySetData(string protocolData, byte[] protocolBytes)
{
try
{
//GD.Print("Init Request");
EGBacnetRequest request = JsonConvert.DeserializeObject<EGBacnetRequest>(protocolData);
if(request.FunctionCode != FunctionCode){
return false;
}
//GD.Print("OperateCode is " + request.OperateCode);
this.OperateCode = request.OperateCode;
this.DeviceId = request.DeviceId;
this.ObjectTypes = request.ObjectTypes;
this.RegisterAddress = request.RegisterAddress;
this.PropertyIds = request.PropertyIds;
this.Value = request.Value;
this.ValueType = request.ValueType;
return true;
}
catch (System.Exception e)
{
EG.Print("Error:"+e);
return false;
}
}
}
public class EGBacnetResponse : IResponse,IRequest
{
public string FunctionCode { set; get; } = "OperateResponse";
public bool IsSuccess { set; get; } = false;
public EGBacnetRequest Request { set; get; }
public IList<BacnetValue> ValueQuery { set; get; }
public string FailedReason { set; get; }
public EGBacnetResponse(){
}
public EGBacnetResponse(EGBacnetRequest request){
this.Request = request;
}
public EGBacnetResponse(EGBacnetRequest request,IList<BacnetValue> values){
this.Request = request;
this.ValueQuery = values;
}
public bool TrySetData(string protocolData, byte[] protocolBytes)
{
try
{
EGBacnetResponse response = JsonConvert.DeserializeObject<EGBacnetResponse>(protocolData);
if(response.FunctionCode != FunctionCode){
return false;
}
this.IsSuccess = response.IsSuccess;
this.Request = response.Request;
this.ValueQuery = response.ValueQuery;
return true;
}
catch (System.Exception)
{
return false;
}
//throw new System.NotImplementedException();
}
public string ToProtocolData()
{
return JsonConvert.SerializeObject(this,Formatting.Indented);
}
public byte[] ToProtocolByteData()
{
return null;
}
}
#endregion
#region Multi Operate
public class EGBacnetRequestReadMulti : IRequest,IResponse{
public string FunctionCode { set; get; } = "ReadMultiRequest";
public EGBacnetOperateCode OperateCode { set; get; }
public uint DeviceId { set; get; }
public List<EGBacnetRegisterInfo> RegisterInfos { set; get; } = new List<EGBacnetRegisterInfo>();
public byte[] ToProtocolByteData()
{
return null;
}
public string ToProtocolData()
{
return JsonConvert.SerializeObject(this,Formatting.Indented);
}
public bool TrySetData(string protocolData, byte[] protocolBytes)
{
try
{
//GD.Print("Init Request");
EGBacnetRequestReadMulti request = JsonConvert.DeserializeObject<EGBacnetRequestReadMulti>(protocolData);
if(request.FunctionCode != FunctionCode){
return false;
}
//GD.Print("OperateCode is " + request.OperateCode);
this.OperateCode = request.OperateCode;
this.DeviceId = request.DeviceId;
this.RegisterInfos = request.RegisterInfos;
return true;
}
catch (System.Exception e)
{
EG.Print("Error:"+e);
return false;
}
}
}
public class EGBacnetResponseReadMulti : IResponse,IRequest
{
public string FunctionCode { set; get; } = "ReadMultiResponse";
public bool IsSuccess { set; get; } = false;
public List<EGBacnetRegisterValueInfo> RegisterInfos { set; get; } = new List<EGBacnetRegisterValueInfo>();
public string FailedReason { set; get; }
public EGBacnetResponseReadMulti(){}
public EGBacnetResponseReadMulti(List<EGBacnetRegisterValueInfo> valueSet){
this.RegisterInfos = valueSet;
}
public bool TrySetData(string protocolData, byte[] protocolBytes)
{
try
{
EGBacnetResponseReadMulti response = JsonConvert.DeserializeObject<EGBacnetResponseReadMulti>(protocolData);
if(response.FunctionCode != FunctionCode){
FailedReason = "[Error] FunctionCode is error!";
return false;
}
this.IsSuccess = response.IsSuccess;
this.RegisterInfos = response.RegisterInfos;
this.FailedReason = response.FailedReason;
return true;
}
catch (System.Exception e)
{
EG.Print("Error:"+e);
return false;
}
//throw new System.NotImplementedException();
}
public string ToProtocolData()
{
return JsonConvert.SerializeObject(this,Formatting.Indented);
}
public byte[] ToProtocolByteData()
{
return null;
}
}
public struct EGBacnetRegisterInfo{
public BacnetObjectTypes ObjectTypes { set; get; }
public uint RegisterAddress { set; get; }
public BacnetPropertyIds PropertyIds { set; get; }
}
public struct EGBacnetRegisterValueInfo{
public BacnetObjectTypes ObjectTypes { set; get; }
public uint RegisterAddress { set; get; }
public BacnetPropertyIds PropertyIds { set; get; }
public bool IsSuccess { set; get; }
public BacnetValue Value{ set; get; }
}
#endregion
public enum EGBacnetOperateCode{
ReadPropertyRequest = 0,
WritePropertyRequest = 1,
WhoIsRequest = 2,
ReadMultiRequest = 3,
}
public static class CanGetEGBacnetExtension{
public static EGBacnet EGBacnet(this IEGFramework self){
return self.GetModule<EGBacnet>();
}
public static object ConvertBacnetValueType(this object value,BacnetApplicationTags valueType){
object resultValue = value;
switch(valueType){
case BacnetApplicationTags.BACNET_APPLICATION_TAG_BOOLEAN:
resultValue = Convert.ToBoolean(value);
break;
case BacnetApplicationTags.BACNET_APPLICATION_TAG_UNSIGNED_INT:
resultValue = Convert.ToUInt32(value);
break;
case BacnetApplicationTags.BACNET_APPLICATION_TAG_SIGNED_INT:
resultValue = Convert.ToInt32(value);
break;
case BacnetApplicationTags.BACNET_APPLICATION_TAG_REAL:
resultValue = Convert.ToSingle(value);
break;
case BacnetApplicationTags.BACNET_APPLICATION_TAG_DOUBLE:
resultValue = Convert.ToDouble(value);
break;
}
return resultValue;
}
}
}