/// <summary> /// Sends a netgram out of this port /// </summary> /// <param name="netgram">The netgram to send</param> public void SendNetgram(OutboundNetgram netgram) { Contract.Requires(_deviceMac.Length == 6); Contract.Requires(netgram.Destination.IsBroadcast() || netgram.Destination.Length == 6); byte[] buffer = new byte[1500]; int lengthOffset = 0; int offset = 0; int length; var destination = netgram.Destination.IsBroadcast() ? _ethernetBroadcastMac : netgram.Destination; // write the destination mac address bytes for (int i = 0; i < 6; i++) { buffer[offset++] = destination[i]; } // write the source mac address bytes for (int i = 0; i < 6; i++) { buffer[offset++] = _deviceMac[i]; } // the next 2 bytes are used for the packet length, so // we skip them until we know what they are lengthOffset = offset; offset += 2; // DSAP and SSAP buffer[offset++] = 0x82; buffer[offset++] = 0x82; // LLC control buffer[offset++] = 0x03; // serialize the netgram content offset = netgram.Content.Serialize(buffer, offset); // now that we have the full packet length, we backfill // the length field length = offset - lengthOffset - 2; buffer.WriteUInt16(lengthOffset, (ushort)length); lock (_device) { _device.SendPacket(buffer, offset); } }
/// <summary> /// Sends a netgram using a supplied route /// </summary> /// <param name="route">The route to send with</param> /// <param name="content">The content to of the netgram to send</param> private void _sendWithRoute(Route route, NetgramContent content) { var destination = content.Destination; byte portId; Mac mac; if (destination.IsGlobalBroadcast()) { // global broadcast content.Header.Destination = Address.GlobalBroadcast; portId = 255; mac = Mac.Broadcast; } else if (destination.IsDirectedlyConnectedBroadcast()) { // broadcast on all directly connected networks content.Header.Destination = null; portId = 255; mac = Mac.Broadcast; } else if (route.NextHop.IsBroadcast()) { // directly attached network content.Header.Destination = null; portId = route.PortId; mac = destination.Mac; } else { // not directly attached content.Header.Destination = destination; portId = route.PortId; mac = route.NextHop; } OutboundNetgram netgram = new OutboundNetgram(); netgram.PortId = portId; netgram.Destination = mac; netgram.Content = content; if (_portManager != null) { _portManager.SendNetgram(netgram); } }
/// <summary> /// Sends a netgram out of this port /// </summary> /// <param name="netgram">The netgram to send</param> public void SendNetgram(OutboundNetgram netgram) { IPEndPoint ep = null; byte[] buffer = new byte[1500]; int offset = 0; BvlcHeader header = new BvlcHeader(); IBvlcMessage message = null; if (netgram.Destination.IsBroadcast()) { ep = IPUtils.MacToIPEndPoint(_bbmdMac); header.Function = FunctionCode.OriginalUnicastNpdu; //header.Function = FunctionCode.OriginalBroadcastNpdu; header.Length = 0; message = new OriginalBroadcastNpduMessage(); } else { ep = IPUtils.MacToIPEndPoint(netgram.Destination); header.Function = FunctionCode.OriginalUnicastNpdu; header.Length = 0; message = new OriginalUnicastNpduMessage(); } offset = header.Serialize(buffer, offset); offset = message.Serialize(buffer, offset); offset = netgram.Content.Serialize(buffer, offset); // patch the length buffer[2] = (byte)(offset << 8); buffer[3] = (byte)(offset); lock (this._lock) { if (_server != null) { _server.Send(ep, buffer, offset); } } }