/// <summary>
/// USE AT OWN RISK!! THIS IS NOT DOCUMENTED BY BECKHOFF AS FAR AS I KNOW
/// You can use this to add a route on the remote target
/// </summary>
/// <param name="amsNetIdSource">The NetID from this device</param>
/// <param name="ipTarget">The IP of the target device</param>
/// <param name="routeName">Route name</param>
/// <param name="address">IP or Hostname</param>
/// <param name="username">Username (default Administrator)</param>
/// <param name="passwd">password (default empty)</param>
/// <returns></returns>
public static void AddRoute(string amsNetIdSource, string ipTarget, string routeName, string address, string username="Administrator", string passwd="")
{
int port = 48899;
AmsNetId netIdSource = new AmsNetId(amsNetIdSource);
byte[] receivemsg = new byte[100];
IEnumerable<byte> message = new List<byte>();
message = message.Concat(new byte[] { 0x03, 0x66, 0x14, 0x71 }); //No idea what it means
message = message.Concat(new byte[] { 0x00, 0x00, 0x00, 0x00 }); //No idea what it means
message = message.Concat(new byte[] { 0x06, 0x00, 0x00, 0x00 }); //No idea what it means
message = message.Concat(netIdSource.Bytes); //AmsNetIdSource
message = message.Concat(new byte[] { 0x10, 0x27 }); //No idea what it means
message = message.Concat(new byte[] { 0x05, 0x00, 0x00, 0x00 }); //No idea what it means
message = message.Concat(new byte[] { 0x0c, 0x00 }); //Routename tag?
message = message.Concat(BitConverter.GetBytes((UInt16)(routeName.Length + 1))); //Length routename + 1
message = message.Concat(routeName.ToAdsBytes()); //Routename
message = message.Concat(new byte[] { 0x07, 0x00 }); //AmsNetIdSource tag?
message = message.Concat(BitConverter.GetBytes((UInt16)(netIdSource.Bytes.Count))); //Length AmsNetId
message = message.Concat(netIdSource.Bytes); //AmsNetId
message = message.Concat(new byte[] { 0x0d, 0x00 }); //Username tag?
message = message.Concat(BitConverter.GetBytes((UInt16)(username.Length + 1))); //Length username + 1
message = message.Concat(username.ToAdsBytes()); //Username
message = message.Concat(new byte[] { 0x02, 0x00 }); //Password tag?
message = message.Concat(BitConverter.GetBytes((UInt16)(passwd.Length + 1))); //Length password + 1
message = message.Concat(passwd.ToAdsBytes()); //Password
message = message.Concat(new byte[] { 0x05, 0x00 }); //Address tag?
message = message.Concat(BitConverter.GetBytes((UInt16)(address.Length + 1))); //Length Address + 1
message = message.Concat(address.ToAdsBytes()); //Address
byte[] sendmsg = message.ToArray<byte>();
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//socket.Bind(new IPEndPoint(IPAddress.Any, port));
socket.Connect(ipTarget, port);
socket.Send(sendmsg);
socket.Receive(receivemsg);
socket.Shutdown(SocketShutdown.Both);
socket.Close();
uint error = BitConverter.ToUInt32(receivemsg, 28);
if (error > 0) throw new AdsException(error);
}