From a671ff942bf100fd18212020ebf30c44cf0a06c1 Mon Sep 17 00:00:00 2001 From: Evan Jeffrey Date: Wed, 7 Oct 2015 20:42:37 -0700 Subject: [PATCH] Import direct ethernet code --- DirectEthernetServer/Adapter.dfm | 935 ++++++++++++++++++ DirectEthernetServer/Adapter.pas | 329 ++++++ DirectEthernetServer/Contexts.pas | 270 +++++ DirectEthernetServer/DirectEthernet.dpr | 35 + DirectEthernetServer/DirectEthernet.res | Bin 0 -> 876 bytes DirectEthernetServer/Errors.pas | 84 ++ DirectEthernetServer/Filters.pas | 174 ++++ DirectEthernetServer/GetMAC.pas | 188 ++++ DirectEthernetServer/LICENSE.txt | 339 +++++++ DirectEthernetServer/ListenThread.pas | 79 ++ DirectEthernetServer/Main.dfm | 298 ++++++ DirectEthernetServer/Main.pas | 571 +++++++++++ DirectEthernetServer/Packets.pas | 83 ++ DirectEthernetServer/Triggers.pas | 114 +++ DirectEthernetServer/link_idle.bmp | Bin 0 -> 822 bytes DirectEthernetServer/link_idle_no_listen.bmp | Bin 0 -> 822 bytes .../link_idle_no_listen_stop.bmp | Bin 0 -> 1334 bytes DirectEthernetServer/link_idle_stop.bmp | Bin 0 -> 1334 bytes DirectEthernetServer/link_rec.bmp | Bin 0 -> 822 bytes DirectEthernetServer/link_rec_stop.bmp | Bin 0 -> 1334 bytes DirectEthernetServer/link_send.bmp | Bin 0 -> 822 bytes DirectEthernetServer/link_send_no_listen.bmp | Bin 0 -> 822 bytes .../link_send_no_listen_stop.bmp | Bin 0 -> 1334 bytes DirectEthernetServer/link_send_rec.bmp | Bin 0 -> 822 bytes DirectEthernetServer/link_send_rec_stop.bmp | Bin 0 -> 1334 bytes DirectEthernetServer/link_send_stop.bmp | Bin 0 -> 1334 bytes DirectEthernetServer/thread_debug.bmp | Bin 0 -> 822 bytes 27 files changed, 3499 insertions(+) create mode 100755 DirectEthernetServer/Adapter.dfm create mode 100755 DirectEthernetServer/Adapter.pas create mode 100755 DirectEthernetServer/Contexts.pas create mode 100755 DirectEthernetServer/DirectEthernet.dpr create mode 100755 DirectEthernetServer/DirectEthernet.res create mode 100755 DirectEthernetServer/Errors.pas create mode 100755 DirectEthernetServer/Filters.pas create mode 100755 DirectEthernetServer/GetMAC.pas create mode 100755 DirectEthernetServer/LICENSE.txt create mode 100755 DirectEthernetServer/ListenThread.pas create mode 100755 DirectEthernetServer/Main.dfm create mode 100755 DirectEthernetServer/Main.pas create mode 100755 DirectEthernetServer/Packets.pas create mode 100755 DirectEthernetServer/Triggers.pas create mode 100755 DirectEthernetServer/link_idle.bmp create mode 100755 DirectEthernetServer/link_idle_no_listen.bmp create mode 100755 DirectEthernetServer/link_idle_no_listen_stop.bmp create mode 100755 DirectEthernetServer/link_idle_stop.bmp create mode 100755 DirectEthernetServer/link_rec.bmp create mode 100755 DirectEthernetServer/link_rec_stop.bmp create mode 100755 DirectEthernetServer/link_send.bmp create mode 100755 DirectEthernetServer/link_send_no_listen.bmp create mode 100755 DirectEthernetServer/link_send_no_listen_stop.bmp create mode 100755 DirectEthernetServer/link_send_rec.bmp create mode 100755 DirectEthernetServer/link_send_rec_stop.bmp create mode 100755 DirectEthernetServer/link_send_stop.bmp create mode 100755 DirectEthernetServer/thread_debug.bmp diff --git a/DirectEthernetServer/Adapter.dfm b/DirectEthernetServer/Adapter.dfm new file mode 100755 index 0000000..beda6f4 --- /dev/null +++ b/DirectEthernetServer/Adapter.dfm @@ -0,0 +1,935 @@ +object AdapterForm: TAdapterForm + Left = 200 + Top = 680 + Width = 630 + Height = 322 + Caption = 'AdapterForm' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + FormStyle = fsMDIChild + OldCreateOrder = False + Position = poDefault + Visible = True + OnCreate = FormCreate + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 13 + object Splitter1: TSplitter + Left = 0 + Top = 222 + Width = 622 + Height = 3 + Cursor = crVSplit + Align = alBottom + end + object ToolPanel: TPanel + Left = 0 + Top = 0 + Width = 622 + Height = 85 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + object Panel5: TPanel + Left = 0 + Top = 0 + Width = 125 + Height = 85 + Align = alLeft + BevelOuter = bvNone + TabOrder = 0 + object Panel12: TPanel + Left = 0 + Top = 42 + Width = 125 + Height = 21 + Align = alTop + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + BorderWidth = 1 + Caption = ' MAC Address: ' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + end + object Panel4: TPanel + Left = 0 + Top = 63 + Width = 125 + Height = 21 + Align = alTop + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + BorderWidth = 1 + Caption = ' Received Packets:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + end + object Panel10: TPanel + Left = 0 + Top = 0 + Width = 125 + Height = 21 + Align = alTop + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + BorderWidth = 1 + Caption = ' Adapter Name:' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 2 + end + object Panel11: TPanel + Left = 0 + Top = 21 + Width = 125 + Height = 21 + Align = alTop + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + BorderWidth = 1 + Caption = ' IP Address: ' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 3 + end + end + object Panel6: TPanel + Left = 125 + Top = 0 + Width = 497 + Height = 85 + Align = alClient + BevelOuter = bvNone + TabOrder = 1 + object MACPanel: TPanel + Left = 0 + Top = 42 + Width = 497 + Height = 21 + Align = alTop + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + BorderWidth = 1 + Caption = ' ' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + end + object RecCountPanel: TPanel + Left = 0 + Top = 63 + Width = 497 + Height = 21 + Align = alTop + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + BorderWidth = 1 + Caption = ' 0' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + end + object ANamePanel: TPanel + Left = 0 + Top = 0 + Width = 497 + Height = 21 + Align = alTop + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + BorderWidth = 1 + Caption = ' ' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 2 + end + object IPPanel: TPanel + Left = 0 + Top = 21 + Width = 497 + Height = 21 + Align = alTop + Alignment = taLeftJustify + BevelInner = bvLowered + BevelOuter = bvNone + BorderWidth = 1 + Caption = ' ' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 3 + end + end + end + object LogPanel: TPanel + Left = 0 + Top = 225 + Width = 622 + Height = 70 + Align = alBottom + BevelOuter = bvLowered + Constraints.MinHeight = 70 + TabOrder = 1 + object Panel7: TPanel + Left = 1 + Top = 1 + Width = 620 + Height = 19 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + object Panel8: TPanel + Left = 0 + Top = 0 + Width = 149 + Height = 19 + Align = alLeft + Alignment = taLeftJustify + Caption = ' Traffic Monitor' + Color = clHighlight + Font.Charset = DEFAULT_CHARSET + Font.Color = clHighlightText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + end + object Panel9: TPanel + Left = 149 + Top = 0 + Width = 471 + Height = 19 + Align = alClient + BevelOuter = bvNone + TabOrder = 1 + DesignSize = ( + 471 + 19) + object LANLogShow: TCheckBox + Left = 4 + Top = 1 + Width = 97 + Height = 17 + Caption = 'show' + TabOrder = 0 + end + object ClrLANLogBtn: TButton + Left = 444 + Top = 2 + Width = 25 + Height = 15 + Anchors = [akTop, akRight] + Caption = 'clr' + TabOrder = 1 + OnClick = ClrLANLogBtnClick + end + end + end + object LANLogMemo: TMemo + Left = 1 + Top = 20 + Width = 620 + Height = 49 + Align = alClient + Font.Charset = OEM_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Terminal' + Font.Style = [] + ParentFont = False + ReadOnly = True + ScrollBars = ssBoth + TabOrder = 1 + end + end + object ConnectionPanel: TPanel + Left = 0 + Top = 85 + Width = 622 + Height = 137 + Align = alClient + BevelOuter = bvLowered + Constraints.MinHeight = 70 + TabOrder = 2 + object Panel1: TPanel + Left = 1 + Top = 1 + Width = 620 + Height = 19 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + object Panel2: TPanel + Left = 0 + Top = 0 + Width = 149 + Height = 19 + Align = alLeft + Alignment = taLeftJustify + Caption = ' Connected Contexts' + Color = clHighlight + Font.Charset = DEFAULT_CHARSET + Font.Color = clHighlightText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + end + object Panel3: TPanel + Left = 149 + Top = 0 + Width = 471 + Height = 19 + Align = alClient + BevelOuter = bvNone + TabOrder = 1 + object FastRefreshCheckBox: TCheckBox + Left = 4 + Top = 1 + Width = 97 + Height = 17 + Caption = 'fast refresh' + TabOrder = 0 + OnClick = FastRefreshCheckBoxClick + end + end + end + object ContextList: TListView + Left = 1 + Top = 20 + Width = 620 + Height = 116 + Align = alClient + Columns = < + item + Caption = 'Context ID' + Width = 112 + end + item + Alignment = taCenter + Caption = 'Sent' + Width = 60 + end + item + Alignment = taCenter + Caption = 'Received' + Width = 60 + end + item + Alignment = taCenter + Caption = 'Buffered' + Width = 60 + end + item + Alignment = taCenter + Caption = 'Source MAC' + Width = 112 + end + item + Alignment = taCenter + Caption = 'Destination MAC' + Width = 112 + end + item + Alignment = taCenter + Caption = 'Ether Type' + Width = 70 + end> + ReadOnly = True + SmallImages = ImageList1 + TabOrder = 1 + ViewStyle = vsReport + end + end + object Timer1: TTimer + Interval = 250 + OnTimer = Timer1Timer + Left = 4 + Top = 125 + end + object ImageList1: TImageList + Left = 36 + Top = 125 + Bitmap = { + 494C01010C000E00040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000004000000001002000000000000040 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000099999900000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000099999900000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C9AB6600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C9AB6600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008989890066666600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008989890066666600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000CEA64200BC880500000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000CEA64200BC880500000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000099999900757575007070700056565600515151004C4C4C00494949006666 + 660093939300CECECE0000000000000000000000000000000000000000000000 + 000099999900757575007070700056565600515151004C4C4C00494949006666 + 660093939300CECECE0000000000000000000000000000000000000000000000 + 0000DDB74D00E0A00000D8970000BA720000AF6C0000A3640000A0630000AA82 + 1D00BCA46B00D8D4C50000000000000000000000000000000000000000000000 + 0000DDB74D00E0A00000D8970000BA720000AF6C0000A3640000A0630000AA82 + 1D00BCA46B00D8D4C5000000000000000000000000000000000000000000A8A8 + A80084848400A5A5A500A0A0A0009E9E9E009999990091919100898989007272 + 72005656560068686800BCBCBC0000000000000000000000000000000000A8A8 + A80084848400A5A5A500A0A0A0009E9E9E009999990091919100898989007272 + 72005656560068686800BCBCBC0000000000000000000000000000000000EAC6 + 5B00EDB00900F7CC4000F4C93A00F7C63300F7BE2E00F4B72900EAB21700DB9D + 0000BC740000A8812800D1C5A90000000000000000000000000000000000EAC6 + 5B00EDB00900F7CC4000F4C93A00F7C63300F7BE2E00F4B72900EAB21700DB9D + 0000BC740000A8812800D1C5A90000000000000000000000000000000000AAAA + AA008C8C8C009C9C9C002F2F2F000000000000000000222222007E7E7E008C8C + 8C008E8E8E006868680068686800D1D1D100000000000000000000000000AAAA + AA008C8C8C009C9C9C002F2F2F000000000000000000222222007E7E7E008C8C + 8C008E8E8E006868680068686800D1D1D100000000000000000000000000EFC9 + 5800F4BE0C00E4C03F00463A13000000000000000000362A0A00D0A12000F4B8 + 1300F4BA1800D18E0000AA7E2700DDD8C700000000000000000000000000EFC9 + 5800F4BE0C00E4C03F00463A13000000000000000000362A0A00D0A12000F4B8 + 1300F4BA1800D18E0000AA7E2700DDD8C7000000000000000000000000000000 + 00009D9D9D001E1B6A00120FAA000E05B600130DAC002A287D00151515007A7A + 7A0093939300919191005B5B5B00969696000000000000000000000000000000 + 00009D9D9D001E1B6A00120FAA000E05B600130DAC002A287D00151515007A7A + 7A0093939300919191005B5B5B00969696000000000000000000000000000000 + 0000E4BC4A0028205D001B139E000E05B6001F11A10056345500281C0000C79B + 1F00F4BD2700F4B92200C4790000C1A86C000000000000000000000000000000 + 0000E4BC4A0028205D001B139E000E05B6001F11A10056345500281C0000C79B + 1F00F4BD2700F4B92200C4790000C1A86C000000000000000000000000000000 + 0000413D91002527C300222EE2000620E5000210D8000707BA00403D91001919 + 190093939300939393007C7C7C00686868000000000000000000000000000000 + 0000413D91002527C300222EE2000620E5000210D8000707BA00403D91001919 + 190093939300939393007C7C7C00686868000000000000000000000000000000 + 0000413D91002628C300222EE2000620E5000210D8000707BA00584774003321 + 0000EFBB2B00F4BB2900E0A40D00B2861E000000000000000000000000000000 + 0000413D91002628C300222EE2000620E5000210D8000707BA00584774003321 + 0000EFBB2B00F4BB2900E0A40D00B2861E00B7B7B700AFAFAF00ADADAD00AAAA + AA000A05A3006264EF001928FF000014F4000017EA000416DD001F1AB9000505 + 05005E5E5E0059595900545454005151510081B1DB007EA8D6007EA7D3007BA6 + CE000905A3006264EF001928FF000014F4000017EA000416DD001F1AB9000505 + 05005E5E5E00595959005454540051515100B7B7B700AFAFAF00ADADAD00AAAA + AA000A05A3006264EF001928FF000014F4000017EA000416DD001F1AB9000605 + 0200CC7D0000C1770000B56F0000AF6C000081B1DB007EA8D6007EA7D3007BA6 + CE000905A3006264EF001928FF000014F4000017EA000416DD001F1AB9000605 + 0200CC7D0000C1770000B56F0000AF6C000084848400848484007C7C7C007575 + 75000C03B700AEAEF900FFFFFF00FFFFFF00FFFFFF00192BEA000E05B6000B0B + 0B00B2B2B200AFAFAF00ADADAD00A8A8A8000077D800007BCE000074C100006E + B7000C03B700AEAEF900FFFFFF00FFFFFF00FFFFFF00192BEA000E05B6000B0B + 0B00B2B2B200AFAFAF00ADADAD00A8A8A80084848400848484007C7C7C007575 + 75000C03B700AEAEF900FFFFFF00FFFFFF00FFFFFF00192BEA000E05B6000E0C + 0800E0C48200DDC38000D8BE7F00D3BA7E000077D800007BCE000074C100006E + B7000C03B700AEAEF900FFFFFF00FFFFFF00FFFFFF00192BEA000E05B6000E0C + 0800E0C48200DDC38000D8BE7F00D3BA7E009191910093939300A3A3A3009B9B + 9B00100BA3008C8CF2004F4FFF00111DFF00212FFF004049E800110CA6005D5D + 5D00000000000000000000000000000000002681E2001F80EF003191F700268B + EF00070AA9008C8CF2004F4FFF00111DFF00212FFF004049E8000B0BAA005D5D + 5D00000000000000000000000000000000009191910093939300A3A3A3009B9B + 9B00100BA3008C8CF2004F4FFF00111DFF00212FFF004049E800110CA6005D5D + 5D00000000000000000000000000000000002681E2001F80EF003191F700268B + EF00070AA9008C8CF2004F4FFF00111DFF00212FFF004049E8000B0BAA005D5D + 5D0000000000000000000000000000000000B5B5B5008C8C8C00A5A5A500A0A0 + A0006663AD003737CB008C8CF200B8BCF9007478F2002B2DC300110F59007D7D + 7D000000000000000000000000000000000072AAEA000978EF004094F9003A8E + F400285ADA003637CC008C8CF200B8BCF9007478F2002A2DC300030E61004178 + A90000000000000000000000000000000000B5B5B5008C8C8C00A5A5A500A0A0 + A0006663AD003737CB008C8CF200B8BCF9007478F2002B2DC300110F59007D7D + 7D000000000000000000000000000000000072AAEA000978EF004094F9003A8E + F400285ADA003637CC008C8CF200B8BCF9007478F2002A2DC300030E61004178 + A90000000000000000000000000000000000D8D8D8009B9B9B0099999900A8A8 + A800A0A0A0006763AE001E19B0000C03B7000B07A2002A2A7E00949494007575 + 75008C8C8C00000000000000000000000000C9D8E800318CED002285F7004596 + F900318BF900305ADC001518B7000C03B7000806A500072498001282EC00006E + B7005087B200000000000000000000000000D8D8D8009B9B9B0099999900A8A8 + A800A0A0A0006763AE001E19B0000C03B7000B07A2002A2A7E00949494007575 + 75008C8C8C00000000000000000000000000C9D8E800318CED002285F7004596 + F900318BF900305ADC001518B7000C03B7000806A500072498001282EC00006E + B7005087B20000000000000000000000000000000000CECECE00A0A0A0008E8E + 8E009E9E9E00A5A5A500A0A0A000A0A0A000A0A0A0009B9B9B00999999007A7A + 7A008E8E8E0000000000000000000000000000000000ADCCEA00328FF2000E76 + F4002A89F7003B91F9003B8CF700348DF900308FF400278AF4001F88F2000072 + BF005589BA0000000000000000000000000000000000CECECE00A0A0A0008E8E + 8E009E9E9E00A5A5A500A0A0A000A0A0A000A0A0A0009B9B9B00999999007A7A + 7A008E8E8E0000000000000000000000000000000000ADCCEA00328FF2000E76 + F4002A89F7003B91F9003B8CF700348DF900308FF400278AF4001F88F2000072 + BF005589BA000000000000000000000000000000000000000000D8D8D800B7B7 + B70099999900898989008E8E8E00878787007F7F7F007F7F7F007C7C7C009393 + 9300000000000000000000000000000000000000000000000000C9D7EA0074AC + ED002A88ED00007AE5000085DD00007ED3000078C900006ED600006ECE004C8A + C400000000000000000000000000000000000000000000000000D8D8D800B7B7 + B70099999900898989008E8E8E00878787007F7F7F007F7F7F007C7C7C009393 + 9300000000000000000000000000000000000000000000000000C9D7EA0074AC + ED002A88ED00007AE5000085DD00007ED3000078C900006ED600006ECE004C8A + C400000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007C7C7C00939393000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000A6CCE004288CE000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007C7C7C00939393000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000A6CCE004288CE000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000ADADAD00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000069A4E000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000ADADAD00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000069A4E000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000CEAD6300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000CEAD6300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000CEA54200BD8C0000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000CEA54200BD8C0000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000DEB54A00E7A50000DE940000BD730000AD6B0000A5630000A5630000AD84 + 1800BDA56B00DED6C60000000000000000000000000000000000000000000000 + 0000DEB54A00E7A50000DE940000BD730000AD6B0000A5630000A5630000AD84 + 1800BDA56B00DED6C60000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000EFC6 + 5A00EFB50800F7CE4200F7CE3900F7C63100F7BD2900F7B52900EFB51000DE9C + 0000BD730000AD842900D6C6AD0000000000000000000000000000000000EFC6 + 5A00EFB50800F7CE4200F7CE3900F7C63100F7BD2900F7B52900EFB51000DE9C + 0000BD730000AD842900D6C6AD00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000EFCE + 5A00F7BD0800FFD64200FFCE4200FFCE4200F7CE3900F7C63100F7BD2100F7BD + 1000F7BD1800D68C0000AD7B2100DEDEC600000000000000000000000000EFCE + 5A00F7BD0800FFD64200FFCE4200FFCE4200F7CE3900F7C63100F7BD2100F7BD + 1000F7BD1800D68C0000AD7B2100DEDEC6000000000000000000000000000000 + 000000000000CFCFCF0040404000000000000000000032323200C1C1C1000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000CFCFCF0040404000000000000000000032323200C1C1C1000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000F7CE5200FFC60800F7BD0800E78C0000DE840000CE7B0000DE940000EFBD + 2100F7BD2100F7BD2100C67B0000C6AD6B000000000000000000000000000000 + 0000F7CE5200FFC60800F7BD0800E78C0000DE840000CE7B0000DE940000EFBD + 2100F7BD2100F7BD2100C67B0000C6AD6B000000000000000000000000000000 + 0000D6D6D600262372001A17B2000E05B700211BBA00605EB3002B2B2B00C1C1 + C100000000000000000000000000000000000000000000000000000000000000 + 0000D6D6D600262372001A17B2000E05B700211BBA00605EB3002B2B2B00C1C1 + C100000000000000000000000000000000000000000000000000000000000000 + 000000000000F7C64200F7B50800000000000000000000000000DEB55200CE84 + 0000EFBD2900F7BD2900E7A50800B58418000000000000000000000000000000 + 000000000000F7C64200F7B50800000000000000000000000000DEB55200CE84 + 0000EFBD2900F7BD2900E7A50800B58418000000000000000000000000000000 + 0000413D91002628C400222EE2000620E5000210D8000707BA005E5BAE003939 + 3900000000000000000000000000000000000000000000000000000000000000 + 0000413D91002628C400222EE2000620E5000210D8000707BA005E5BAE003939 + 390000000000000000000000000000000000B5B5B500ADADAD00ADADAD00ADAD + AD00ADADAD0000000000F7D66B0000000000000000000000000000000000DEBD + 5A00CE7B0000C6730000B56B0000AD6B000084B5DE007BADD6007BA5D6007BA5 + CE007BA5CE0000000000F7D66B0000000000000000000000000000000000DEBD + 5A00CE7B0000C6730000B56B0000AD6B0000B7B7B700AFAFAF00ADADAD00AAAA + AA000A05A3006264EF001928FF000014F4000017EA000416DD001F1AB9000707 + 07000000000000000000000000000000000081B1DB007EA8D6007EA7D3007BA6 + CE000905A3006264EF001928FF000014F4000017EA000416DD001F1AB9000707 + 07000000000000000000000000000000000084848400848484007B7B7B007373 + 73009C9C9C00000000000000000000000000000000009494940000000000E7CE + 8400E7C68400DEC68400DEBD7B00D6BD7B000073DE00007BCE000073C600006B + B5005A94C600000000000000000000000000000000005A8CB500E7E7E700E7CE + 8400E7C68400DEC68400DEBD7B00D6BD7B0084848400848484007C7C7C007575 + 75000C03B700AEAEF900FFFFFF00FFFFFF00FFFFFF00192BEA000E05B7000E0E + 0E00000000000000000000000000000000000077D800007BCE000074C100006E + B7000C03B700AEAEF900FFFFFF00FFFFFF00FFFFFF00192BEA000E05B7000E0E + 0E00000000000000000000000000000000009494940094949400A5A5A5009C9C + 9C0073737300949494000000000000000000000000005A5A5A007B7B7B000000 + 0000000000000000000000000000000000002184E7001884EF003194F700218C + EF000063BD004A8CCE0000000000000000000000000000529C003973AD000000 + 0000000000000000000000000000000000009191910093939300A3A3A3009B9B + 9B00100BA3008C8CF2004F4FFF00111DFF00212FFF004049E800110CA6005D5D + 5D00000000000000000000000000000000002681E2001F80EF003191F700268B + EF00070AA9008C8CF2004F4FFF00111DFF00212FFF004049E8000B0BAA005D5D + 5D0000000000000000000000000000000000B5B5B5008C8C8C00A5A5A500A5A5 + A5009C9C9C007B7B7B00737373006B6B6B006363630073737300737373008484 + 84000000000000000000000000000000000073ADEF00087BEF004294FF00398C + F700298CF7000073D600006BB5000063AD00005A9C00006BBD00006BB500427B + AD0000000000000000000000000000000000B5B5B5008C8C8C00A5A5A500A0A0 + A0006663AD003737CB008C8CF200B8BCF9007478F2002B2DC300110F59007D7D + 7D000000000000000000000000000000000072AAEA000978EF004094F9003A8E + F400285ADA003637CC008C8CF200B8BCF9007478F2002A2DC300030E61004178 + A90000000000000000000000000000000000DEDEDE009C9C9C009C9C9C00ADAD + AD00A5A5A500A5A5A500A5A5A5009C9C9C009C9C9C00949494009C9C9C007373 + 73008C8C8C00000000000000000000000000CEDEEF00318CEF002184F7004294 + FF00318CFF00398CF7003194F700218CF7002184F7001884F7001084F700006B + B5005284B500000000000000000000000000D8D8D8009B9B9B0099999900A8A8 + A800A0A0A0006763AE001E19B0000C03B7000B07A2002A2A7E00949494007575 + 75008C8C8C00000000000000000000000000C9D8E800318CED002285F7004596 + F900318BF900305ADC001518B7000C03B7000806A500072498001282EC00006E + B7005087B20000000000000000000000000000000000CECECE00A5A5A5008C8C + 8C009C9C9C00A5A5A500A5A5A500A5A5A500A5A5A5009C9C9C009C9C9C007B7B + 7B008C8C8C0000000000000000000000000000000000ADCEEF00318CF7000873 + F700298CF7003994FF00398CF700318CFF00318CF700218CF700188CF7000073 + BD00528CBD0000000000000000000000000000000000CECECE00A0A0A0008E8E + 8E009E9E9E00A5A5A500A0A0A000A0A0A000A0A0A0009B9B9B00999999007A7A + 7A008E8E8E0000000000000000000000000000000000ADCCEA00328FF2000E76 + F4002A89F7003B91F9003B8CF700348DF900308FF400278AF4001F88F2000072 + BF005589BA000000000000000000000000000000000000000000DEDEDE00B5B5 + B5009C9C9C008C8C8C008C8C8C00848484007B7B7B007B7B7B007B7B7B009494 + 9400000000000000000000000000000000000000000000000000CED6EF0073AD + EF00298CEF00007BE7000084DE00007BD600007BCE00006BD600006BCE004A8C + C600000000000000000000000000000000000000000000000000D8D8D800B7B7 + B70099999900898989008E8E8E00878787007F7F7F007F7F7F007C7C7C009393 + 9300000000000000000000000000000000000000000000000000C9D7EA0074AC + ED002A88ED00007AE5000085DD00007ED3000078C900006ED600006ECE004C8A + C400000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007B7B7B00949494000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000086BCE00428CCE000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007C7C7C00939393000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000A6CCE004288CE000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000ADADAD00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000006BA5E700000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000ADADAD00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000069A4E000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000009C9C9C00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000009C9C9C00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008C8C8C0063636300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008C8C8C0063636300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00009C9C9C00737373007373730052525200525252004A4A4A004A4A4A006363 + 630094949400CECECE0000000000000000000000000000000000000000000000 + 00009C9C9C00737373007373730052525200525252004A4A4A004A4A4A006363 + 630094949400CECECE0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000ADAD + AD0084848400A5A5A500A5A5A5009C9C9C009C9C9C00949494008C8C8C007373 + 7300525252006B6B6B00BDBDBD0000000000000000000000000000000000ADAD + AD0084848400A5A5A500A5A5A5009C9C9C009C9C9C00949494008C8C8C007373 + 7300525252006B6B6B00BDBDBD00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000ADAD + AD008C8C8C00ADADAD00ADADAD00A5A5A500A5A5A5009C9C9C00949494008C8C + 8C008C8C8C006B6B6B006B6B6B00D6D6D600000000000000000000000000ADAD + AD008C8C8C00ADADAD00ADADAD00A5A5A500A5A5A5009C9C9C00949494008C8C + 8C008C8C8C006B6B6B006B6B6B00D6D6D6000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000ADADAD00949494008C8C8C006B6B6B006363630063636300737373009494 + 940094949400949494005A5A5A00949494000000000000000000000000000000 + 0000ADADAD00949494008C8C8C006B6B6B006363630063636300737373009494 + 940094949400949494005A5A5A00949494000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000A5A5A5008C8C8C000000000000000000000000009C9C9C006363 + 630094949400949494007B7B7B006B6B6B000000000000000000000000000000 + 000000000000A5A5A5008C8C8C000000000000000000000000009C9C9C006363 + 630094949400949494007B7B7B006B6B6B00B5B5B500ADADAD00ADADAD00ADAD + AD00ADADAD000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000084B5DE007BADD6007BA5D6007BA5 + CE007BA5CE000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000B5B5B500ADADAD00ADADAD00ADAD + AD00ADADAD0000000000B5B5B50000000000000000000000000000000000A5A5 + A5005A5A5A005A5A5A00525252005252520084B5DE007BADD6007BA5D6007BA5 + CE007BA5CE0000000000B5B5B50000000000000000000000000000000000A5A5 + A5005A5A5A005A5A5A00525252005252520084848400848484007B7B7B007373 + 73009C9C9C000000000000000000000000000000000094949400000000000000 + 0000000000000000000000000000000000000073DE00007BCE000073C600006B + B5005A94C600000000000000000000000000000000005A8CB500000000000000 + 00000000000000000000000000000000000084848400848484007B7B7B007373 + 73009C9C9C00000000000000000000000000000000009494940000000000B5B5 + B500B5B5B500ADADAD00ADADAD00ADADAD000073DE00007BCE000073C600006B + B5005A94C600000000000000000000000000000000005A8CB50000000000B5B5 + B500B5B5B500ADADAD00ADADAD00ADADAD009494940094949400A5A5A5009C9C + 9C0073737300949494000000000000000000000000005A5A5A007B7B7B000000 + 0000000000000000000000000000000000002184E7001884EF003194F700218C + EF000063BD004A8CCE0000000000000000000000000000529C003973AD000000 + 0000000000000000000000000000000000009494940094949400A5A5A5009C9C + 9C0073737300949494000000000000000000000000005A5A5A007B7B7B000000 + 0000000000000000000000000000000000002184E7001884EF003194F700218C + EF000063BD004A8CCE0000000000000000000000000000529C003973AD000000 + 000000000000000000000000000000000000B5B5B5008C8C8C00A5A5A500A5A5 + A5009C9C9C007B7B7B00737373006B6B6B006363630073737300737373008484 + 84000000000000000000000000000000000073ADEF00087BEF004294FF00398C + F700298CF7000073D600006BB5000063AD00005A9C00006BBD00006BB500427B + AD0000000000000000000000000000000000B5B5B5008C8C8C00A5A5A500A5A5 + A5009C9C9C007B7B7B00737373006B6B6B006363630073737300737373008484 + 84000000000000000000000000000000000073ADEF00087BEF004294FF00398C + F700298CF7000073D600006BB5000063AD00005A9C00006BBD00006BB500427B + AD0000000000000000000000000000000000DEDEDE009C9C9C009C9C9C00ADAD + AD00A5A5A500A5A5A500A5A5A5009C9C9C009C9C9C00949494009C9C9C007373 + 73008C8C8C00000000000000000000000000CEDEEF00318CEF002184F7004294 + FF00318CFF00398CF7003194F700218CF7002184F7001884F7001084F700006B + B5005284B500000000000000000000000000DEDEDE009C9C9C009C9C9C00ADAD + AD00A5A5A500A5A5A500A5A5A5009C9C9C009C9C9C00949494009C9C9C007373 + 73008C8C8C00000000000000000000000000CEDEEF00318CEF002184F7004294 + FF00318CFF00398CF7003194F700218CF7002184F7001884F7001084F700006B + B5005284B50000000000000000000000000000000000CECECE00A5A5A5008C8C + 8C009C9C9C00A5A5A500A5A5A500A5A5A500A5A5A5009C9C9C009C9C9C007B7B + 7B008C8C8C0000000000000000000000000000000000ADCEEF00318CF7000873 + F700298CF7003994FF00398CF700318CFF00318CF700218CF700188CF7000073 + BD00528CBD0000000000000000000000000000000000CECECE00A5A5A5008C8C + 8C009C9C9C00A5A5A500A5A5A500A5A5A500A5A5A5009C9C9C009C9C9C007B7B + 7B008C8C8C0000000000000000000000000000000000ADCEEF00318CF7000873 + F700298CF7003994FF00398CF700318CFF00318CF700218CF700188CF7000073 + BD00528CBD000000000000000000000000000000000000000000DEDEDE00B5B5 + B5009C9C9C008C8C8C008C8C8C00848484007B7B7B007B7B7B007B7B7B009494 + 9400000000000000000000000000000000000000000000000000CED6EF0073AD + EF00298CEF00007BE7000084DE00007BD600007BCE00006BD600006BCE004A8C + C600000000000000000000000000000000000000000000000000DEDEDE00B5B5 + B5009C9C9C008C8C8C008C8C8C00848484007B7B7B007B7B7B007B7B7B009494 + 9400000000000000000000000000000000000000000000000000CED6EF0073AD + EF00298CEF00007BE7000084DE00007BD600007BCE00006BD600006BCE004A8C + C600000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007B7B7B00949494000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000086BCE00428CCE000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007B7B7B00949494000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000086BCE00428CCE000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000ADADAD00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000006BA5E700000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000ADADAD00000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000006BA5E700000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000400000000100010000000000000200000000000000000000 + 000000000000000000000000FFFFFF0000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000FDFFFDFFFDFFFDFFF9FFF9FFF9FFF9FF + F003F003F003F003E001E001E001E001E000E000E000E000F000F000F000F000 + F000F000F000F00000000000000000000000000000000000000F000F000F000F + 000F000F000F000F00070007000700078007800780078007C00FC00FC00FC00F + FF9FFF9FFF9FFF9FFFBFFFBFFFBFFFBFFDFFFDFFFFFFFFFFF9FFF9FFFFFFFFFF + F003F003FFFFFFFFE001E001FFFFFFFFE000E000F81FF81FF000F000F00FF00F + F9C0F9C0F00FF00F05E005E0000F000F07A00780000F000F039F039F000F000F + 000F000F000F000F00070007000700078007800780078007C00FC00FC00FC00F + FF9FFF9FFF9FFF9FFFBFFFBFFFBFFFBFFFFFFFFFFDFFFDFFFFFFFFFFF9FFF9FF + FFFFFFFFF003F003FFFFFFFFE001E001FFFFFFFFE000E000FFFFFFFFF000F000 + FFFFFFFFF9C0F9C007FF07FF05E005E007BF07BF07A007A0039F039F039F039F + 000F000F000F000F00070007000700078007800780078007C00FC00FC00FC00F + FF9FFF9FFF9FFF9FFFBFFFBFFFBFFFBF00000000000000000000000000000000 + 000000000000} + end +end diff --git a/DirectEthernetServer/Adapter.pas b/DirectEthernetServer/Adapter.pas new file mode 100755 index 0000000..5bd960e --- /dev/null +++ b/DirectEthernetServer/Adapter.pas @@ -0,0 +1,329 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +unit Adapter; + +interface + + uses + Forms, Classes, Controls, ExtCtrls, ComCtrls, StdCtrls, + Filters, Packets, PCap, LabRADThreadMessageQueue, Contexts, ImgList; + + type + TAdapterForm = class(TForm) + ToolPanel: TPanel; + LogPanel: TPanel; + Panel7: TPanel; + Panel8: TPanel; + Panel9: TPanel; + LANLogShow: TCheckBox; + ClrLANLogBtn: TButton; + LANLogMemo: TMemo; + Splitter1: TSplitter; + ConnectionPanel: TPanel; + Panel1: TPanel; + Panel2: TPanel; + Panel3: TPanel; + Panel5: TPanel; + Panel12: TPanel; + Panel4: TPanel; + Panel6: TPanel; + MACPanel: TPanel; + RecCountPanel: TPanel; + Panel10: TPanel; + ANamePanel: TPanel; + Timer1: TTimer; + Panel11: TPanel; + IPPanel: TPanel; + FastRefreshCheckBox: TCheckBox; + ImageList1: TImageList; + ContextList: TListView; + procedure FormCreate(Sender: TObject); + procedure Timer1Timer(Sender: TObject); + procedure ClrLANLogBtnClick(Sender: TObject); + procedure PacketQueueMessage(Sender: TObject; Msg: Integer; var Data: TObject); + procedure FastRefreshCheckBoxClick(Sender: TObject); + procedure FormDestroy(Sender: TObject); + + private + fRecCount: integer; + fListeners: array of TDEContext; + fChanging: Boolean; + fPktQueue: TThreadMessageQueue; + + public + fDbgTimeouts: Boolean; + Handle: ppcap_t; + Adapter: integer; + IP: array[0..3] of Byte; + + procedure RunLoop; + procedure Send(SourceMAC, DestMAC: TMAC; Data: string; Ethertype: integer); + procedure AddListener(Context: TDEContext); + procedure RemoveListener(Context: TDEContext); + procedure UpdateContext(Context: TDEContext); + procedure AddLANLog(Sending: Boolean; const Data: string); + + property PacketQueue: TThreadMessageQueue read fPktQueue; + end; + +implementation + +uses SysUtils, Main, ListenThread, Triggers, Windows; + +{$R *.dfm} + +procedure TAdapterForm.RunLoop; +begin + if assigned(Handle) then TListenThread.Create(Handle, self); +end; + +procedure TAdapterForm.FormCreate(Sender: TObject); +begin + fRecCount:=0; + DoubleBuffered:=true; + setlength(fListeners, 0); + ContextList.DoubleBuffered:=True; + fPktQueue:=TThreadMessageQueue.Create(self); + fPktQueue.OnMessage:=PacketQueueMessage; +end; + +procedure TAdapterForm.Timer1Timer(Sender: TObject); +var a: integer; +begin + RecCountPanel.Caption:=' '+inttostr(fRecCount); + for a:=1 to length(fListeners) do UpdateContext(fListeners[a-1]); + if fChanging then ContextList.Items.EndUpdate; + fChanging:=False; + if fDbgTimeouts then begin + MainForm.ErrorLogMemo.Lines.Add('<- Adapter '+inttostr(Adapter)+' Updates operational'); + fDbgTimeouts:=False; + end; +end; + +procedure TAdapterForm.ClrLANLogBtnClick(Sender: TObject); +begin + LANLogMemo.Clear; +end; + +procedure TAdapterForm.Send(SourceMAC, DestMAC: TMAC; Data: string; Ethertype: integer); +var id: word; +begin + if not SourceMAC.Valid then SourceMAC:=StrToMAC(trim(MACPanel.Caption)); + if EtherType<1518 then id:=length(Data) else id:=EtherType; + id:=swap(id); + Data:='12345612345612'+Data; + move(DestMAC.MAC[0], Data[ 1], 6); + move(SourceMAC.MAC[0], Data[ 7], 6); + move(id, Data[13], 2); + pcap_sendpacket(Handle, @Data[1], length(Data)); + if LANLogShow.Checked then AddLANLog(True, Data); +end; + +procedure TAdapterForm.PacketQueueMessage(Sender: TObject; Msg: Integer; var Data: TObject); +var a: integer; +begin + if Msg=12345 then begin + MainForm.LogPanel.Visible:=true; + MainForm.ErrorLogMemo.Lines.Add('<- Adapter '+inttostr(Adapter)+' Message Loop running'); + exit; + end; + if Data is TParsedPacket then begin + inc(fRecCount); + if LANLogShow.Checked then AddLANLog(False, TParsedPacket(Data).Raw); + if TParsedPacket(Data).Parsed then + for a:=1 to length(fListeners) do begin + try + fListeners[a-1].AddPacket(TParsedPacket(Data)); + except + on E: EOutOfMemory do begin + Application.MessageBox('CANNOT RESERVE MEMORY TO BUFFER MORE PACKETS.'#13#10#13#10+ + 'Cause: Packets are getting buffered faster than they are retrieved.'#13#10+ + 'Solution: Use packet filters to automatically discard undesired packets.'#13#10#13#10+ + '!!! PLEASE RESTART THE DIRECT ETHERNET SERVER !!!'#13#10, + 'ERROR: Out Of Memory', MB_ICONERROR + MB_OK); + exit; + end; + end; + end; + end; +end; + +procedure TAdapterForm.AddListener(Context: TDEContext); +var LI: TListItem; + a: integer; +begin + setlength(fListeners, length(fListeners)+1); + fListeners[high(fListeners)]:=Context; + LI:=ContextList.Items.Add; + Context.Tag:=LI.Index; + LI.Caption:=inttostr(Context.Context.High)+', '+inttostr(Context.Context.Low); + for a:=1 to 6 do LI.SubItems.Add(''); + LI.ImageIndex:=0; + UpdateContext(Context); + if fChanging then ContextList.Items.EndUpdate; + fChanging:=False; +end; + +procedure TAdapterForm.RemoveListener(Context: TDEContext); +var a, b: integer; +begin + a:=0; + while aContext.Tag then + fListeners[a-1].Tag:=fListeners[a-1].Tag-1; + end; +end; + +procedure TAdapterForm.UpdateContext(Context: TDEContext); +var LI: TListItem; + s: string; + ii: integer; + n: integer; +begin + LI:=ContextList.Items[Context.Tag]; + if not assigned(LI) then exit; + + s:=inttostr(Context.Sent); + if LI.SubItems[0]<>s then begin + if not fChanging then begin + ContextList.Items.BeginUpdate; + fChanging:=True; + end; + LI.SubItems[0]:=s; + end; + + s:=inttostr(Context.Received); + if LI.SubItems[1]<>s then begin + if not fChanging then begin + ContextList.Items.BeginUpdate; + fChanging:=True; + end; + LI.SubItems[1]:=s; + end; + + s:=inttostr(Context.Buffered); + if LI.SubItems[2]<>s then begin + if not fChanging then begin + ContextList.Items.BeginUpdate; + fChanging:=True; + end; + LI.SubItems[2]:=s; + end; + + if Context.SourceMAC.Valid then s:=MACtoStr(Context.SourceMAC) + else s:='not specified'; + if LI.SubItems[3]<>s then begin + if not fChanging then begin + ContextList.Items.BeginUpdate; + fChanging:=True; + end; + LI.SubItems[3]:=s; + end; + + if Context.DestMAC.Valid then s:=MACtoStr(Context.DestMAC) + else s:='not specified'; + if LI.SubItems[4]<>s then begin + if not fChanging then begin + ContextList.Items.BeginUpdate; + fChanging:=True; + end; + LI.SubItems[4]:=s; + end; + + case Context.EtherType of + -1: s:='IEEE 802.3'; + else + s:='Type: '+inttostr(Context.EtherType); + end; + if LI.SubItems[5]<>s then begin + if not fChanging then begin + ContextList.Items.BeginUpdate; + fChanging:=True; + end; + LI.SubItems[5]:=s; + end; + + ii:=0; + n:=trunc(now*24*3600*4); + if (n-Context.LastSent) in [1,3,5] then inc(ii); + if Context.Listening then begin + inc(ii, 2); + if (n-Context.LastRecd) in [1,3,5] then inc(ii, 2); + end; + if IsWaiting(Context.Context) then inc(ii, 6); + if LI.ImageIndex<>ii then begin + if not fChanging then begin + ContextList.Items.BeginUpdate; + fChanging:=True; + end; + LI.ImageIndex:=ii; + end; +end; + +procedure TAdapterForm.FastRefreshCheckBoxClick(Sender: TObject); +begin + if FastRefreshCheckBox.Checked then Timer1.Interval:=25 else Timer1.Interval:=250; +end; + +procedure TAdapterForm.AddLANLog(Sending: Boolean; const Data: string); +const HexChars: array[0..15] of Char= '0123456789ABCDEF'; +var a, b, o: integer; + c: char; + s: string; +begin + LANLogMemo.Lines.BeginUpdate; + if LANLogMemo.Lines.Count>0 then LANLogMemo.Lines.Add(''); + if Sending then LANLogMemo.Lines.Add('Sent:') else LANLogMemo.Lines.Add('Received:'); + for a:=1 to length(Data) div 16 do begin + s:=' 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 0123456789ABCDEF'; + for b:=0 to 15 do begin + c:=Data[a*16+b-15]; + if b>7 then o:=4 else o:=3; + s[o+b*3 ]:=HexChars[ord(c) shr 4]; + s[o+b*3+1]:=HexChars[ord(c) and $F]; + if c in [' '..#$7E] then s[54+b]:=c else s[54+b]:='.'; + end; + LANLogMemo.Lines.Add(s); + end; + a:=(length(Data)+15) div 16; + s:=' '; + for b:=0 to length(Data)+15-a*16 do begin + c:=Data[a*16+b-15]; + if b>7 then o:=4 else o:=3; + s[o+b*3 ]:=HexChars[ord(c) shr 4]; + s[o+b*3+1]:=HexChars[ord(c) and $F]; + if c in [' '..#$7E] then s[54+b]:=c else s[54+b]:='.'; + end; + LANLogMemo.Lines.Add(s); + LANLogMemo.Lines.EndUpdate; +end; + +procedure TAdapterForm.FormDestroy(Sender: TObject); +begin + fPktQueue.Free; +end; + +end. diff --git a/DirectEthernetServer/Contexts.pas b/DirectEthernetServer/Contexts.pas new file mode 100755 index 0000000..66c1a7c --- /dev/null +++ b/DirectEthernetServer/Contexts.pas @@ -0,0 +1,270 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +unit Contexts; + +interface + + uses + Classes, Filters, Packets, LabRADDataStructures, LabRADServer; + + type + TDEAction = (daReturn, daDrop, daKeep); + TDEFormat = (dfEmpty, dfString, dfStringArray, dfWords, dfWordsArray); + + TDEWaiter = record + Count: integer; + Timeout: TDateTime; + Action: TDEAction; + Format: TDEFormat; + end; + + TDEContext = class (TObject) + private + fContext: TLabRADContext; + fFilters: array of TPacketFilter; + fAdapter: integer; + fPackets: array of TParsedPacket; + fWaiter: TDEWaiter; + fListens: boolean; + fTimeout: Real; + fCollOfs: Integer; + fLColOfs: Integer; + + fServer: TLabRADServer; + + function BuildReply (Count: integer; Format: TDEFormat): TLabRADData; + procedure DropPackets(Count: integer); + + public + SourceMAC: TMAC; + DestMAC: TMAC; + EtherType: integer; + Tag: integer; + Sent: int64; + Received: int64; + Buffered: int64; + LastSent: Integer; + LastRecd: Integer; + + constructor Create(Context: TLabRADContext; Server: TLabRADServer); reintroduce; + destructor Destroy; override; + procedure Connect(Index: integer); + procedure AddFilter(Filter: TPacketFilter); + procedure AddPacket(Packet: TParsedPacket); + function ReceivePackets(Count: integer; Action: TDEAction; Format: TDEFormat = dfEmpty): TLabRADData; + + procedure CheckTimeout(Time: TDateTime); + procedure ClearPackets; + + property Adapter: integer read fAdapter; + property Listening: boolean read fListens write fListens; + property Timeout: real read fTimeout write fTimeout; + property Context: TLabRADContext read fContext; + end; + +implementation + +uses Forms, SysUtils, Errors; + +constructor TDEContext.Create(Context: TLabRADContext; Server: TLabRADServer); +begin + inherited Create; + setlength(fFilters, 0); + setlength(fPackets, 0); + fWaiter.Count:=-1; + fServer:=Server; + fContext:=Context; + fAdapter:=-1; + SourceMAC.Valid:=False; + DestMAC.Valid:=False; + EtherType:=-1; + Tag:=-1; + Sent:=0; + Received:=0; + Buffered:=0; + LastSent:=trunc(now*24*3600*2)-10; + LastRecd:=trunc(now*24*3600*2)-10; +end; + +destructor TDEContext.Destroy; +var a: integer; +begin + for a:=1 to length(fPackets) do fPackets[a-1].Release; + inherited; +end; + +procedure TDEContext.Connect(Index: Integer); +begin + fAdapter:=Index; +end; + +procedure TDEContext.AddFilter(Filter: TPacketFilter); +begin + setlength(fFilters, length(fFilters)+1); + fFilters[high(fFilters)]:=Filter; +end; + +function TDEContext.BuildReply(Count: integer; Format: TDEFormat): TLabRADData; +var a, b: integer; +begin + case Format of + dfString: + begin + Result:=TLabRADData.Create('(ssis)'); + Result.SetString (0, fPackets[0].Source); + Result.SetString (1, fPackets[0].Destination); + Result.SetInteger(2, fPackets[0].ID); + Result.SetString (3, fPackets[0].Data); + end; + + dfWords: + begin + Result:=TLabRADData.Create('(ssi*w)'); + Result.SetString (0, fPackets[0].Source); + Result.SetString (1, fPackets[0].Destination); + Result.SetInteger (2, fPackets[0].ID); + Result.SetArraySize(3, length(fPackets[0].Data)); + for b:=1 to length(fPackets[0].Data) do Result.SetWord([3, b-1], ord(fPackets[0].Data[b])); + end; + + dfStringArray: + begin + Result:=TLabRADData.Create('*(ssis)'); + Result.SetArraySize(Count); + for a:=0 to Count-1 do begin + Result.SetString ([a, 0], fPackets[a].Source); + Result.SetString ([a, 1], fPackets[a].Destination); + Result.SetInteger([a, 2], fPackets[a].ID); + Result.SetString ([a, 3], fPackets[a].Data); + end; + end; + + dfWordsArray: + begin + Result:=TLabRADData.Create('*(ssi*w)'); + Result.SetArraySize(Count); + for a:=0 to Count-1 do begin + Result.SetString ([a, 0], fPackets[a].Source); + Result.SetString ([a, 1], fPackets[a].Destination); + Result.SetInteger ([a, 2], fPackets[a].ID); + Result.SetArraySize([a, 3], length(fPackets[a].Data)); + for b:=1 to length(fPackets[a].Data) do Result.SetWord([a, 3, b-1], Ord(fPackets[a].Data[b])); + end; + end; + + else + Result:=TLabRADData.Create; + end; + DropPackets(Count); +end; + +procedure TDEContext.DropPackets(Count: integer); +var a: integer; +begin + if Count=length(fPackets) then begin + for a:=1 to length(fPackets) do fPackets[a-1].Release; + setlength(fPackets, 0); + end else begin + for a:=1 to Count do fPackets[a-1].Release; + for a:=Count to high(fPackets) do fPackets[a-Count]:=fPackets[a]; + setlength(fPackets, length(fPackets)-Count); + end; +end; + +procedure TDEContext.AddPacket(Packet: TParsedPacket); +var a: integer; + Reply: TLabRADData; +begin + if not fListens then exit; + a:=0; + while (a=Count then begin + if Action=daKeep then Result:=TLabRADData.Create + else Result:=BuildReply(Count, Format); + end else begin + if fTimeOut>0 then begin + Result:=nil; + fWaiter.Count :=Count; + fWaiter.Timeout:=now+fTimeOut; + fWaiter.Action :=Action; + fWaiter.Format :=Format; + end else begin + raise ETimeoutError.Create; + end; + end; +end; + +procedure TDEContext.CheckTimeout(Time: TDateTime); +begin + if (fWaiter.Count>0) and (fWaiter.TimeoutdaKeep then inc(Buffered, fWaiter.Count); + fWaiter.Count:=-1; + if assigned(fServer) then fServer.SendError(fContext, 0, 'Operation timed out'); + fCollOfs:=fLColOfs; + end; +end; + +procedure TDEContext.ClearPackets; +var a: integer; +begin + for a:=1 to length(fPackets) do fPackets[a-1].Release; + setlength(fPackets, 0); + Buffered:=0; + fCollOfs:=0; +end; + +end. diff --git a/DirectEthernetServer/DirectEthernet.dpr b/DirectEthernetServer/DirectEthernet.dpr new file mode 100755 index 0000000..3475c1b --- /dev/null +++ b/DirectEthernetServer/DirectEthernet.dpr @@ -0,0 +1,35 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +program DirectEthernet; + +uses + Forms, + Main in 'Main.pas' {MainForm}, + Adapter in 'Adapter.pas' {AdapterForm}, + Filters in 'Filters.pas', + Contexts in 'Contexts.pas', + Packets in 'Packets.pas', + ListenThread in 'ListenThread.pas', + Errors in 'Errors.pas', + Triggers in 'Triggers.pas'; + +{$R *.res} + +begin + Application.Initialize; + Application.CreateForm(TMainForm, MainForm); + Application.Run; +end. diff --git a/DirectEthernetServer/DirectEthernet.res b/DirectEthernetServer/DirectEthernet.res new file mode 100755 index 0000000000000000000000000000000000000000..077ea9dbc0da04f7df2dd6e95f82e7bb064949c0 GIT binary patch literal 876 zcmZuw!D(!F%@TF_6RNWFiK|gZdLPlbZ_@x(5O}A>cOjA-@us!w7X5 zPyR;0i^shgFj&6o?uijB_I20mdR5iiJxxTk1Vkd>{$oELOz|9=EW{RzhqFoa6wVSj z0y0X=$oao@MEFtH#R(%^prdgd5ztNOByqwR_a#&|`)UhBgOzMy&ECWd=k30=cbpJ} zehL#g=a~DyTm>sjv*Y8m=DF`__R^TN;CX21Rb5x+C@7pCnt5eRUB3^!M10=1h@U3j zH+Hl6T-8-bC>%F!+Zv<H5cY$=?Cr`pcgpLyQ21eQZY`Bb0N#YiBtSuMd&WuNSP!&hP68Y{ z1mHx29{*Y3=)0zH9hL`+0*rj_ar#J9j)b*`&+KAl<}V)i0rQ~~^Hrp{Bi&FLM)i_i zQJ0BK7;_QDHouVV4$1ZrecBduc%vZNRovdgZ}`BW0-u*+SI#dkrIT+m-sUoX%;fsn zV}#~F4x9rc@D=zjB0ryCC;D-T?9dx}POs@L@Pgi9p6vd+(ASXBaybjHLSIove*oz4 B>!$z! literal 0 HcmV?d00001 diff --git a/DirectEthernetServer/Errors.pas b/DirectEthernetServer/Errors.pas new file mode 100755 index 0000000..10838fe --- /dev/null +++ b/DirectEthernetServer/Errors.pas @@ -0,0 +1,84 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +unit Errors; + +interface + + uses + LabRADExceptions; + + type + ETimeoutError = class(ELabRADException) + public + constructor Create; reintroduce; + end; + + EUnknownAdapterError = class(ELabRADException) + public + constructor Create(Index: integer); reintroduce; overload; + constructor Create(Name: string ); reintroduce; overload; + end; + + ENotConnectedError = class(ELabRADException) + public + constructor Create; reintroduce; + end; + + ENoDestinationMACError = class(ELabRADException) + public + constructor Create; reintroduce; + end; + + EUnknownSettingError = class(ELabRADException) + public + constructor Create(Index: integer); reintroduce; + end; + +implementation + +uses SysUtils; + +constructor ETimeoutError.Create; +begin + inherited Create(0, 'Operation timed out'); +end; + +constructor EUnknownAdapterError.Create(Index: Integer); +begin + inherited Create(0, 'Adapter '+inttostr(Index)+' not found'); +end; + +constructor EUnknownAdapterError.Create(Name: string); +begin + inherited Create(0, 'Adapter "'+Name+'" not found'); +end; + +constructor ENotConnectedError.Create; +begin + inherited Create(0, 'Not connected'); +end; + +constructor ENoDestinationMACError.Create; +begin + inherited Create(0, 'No destination MAC address specified'); +end; + +constructor EUnknownSettingError.Create(Index: Integer); +begin + inherited Create(0, 'Setting '+inttostr(Index)+' has not been implemented yet...'); +end; + +end. diff --git a/DirectEthernetServer/Filters.pas b/DirectEthernetServer/Filters.pas new file mode 100755 index 0000000..3adc42d --- /dev/null +++ b/DirectEthernetServer/Filters.pas @@ -0,0 +1,174 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +unit Filters; + +interface + + type + TMAC = record + Valid: Boolean; + MAC: packed array[0..5] of Byte; + end; + + TPacketFilter = class(TObject) + public + function Match(const Source, Dest: string; ID: integer; const Data: string): boolean; virtual; abstract; + end; + + TMACFilter = class(TPacketFilter) + private + fMAC: string; + fSrc: boolean; + fNeg: boolean; + public + constructor Create(MAC: string; CheckSource: boolean; RejectMatch: boolean); reintroduce; + function Match(const Source, Dest: string; ID: integer; const Data: string): boolean; override; + end; + + TLengthFilter = class(TPacketFilter) + private + fLen: integer; + fNeg: boolean; + public + constructor Create(Len: integer; RejectMatch: boolean); reintroduce; + function Match(const Source, Dest: string; ID: integer; const Data: string): boolean; override; + end; + + TContentFilter = class(TPacketFilter) + private + fOfs: integer; + fDat: string; + fNeg: boolean; + public + constructor Create(Offset: integer; Data: string; RejectMatch: boolean); reintroduce; + function Match(const Source, Dest: string; ID: integer; const Data: string): boolean; override; + end; + + TProtocolFilter = class(TPacketFilter) + private + fID: integer; + fNeg: boolean; + public + constructor Create(Protocol: integer; RejectMatch: boolean); reintroduce; + function Match(const Source, Dest: string; ID: integer; const Data: string): boolean; override; + end; + + function StrToMAC(S:string): TMAC; + function MACtoStr(MAC: TMAC): string; + +implementation + +function StrToMAC(S:string): TMAC; +var a, p: integer; +begin + Result.Valid:=False; + if length(s)<>17 then exit; + for a:=0 to 16 do begin + case S[a+1] of + '0'..'9': p:=ord(S[a+1])-Ord('0'); + 'A'..'F': p:=ord(S[a+1])-Ord('A')+10; + 'a'..'f': p:=ord(S[a+1])-Ord('a')+10; + else + p:=-1; + end; + case a mod 3 of + 0: + begin + if not (p in [0..15]) then exit; + Result.MAC[a div 3]:=p shl 4; + end; + 1: + begin + if not (p in [0..15]) then exit; + Result.MAC[a div 3]:=Result.MAC[a div 3] or p; + end; + 2: + if s[a+1]<>':' then exit; + end; + end; + Result.Valid:=true; +end; + +function MACtoStr(MAC: TMAC): string; +const HCs: array[0..15] of Char = '0123456789ABCDEF'; +begin + Result:=HCs[MAC.MAC[0] shr 4]+HCs[MAC.MAC[0] and $F]+':'+ + HCs[MAC.MAC[1] shr 4]+HCs[MAC.MAC[1] and $F]+':'+ + HCs[MAC.MAC[2] shr 4]+HCs[MAC.MAC[2] and $F]+':'+ + HCs[MAC.MAC[3] shr 4]+HCs[MAC.MAC[3] and $F]+':'+ + HCs[MAC.MAC[4] shr 4]+HCs[MAC.MAC[4] and $F]+':'+ + HCs[MAC.MAC[5] shr 4]+HCs[MAC.MAC[5] and $F]; +end; + + +constructor TMACFilter.Create(MAC: string; CheckSource: boolean; RejectMatch: boolean); +begin + inherited Create; + fMAC:=MAC; + fSrc:=CheckSource; + fNeg:=RejectMatch; +end; + +function TMACFilter.Match(const Source, Dest: string; ID: integer; const Data: string): boolean; +begin + if fSrc then begin + Result:=(Source = fMAC) xor fNeg; + end else begin + Result:=(Dest = fMAC) xor fNeg; + end; +end; + + +constructor TLengthFilter.Create(Len: integer; RejectMatch: boolean); +begin + inherited Create; + fLen:=Len; + fNeg:=RejectMatch; +end; + +function TLengthFilter.Match(const Source, Dest: string; ID: integer; const Data: string): boolean; +begin + Result:=(length(Data) = fLen) xor fNeg; +end; + + +constructor TContentFilter.Create(Offset: integer; Data: string; RejectMatch: boolean); +begin + inherited Create; + fOfs:=Offset; + fDat:=Data; + fNeg:=RejectMatch; +end; + +function TContentFilter.Match(const Source, Dest: string; ID: integer; const Data: string): boolean; +begin + Result:=(copy(Data, fOfs, length(fDat)) = fDat) xor fNeg; +end; + + +constructor TProtocolFilter.Create(Protocol: integer; RejectMatch: boolean); +begin + inherited Create; + fID:=Protocol; + fNeg:=RejectMatch; +end; + +function TProtocolFilter.Match(const Source, Dest: string; ID: integer; const Data: string): boolean; +begin + Result:=(ID=fID) xor fNeg; +end; + +end. diff --git a/DirectEthernetServer/GetMAC.pas b/DirectEthernetServer/GetMAC.pas new file mode 100755 index 0000000..9a6412a --- /dev/null +++ b/DirectEthernetServer/GetMAC.pas @@ -0,0 +1,188 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +unit GetMAC; + +interface + + uses Classes; + + const + MAX_INTERFACE_NAME_LEN = $100; + ERROR_SUCCESS = 0; + MAXLEN_IFDESCR = $100; + MAXLEN_PHYSADDR = 8; + + MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0 ; + MIB_IF_OPER_STATUS_UNREACHABLE = 1; + MIB_IF_OPER_STATUS_DISCONNECTED = 2; + MIB_IF_OPER_STATUS_CONNECTING = 3; + MIB_IF_OPER_STATUS_CONNECTED = 4; + MIB_IF_OPER_STATUS_OPERATIONAL = 5; + + MIB_IF_TYPE_OTHER = 1; + MIB_IF_TYPE_ETHERNET = 6; + MIB_IF_TYPE_TOKENRING = 9; + MIB_IF_TYPE_FDDI = 15; + MIB_IF_TYPE_PPP = 23; + MIB_IF_TYPE_LOOPBACK = 24; + MIB_IF_TYPE_SLIP = 28; + + MIB_IF_ADMIN_STATUS_UP = 1; + MIB_IF_ADMIN_STATUS_DOWN = 2; + MIB_IF_ADMIN_STATUS_TESTING = 3; + + + type + MIB_IFROW = record + wszName: array[0..(MAX_INTERFACE_NAME_LEN*2-1)] of char; + dwIndex: LongInt; + dwType: LongInt; + dwMtu: LongInt; + dwSpeed: LongInt; + dwPhysAddrLen: LongInt; + bPhysAddr: array[0..(MAXLEN_PHYSADDR-1)] of Byte; + dwAdminStatus: LongInt; + dwOperStatus: LongInt; + dwLastChange: LongInt; + dwInOctets: LongInt; + dwInUcastPkts: LongInt; + dwInNUcastPkts: LongInt; + dwInDiscards: LongInt; + dwInErrors: LongInt; + dwInUnknownProtos: LongInt; + dwOutOctets: LongInt; + dwOutUcastPkts: LongInt; + dwOutNUcastPkts: LongInt; + dwOutDiscards: LongInt; + dwOutErrors: LongInt; + dwOutQLen: LongInt; + dwDescrLen: LongInt; + bDescr: array[0..(MAXLEN_IFDESCR - 1)] of Char; + end; + + function GetMACAddress(Adapter: string): string; overload; + function GetMACAddress(Index: integer): string; overload; + + function GetMACAddresses: tstringlist; + + function GetIfTable( pIfTable : Pointer; var pdwSize : LongInt; bOrder : LongInt ): LongInt; stdcall; + + +implementation + +uses sysutils; + +function GetIfTable; stdcall; external 'IPHLPAPI.DLL'; + +type + IfEntry = record + Description: string; + MAC: array[0..5] of Byte; + Index: integer; + end; + +var + IfList: array of IfEntry; + allmacs: tstringlist; + +function GetMACAddresses: tstringlist; +begin + result:=allmacs; +end; + +function GetMACAddress(Adapter: string): string; +const HCs: array[0..15] of Char = '0123456789ABCDEF'; +var a: integer; +begin + a:=0; + while a0 then begin + Result:=HCs[IfList[a].MAC[0] shr 4] + HCs[IfList[a].MAC[0] and $F] + ':' + + HCs[IfList[a].MAC[1] shr 4] + HCs[IfList[a].MAC[1] and $F] + ':' + + HCs[IfList[a].MAC[2] shr 4] + HCs[IfList[a].MAC[2] and $F] + ':' + + HCs[IfList[a].MAC[3] shr 4] + HCs[IfList[a].MAC[3] and $F] + ':' + + HCs[IfList[a].MAC[4] shr 4] + HCs[IfList[a].MAC[4] and $F] + ':' + + HCs[IfList[a].MAC[5] shr 4] + HCs[IfList[a].MAC[5] and $F]; + exit; + end; + inc(a); + end; + Result:=''; +end; + +function GetMACAddress(Index: integer): string; +const HCs: array[0..15] of Char = '0123456789ABCDEF'; +var a: integer; +begin + a:=0; + while a= SizeOf(MIB_IFROW)+Sizeof(LongInt)) then begin + GetMem(pIfTable, TableSize); + if GetIfTable(pIfTable, TableSize, 1)=ERROR_SUCCESS then begin + for i := 1 to pIfTable^.nRows do begin + if (pIfTable^.ifRow[i].dwType in [MIB_IF_TYPE_ETHERNET, MIB_IF_TYPE_LOOPBACK]) and + (pIfTable^.ifRow[i].dwPhysAddrLen=6) then begin + setlength(IfList, length(IfList)+1); + IfList[high(IfList)].Description:=pIfTable^.ifRow[i].bDescr; + IfList[high(IfList)].Description:=trim(IfList[high(IfList)].Description); + IfList[high(IfList)].MAC[0]:=pIfTable^.ifRow[i].bPhysAddr[0]; + IfList[high(IfList)].MAC[1]:=pIfTable^.ifRow[i].bPhysAddr[1]; + IfList[high(IfList)].MAC[2]:=pIfTable^.ifRow[i].bPhysAddr[2]; + IfList[high(IfList)].MAC[3]:=pIfTable^.ifRow[i].bPhysAddr[3]; + IfList[high(IfList)].MAC[4]:=pIfTable^.ifRow[i].bPhysAddr[4]; + IfList[high(IfList)].MAC[5]:=pIfTable^.ifRow[i].bPhysAddr[5]; + IfList[high(IfList)].Index:=i-1; + end; + allmacs.add(pIfTable^.ifRow[i].bDescr); + end; + end; + FreeMem(pIfTable); + end; +end. + diff --git a/DirectEthernetServer/LICENSE.txt b/DirectEthernetServer/LICENSE.txt new file mode 100755 index 0000000..d511905 --- /dev/null +++ b/DirectEthernetServer/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/DirectEthernetServer/ListenThread.pas b/DirectEthernetServer/ListenThread.pas new file mode 100755 index 0000000..b920039 --- /dev/null +++ b/DirectEthernetServer/ListenThread.pas @@ -0,0 +1,79 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +unit ListenThread; + +interface + + uses + Classes, PCap, Adapter; + + type + TListenThread = class(TThread) + private + fHandle: ppcap_t; + fAdapter: TAdapterForm; + fMsg: string; + + public + constructor Create(Handle: ppcap_t; Adapter: TAdapterForm); + procedure Execute; override; + procedure PCap_Loop_Exception; + procedure PCap_Loop_Exit; + end; + +implementation + +uses Packets, Main, Forms, SysUtils, Windows; + + +procedure PCapCallback(UserData: Pointer; Pkt_Header: ppcap_pkthdr; Pkt_Data: pchar); cdecl; far; +begin + TAdapterForm(UserData).PacketQueue.Send(TParsedPacket.Create(Pkt_Data, Pkt_Header.len)); +end; + + +constructor TListenThread.Create(Handle: ppcap_t; Adapter: TAdapterForm); +begin + inherited Create(False); + FreeOnTerminate:=True; + fHandle:=Handle; + fAdapter:=Adapter; +end; + +procedure TListenThread.Execute; +begin + try + pcap_loop(fHandle, 0, @PCapCallback, PAnsiChar(fAdapter)); (**) + except + on E: Exception do begin + fMsg:='"pcap_loop" raised exception: "'+E.Message+'"'#13#10'Please report error to "LabRAD Modules" Bug Tracker on SourceForge.net'#0; + Synchronize(PCap_Loop_Exception); + end; + end; + if not Main.Quitting then Synchronize(PCap_Loop_Exit); +end; + +procedure TListenThread.PCap_Loop_Exception; +begin + Application.MessageBox(@fMsg[1], 'Exception', MB_ICONERROR + MB_OK); +end; + +procedure TListenThread.PCap_Loop_Exit; +begin + Application.MessageBox('"pcap_loop" exited unexpectedly.'#13#10'Should this happen frequently or cause problems, please report to "LabRAD Modules" Bug Tracker on SourceForge.net'#0, 'Warning', MB_ICONERROR + MB_OK); +end; + +end. diff --git a/DirectEthernetServer/Main.dfm b/DirectEthernetServer/Main.dfm new file mode 100755 index 0000000..ac5d953 --- /dev/null +++ b/DirectEthernetServer/Main.dfm @@ -0,0 +1,298 @@ +object MainForm: TMainForm + Left = 207 + Top = 116 + Width = 795 + Height = 565 + Caption = 'Direct Ethernet Server v1.1.1 (w) 2008 by Markus Ansmann' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + FormStyle = fsMDIForm + OldCreateOrder = False + Position = poScreenCenter + OnCloseQuery = FormCloseQuery + OnPaint = FormPaint + PixelsPerInch = 96 + TextHeight = 13 + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 787 + Height = 29 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + DesignSize = ( + 787 + 29) + object SpeedButton1: TSpeedButton + Left = 3 + Top = 3 + Width = 25 + Height = 24 + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 1800000000000003000000000000000000000000000000000000CED3D6CED3D6 + CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3 + D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CE + D3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6AD8673BD7D52 + B579529C61429C5D399459399455399C614AB5714AAD694AAD65429451398C4D + 318C4D31A5796BCED3D6C6865AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD + 7952FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C4D31CED3D6C68E63FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD7D52FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFF8C5139CED3D6CE926BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 + 865AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF945539CED3D6D69A73FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE8E63FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFF9C5939CED3D6D6A273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE + 9263FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C5D42CED3D6D6A67BFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6966BFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFA56542CED3D6DEAA84FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 + 9E73FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD694ACED3D6DEAE84FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEA273FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFAD714ACED3D6DEAE84FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE + A67BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB57952CED3D6DEB28CDEB28C + DEB28CDEAE84DEAE84DEAE84DEAA84DEAA7BDEAA7BDEA67BDEA67BDEA273DEA2 + 73DEA273BD825ACED3D6E7B694EFC3A5EFC39CEFC39CEFBE9CEFBE9CEFBE9CDE + B28CEFBE94EFBA94E7BA94E7BA94E7B694E7B68CBD8A6BCED3D6C6AEA5E7BA9C + DEB28CD6A67BD6A27BCEA273CEA68CBD967BDEB694DEAE84DEAA7BCE9A73CE96 + 6BC69A7BBDA69CCED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CE + D3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6} + OnClick = SpeedButton1Click + end + object SpeedButton2: TSpeedButton + Left = 31 + Top = 3 + Width = 25 + Height = 24 + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 1800000000000003000000000000000000000000000000000000CED3D6CED3D6 + CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3D6CED3 + D6CED3D6CED3D6CED3D6CED3D6AD8273B57552B5714AAD6D4AAD6942A565429C + 5D429C59399C59399455399451398C4D31A5796BCED3D6CED3D6CED3D6BD825A + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF8C4D31CED3D6CED3D6CED3D6D6966BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA55D42CED3D6CED3D6CED3D6D69A6B + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFA56542CED3D6CED3D6CED3D6DE9E73FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD694ACED3D6CED3D6CED3D6DEA273 + DEA273DE9E73DE9E6BDE9E6BD69A6BD69A6BD69A6BD69663D69663D69663D692 + 63B5714ACED3D6CED3D6CED3D6DEAA84E7B68CE7B68CE7B28CE7B28CE7B284E7 + B284E7AE84E7AE84E7AE84E7AE7BE7AA7BB5795ACED3D6CED3D6CED3D6AD8263 + DEAE8CDEA67BDEA273D69E73D69A73D6966BCE966BCE9263CE8E63C68A5ABD8A + 63A5715ACED3D6CED3D6CED3D6CE966BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C6142CED3D6CED3D6CED3D6CE9A73 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF9C6542CED3D6CED3D6CED3D6DEAA84FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB57952CED3D6CED3D6CED3D6DEAE84 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFBD825ACED3D6CED3D6CED3D6DEB28CDEB28CDEAE84DEAE84DEAE84DEAE84DE + AA84DEAA84DEAA7BDEA67BDEA67BDEA67BBD8663CED3D6CED3D6CED3D6E7B694 + EFC39CEFC39CEFBE9CEFBE9CEFBE9CEFBE9CEFBE9CEFBE94EFBA94EFBA94E7BA + 94C6926BCED3D6CED3D6CED3D6C6AEA5E7BA9CDEB28CDEB28CDEAE84DEAE84DE + AA84D6A67BD6A67BD6A27BD69E73C69E7BBDAA9CCED3D6CED3D6} + OnClick = SpeedButton2Click + end + object SpeedButton3: TSpeedButton + Left = 59 + Top = 3 + Width = 25 + Height = 24 + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 1800000000000003000000000000000000000000000000000000CED3D6CED3D6 + CED3D6CED3D6AD8A73BD825ABD825AB57D5AB57952B57952AD7152AD6D4AA56D + 4AA5694AA56542AD8A73CED3D6CED3D6CED3D6CED3D6C68663FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA56542CED3D6CED3D6 + CED3D6CED3D6D69A6BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFAD7552CED3D6CED3D6CED3D6CED3D6D69A6BFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB57952CED3D6CED3D6 + B59284BD8E6BD69A6BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFB57D52CED3D6CED3D6C6926BFFFBFFDE9E6BDE9E6BDE9E6BDE + 9E6BDE9E6BDE9E6BDE9E6BDE9E6BDE9E6BDE9E6BDE9E6BBD825ACED3D6CED3D6 + D69E7BFFFBFFDEA67BE7B284E7B284E7B284E7B284E7B284E7B284E7B284E7B2 + 84E7B284E7B284BD8663CED3D6CED3D6D6A27BFFFBFFD6BAADDEAE84DE9E6BDE + 9E6BD69A6BD69A6BD6966BCE9263CE9263CE8E63BD926BBDA69CB59A8CC6967B + D69A6BF7F3EFF7F3EFF7EFEFF7EFEFF7EFEFF7EFEFF7EFEFF7EFEFF7F3EFFFFB + FFB58663CED3D6CED3D6C69A7BF7F7F7DEAA7BDEAA7BDEAA7BDEAA7BDEAA7BDE + AA7BDEAA7BDEAA7BDEAA7BD69A6BD6A67BBD8A6BCED3D6CED3D6D6A684F7F7F7 + DEAE8CE7BA94E7BA94E7BA94E7BA94E7BA94E7BA94E7BA94E7BA94DEAE84E7B6 + 94BD8E73CED3D6CED3D6D6A684F7F7F7D6BEB5DEB294DEAA7BDEA67BDEA67BDE + A27BD6A27BD69E7BCE9A73C68E63BD9A7BBDAAA5CED3D6CED3D6D6A684F7F7F7 + F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7BD9273CED3 + D6CED3D6CED3D6CED3D6D6AA84D6AA84D6AA84D6AA84D6AA84D6AA84D6AA84D6 + AA84D6AA84D6AA84D6AA84BD9273CED3D6CED3D6CED3D6CED3D6D6AE8CE7BA9C + E7BA9CE7BA9CE7BA9CE7BA9CE7BA9CE7BA9CE7BA9CE7BA9CE7BA9CBD967BCED3 + D6CED3D6CED3D6CED3D6BDAEA5D6B294D6AA84D6AA84D6A684CEA684CEA284CE + A284CE9E84CE9E7BC69E84BDAEA5CED3D6CED3D6CED3D6CED3D6} + OnClick = SpeedButton3Click + end + object SpeedButton4: TSpeedButton + Left = 759 + Top = 3 + Width = 25 + Height = 24 + AllowAllUp = True + Anchors = [akTop, akRight] + Flat = True + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 1800000000000003000000000000000000000000000000000000C8D0D4C8D0D4 + C8D0D4C8D0D4C8D0D4C8D0D49FA4A66A6C6D656768959A9C0F7827026F16C4CD + D0C8D0D4C8D0D4C8D0D4C8D0D4C8D0D4C8D0D4B6BDC0C2C9CDC6CED27C7D7DB5 + B5B5A9A9A95859590F7E2F389753227D37C3CDCFC8D0D4C8D0D4C8D0D4C8D0D4 + 95989A636363616262BEC5C91A8D4515863F1084390B80302F955275BA8C3B99 + 56137128C2CCCEC8D0D4C8D0D4B1B5B7B4B4B4DADADA9D9D9D7A7A7B20914F85 + C4A082C19B7FBF977DBE945EAE7A77BB8D3D9B5A13752AC0CBCCC8D0D4B4B9BB + 9C9C9CD0D0D0BEBEBEC5C5C527955789C7A463B2835FB07E5AAE7A55AB755BAD + 7778BB8E31965004741FC8D0D4C8D0D4B4B8BABEBEBEBABABABEBEBE2D995F8C + C8A789C7A486C5A185C59F68B4857FC0973B9B5C067D2DC7CFD3A2A3A48A8B8C + 99999AC9C9C9BFBFBFC6C6C6329B632E99612A975B25925549A67086C5A143A2 + 6811833A58595A606162B7B7B7DEDEDECDCDCDBFBFBFC7C7C7A8A8A8B6BCBFC8 + D0D4C8D0D4B6BCBF2F965C4EAB761F8E4BB9B9B9CDCDCD555555BCBCBCE6E6E6 + D1D1D1C3C3C3C8C8C89B9B9BB2B8BBC8D0D4C8D0D4B8BEC1359A64279559B2B2 + B2BFBFBFD9D9D95F5F5FC2C3C4BDBEBFB9B9BAD3D3D3C7C7C7B4B4B4888A8BAE + B4B7B0B6B9929495BCBCBCBBBBBBC7C7C7858586838485878889C8D0D4C8D0D4 + C2C6C8CFCFCFC6C6C6C3C3C3B2B2B2929292979797BBBBBBBFBFBFBABABAAFAF + AFA0A4A6C8D0D4C8D0D4C8D0D4C5CACCBCBCBCD8D8D8CFCFCFD4D4D4D7D7D7D1 + D1D1CFCFCFD4D4D4CDCDCDC5C5C5C1C1C16C6C6C969B9DC8D0D4C8D0D4C8CCCE + D8D8D8EBEBEBD7D7D7BABABBB6B6B6D1D1D1CFCFCFA6A6A6A3A3A4C5C5C5E4E4 + E4AFAFAFA4A8AAC8D0D4C8D0D4C8D0D4C9CCCEC7C7C7C3C4C4C6CDD1BBBCBCDA + DADAD9D9D9ABACACC4CBCFA5A6A69D9D9DABAEB0C8D0D4C8D0D4C8D0D4C8D0D4 + C8D0D4C7CED1C7CED2C7CFD3C0C1C1E2E2E2E1E1E1A5A6A6C7CFD3C6CDD1C1C8 + CBC8D0D4C8D0D4C8D0D4C8D0D4C8D0D4C8D0D4C8D0D4C8D0D4C8D0D4C6CBCDC1 + C3C4BFC1C2C1C6C8C8D0D4C8D0D4C8D0D4C8D0D4C8D0D4C8D0D4} + OnClick = SpeedButton4Click + end + end + object LogPanel: TPanel + Left = 0 + Top = 406 + Width = 787 + Height = 132 + Align = alBottom + BevelOuter = bvNone + TabOrder = 1 + Visible = False + object Panel2: TPanel + Left = 0 + Top = 3 + Width = 787 + Height = 129 + Align = alClient + BevelOuter = bvLowered + Constraints.MinHeight = 70 + TabOrder = 0 + object Panel7: TPanel + Left = 1 + Top = 1 + Width = 785 + Height = 19 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + object Panel8: TPanel + Left = 0 + Top = 0 + Width = 149 + Height = 19 + Align = alLeft + Alignment = taLeftJustify + Caption = ' Errors' + Color = clHighlight + Font.Charset = DEFAULT_CHARSET + Font.Color = clHighlightText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + end + object Panel9: TPanel + Left = 149 + Top = 0 + Width = 636 + Height = 19 + Align = alClient + BevelOuter = bvNone + TabOrder = 1 + DesignSize = ( + 636 + 19) + object ClrErrorLogBtn: TButton + Left = 609 + Top = 2 + Width = 25 + Height = 15 + Anchors = [akTop, akRight] + Caption = 'clr' + TabOrder = 0 + OnClick = ClrErrorLogBtnClick + end + end + end + object ErrorLogMemo: TMemo + Left = 1 + Top = 20 + Width = 785 + Height = 108 + Align = alClient + ReadOnly = True + ScrollBars = ssBoth + TabOrder = 1 + end + end + object Panel3: TPanel + Left = 0 + Top = 0 + Width = 787 + Height = 3 + Align = alTop + BevelOuter = bvNone + TabOrder = 1 + end + end + object LabRADServer1: TLabRADServer + Active = False + ConnectionName = '%LabRADNode% Direct Ethernet' + Manager.Port = 7682 + API_INFO.ABOUT = '(w) 2008 by Markus Ansmann' + API_INFO.HELP = + 'Visit http://delphi.labrad.org for the documentation of these co' + + 'mponents' + API_INFO.README = + 'These components connect to the LabRAD Manager available as open' + + ' source at http://www.labrad.org' + API_INFO.VERSION = 'v1.3.1' + OnConnect = LabRADServer1Connect + OnDisconnect = LabRADServer1Disconnect + OnError = LabRADServer1Error + CreateCallback = OnSelfResponse + Description = 'Provides raw ethernet packet capturing and sending functions.' + SettingCount = 0 + AutoStartServing = False + NodeInfo = + #13#10'### BEGIN NODE INFO'#13#10'[info]'#13#10'name = Direct Ethernet'#13#10'instancen' + + 'ame = %LabRADNode% Direct Ethernet'#13#10'version = 1.1.1'#13#10'description' + + ' = Provides raw ethernet packet capturing and sending functions.' + + #13#10'[startup]'#13#10'cmdline = %FILE%'#13#10'timeout = 20'#13#10'[shutdown]'#13#10'timeout' + + ' = 5'#13#10'### END NODE INFO'#13#10 + OnNewContext = LabRADServer1NewContext + OnExpireContext = LabRADServer1ExpireContext + OnRequest = LabRADServer1Request + Left = 4 + Top = 36 + end + object Timer1: TTimer + Interval = 500 + OnTimer = Timer1Timer + Left = 36 + Top = 36 + end +end diff --git a/DirectEthernetServer/Main.pas b/DirectEthernetServer/Main.pas new file mode 100755 index 0000000..1aee5e2 --- /dev/null +++ b/DirectEthernetServer/Main.pas @@ -0,0 +1,571 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + + +{ +TODO: + + - Error check MAC addresses, etc. + +} + +unit Main; + +interface + + uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, Adapter, Filters, LabRADConnection, + LabRADClient, LabRADServer, LabRADDataStructures, Contexts, Packets, ExtCtrls, Buttons; + + type + TMainForm = class(TForm) + LabRADServer1: TLabRADServer; + Timer1: TTimer; + Panel1: TPanel; + SpeedButton1: TSpeedButton; + SpeedButton2: TSpeedButton; + SpeedButton3: TSpeedButton; + LogPanel: TPanel; + Panel2: TPanel; + Panel7: TPanel; + Panel8: TPanel; + Panel9: TPanel; + ClrErrorLogBtn: TButton; + ErrorLogMemo: TMemo; + Panel3: TPanel; + SpeedButton4: TSpeedButton; + procedure FormPaint(Sender: TObject); + procedure LabRADServer1Connect(Sender: TObject; ID: Cardinal; Welcome: String); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + function LabRADServer1NewContext(Sender: TObject; Context: TLabRADContext; Source: Cardinal): Pointer; + procedure Timer1Timer(Sender: TObject); + procedure SpeedButton1Click(Sender: TObject); + procedure LabRADServer1ExpireContext(Sender: TObject; Context: TLabRADContext; ContextData: Pointer); + procedure SpeedButton2Click(Sender: TObject); + procedure SpeedButton3Click(Sender: TObject); + function LabRADServer1Request(Sender: TObject; Context: TLabRADContext; + ContextData: Pointer; Source, Setting: Cardinal; Data: TLabRADData): TLabRADData; + procedure LabRADServer1Error(Sender: TObject; Error: String); + procedure ClrErrorLogBtnClick(Sender: TObject); + procedure LabRADServer1Disconnect(Sender: TObject); + procedure SpeedButton4Click(Sender: TObject); + procedure OnManagerResponse(Sender: TObject; + const Packet: TLabRADPacket; Data: Integer); + procedure OnSelfResponse(Sender: TObject; const Packet: TLabRADPacket; + Data: Integer); + + private + { Private declarations } + fDevices: array of TAdapterForm; + fDbgTimeouts: Boolean; + + public + { Public declarations } + end; + +var + MainForm: TMainForm; + Quitting: Boolean; + +implementation + +{$R *.dfm} + +uses Errors, PCap, GetMAC, Triggers; + +procedure TMainForm.FormPaint(Sender: TObject); +var alldevs, d: ppcap_if_t; + errbuf: pcap_errorchar; + index: integer; +begin + Quitting:=false; + OnPaint:=nil; + if not PCapAvailable then begin + Application.MessageBox('Please install the WinPcap library (available at www.winpcap.org)!', 'ERROR: WinPcap Not Found', MB_ICONERROR + MB_OK); + Application.Terminate; + end; + if pcap_findalldevs_ex('rpcap://'#0, nil, alldevs, errbuf)<>0 then begin + Application.MessageBox('Cannot list WinPcap devices', 'ERROR: WinPcap Error', MB_ICONERROR + MB_OK); + Application.Terminate; + end; + d:=alldevs; + setlength(fDevices, 0); + index:=0; + while assigned(d) do begin + if assigned(d.address) then begin + setlength(fDevices, length(fDevices)+1); + fDevices[high(fDevices)]:=TAdapterForm.Create(nil); + fDevices[high(fDevices)].Show; + fDevices[high(fDevices)].Caption:=' Adapter '+inttostr(high(fDevices))+': '+d^.description; + fDevices[high(fDevices)].ANamePanel.Caption:=' '+d^.description; + fDevices[high(fDevices)].MACPanel.Caption:=' '+GetMACAddress(d^.description); + if fDevices[high(fDevices)].MACPanel.Caption=' ' then fDevices[high(fDevices)].MACPanel.Caption:=' '+GetMACAddress(Index); + if fDevices[high(fDevices)].MACPanel.Caption=' ' then fDevices[high(fDevices)].MACPanel.Caption:=' '; + fDevices[high(fDevices)].Adapter:=high(fDevices); + fDevices[high(fDevices)].IPPanel.Caption:=' '+inttostr(ord(d.address.addr.sin_addr.S_un_b.s_b1))+'.'+ + inttostr(ord(d.address.addr.sin_addr.S_un_b.s_b2))+'.'+ + inttostr(ord(d.address.addr.sin_addr.S_un_b.s_b3))+'.'+ + inttostr(ord(d.address.addr.sin_addr.S_un_b.s_b4)); + fDevices[high(fDevices)].IP[0]:=ord(d.address.addr.sin_addr.S_un_b.s_b1); + fDevices[high(fDevices)].IP[1]:=ord(d.address.addr.sin_addr.S_un_b.s_b2); + fDevices[high(fDevices)].IP[2]:=ord(d.address.addr.sin_addr.S_un_b.s_b3); + fDevices[high(fDevices)].IP[3]:=ord(d.address.addr.sin_addr.S_un_b.s_b4); + fDevices[high(fDevices)].Handle:=pcap_open(d.name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1, nil, errbuf); + fDevices[high(fDevices)].RunLoop; + end; + d:=d.next; + inc(index); + end; + pcap_freealldevs(alldevs); + LabRADServer1.Active:=True; +end; + +procedure TMainForm.LabRADServer1Connect(Sender: TObject; ID: Cardinal; Welcome: String); +begin + LabRADServer1.RegisterSetting(1, 'Adapters', + 'Retrieves a list of available network adapters', + [''], + ['*(ws): List of indices and names of adapters'], + ''); + LabRADServer1.RegisterSetting(10, 'Connect', + 'Connects to a network adapter', + ['w: Connect by index', + 's: Connect by name'], + ['s: Adapter name'], + 'After connecting to an adapter, packet filters should be added followed by a request to Listen.'); + LabRADServer1.RegisterSetting(20, 'Listen', + 'Starts listening for packets', + [''], + [''], + ''); + LabRADServer1.RegisterSetting(30, 'Timeout', + 'Sets the timeout for read operations', + ['v[d]'], + [''], + ''); + LabRADServer1.RegisterSetting(40, 'Collect', + 'Waits for packets to arrive, but doesn''t return them yet. After this call completes, a call to "Read" or '+ + '"Read as Words" or "Discard" with the same parameter will complete immediately.', + [' : Wait for one packet', + 'w: Wait for this number of packets'], + [''], + 'This setting is useful for pipelining since it allows a client to wait for the completion of a task that '+ + 'returns a lot of data and start the next task before retrieving the data generated in the first task.'); + LabRADServer1.RegisterSetting(50, 'Read', + 'Reads packets', + [' : Read one packet (returns (ssis))', + 'w: Read this number of packets (returns *(ssis))'], + ['(ssis): Source MAC, Destination MAC, Ether Type (-1 for IEEE 802.3), and Data of received packet', + '*(ssis): List of Source MAC, Destination MAC, Ether Type (-1 for IEEE 802.3), and Data of received packets'], + ''); + LabRADServer1.RegisterSetting(51, 'Read as Words', + 'Reads packets', + [' : Read one packet (returns (ssi*w))', + 'w: Read this number of packets (returns *(ssi*w))'], + ['(ssi*w): Source MAC, Destination MAC, Ether Type (-1 for IEEE 802.3), and Data of received packet', + '*(ssi*w): List of Source MAC, Destination MAC, Ether Type (-1 for IEEE 802.3), and Data of received packets'], + ''); + LabRADServer1.RegisterSetting(52, 'Discard', + 'Waits for packets and deletes them from the queue', + [' : Discard one packet', + 'w: Discard this number of packets'], + [''], + 'This setting behaves exactly like "Read", except it does not return the content of the read packets'); + LabRADServer1.RegisterSetting(55, 'Clear', + 'Clears all pending packets out of the buffer', + [''], + [''], + ''); + LabRADServer1.RegisterSetting(60, 'Source MAC', + 'Sets the Source MAC to be used for following Write''s', + [' : Use adapter MAC as source (default)', + 's: Source MAC as 01:23:45:67:89:AB', + '(wwwwww): MAC as individual numbers'], + ['s'], + ''); + LabRADServer1.RegisterSetting(61, 'Destination MAC', + 'Sets the Destination MAC to be used for following Write''s', + ['s: Destination MAC as 01:23:45:67:89:AB', + '(wwwwww): MAC as individual numbers'], + ['s'], + ''); + LabRADServer1.RegisterSetting(62, 'Ether Type', + 'Sets the Ether Type to be used for following Write''s', + [' : Packet is IEEE 802.3 packet, Ether Type is taken from data length', + 'i: Use this ether type'], + [''], + ''); + LabRADServer1.RegisterSetting(65, 'Write', + 'Sends packets', + ['s: Sends this data as one packet', + '*w: Same, except data is specified as an array of words'], + [''], + ''); + LabRADServer1.RegisterSetting(100, 'Require Source MAC', + 'Sets the Source MAC that a packet has to match to be accepted', + ['s: MAC in string form: 01:23:45:67:89:AB', + '(wwwwww): MAC as individual numbers'], + ['s'], + ''); + LabRADServer1.RegisterSetting(101, 'Reject Source MAC', + 'If a packet''s Source MAC matches, it will be rejected', + ['s: MAC in string form: 01:23:45:67:89:AB', + '(wwwwww): MAC as individual numbers'], + ['s'], + ''); + LabRADServer1.RegisterSetting(110, 'Require Destination MAC', + 'Sets the Destination MAC that a packet has to match to be accepted', + ['s: MAC in string form: 01:23:45:67:89:AB', + '(wwwwww): MAC as individual numbers'], + ['s'], + ''); + LabRADServer1.RegisterSetting(111, 'Reject Destination MAC', + 'If a packet''s Destination MAC matches, it will be rejected', + ['s: MAC in string form: 01:23:45:67:89:AB', + '(wwwwww): MAC as individual numbers'], + ['s'], + ''); + LabRADServer1.RegisterSetting(120, 'Require Length', + 'Only packets of this length will be accepted', + ['w: Packet length in bytes'], + [''], + ''); + LabRADServer1.RegisterSetting(121, 'Reject Length', + 'Packets of this length will be rejected', + ['w: Packet length in bytes'], + [''], + ''); + LabRADServer1.RegisterSetting(130, 'Require Ether Type', + 'Only packets with this Ether Type will be accepted', + ['i: Protocol ID (-1 for raw IEEE 802.3, for others check EtherType on Wikipedia)'], + [''], + ''); + LabRADServer1.RegisterSetting(131, 'Reject Ether Type', + 'Packets with this Ether Type will be rejected', + ['i: Protocol ID (-1 for raw IEEE 802.3, for others check EtherType on Wikipedia)'], + [''], + ''); + LabRADServer1.RegisterSetting(140, 'Require Content', + 'The packet content needs to match for the packet to be accepted', + ['(ws): Offset and Data', + '(w*w): Offset and Data'], + [''], + ''); + LabRADServer1.RegisterSetting(141, 'Reject Content', + 'If the packet content matches, the packet will be rejected', + ['(ws): Offset and Data', + '(w*w): Offset and Data'], + [''], + ''); + LabRADServer1.RegisterSetting(200, 'Send Trigger', + 'Sends a trigger signal to the specified context to release it from a "Wait For Trigger" call.', + ['(w, w): Target context'], + [''], + 'This setting helps to control timing between different contexts to assist pipelining. '+ + 'If this trigger is the final one missing to release a "Wait For Trigger" call, '+ + 'execution is passed into the waiting Context before the call to this setting completes.'); + LabRADServer1.RegisterSetting(201, 'Wait For Trigger', + 'Waits for trigger signals to be sent to this context with "Send Trigger".', + [' : Wait for one trigger signal', + 'w: Wait for this number of trigger signals'], + ['v[s]: Elapsed wait time'], + 'This setting helps to control timing between different contexts to assist pipelining. '+ + 'The return value can be used to investigate performance of pipelined operations. '+ + 'If all required triggers had already been received before this setting was called, '+ + 'the return value is 0s and most likely indicates that the pipe was no longer filled.'); + LabRADServer1.StartServing; +end; + +function GetString(Data: TLabRADData): string; +var a: integer; +begin + Result:=''; + if Data.IsString then Result:=Data.GetString; + if Data.IsArray then + for a:=1 to Data.GetArraySize[0] do + Result:=Result+Chr(Data.GetWord(a-1)); +end; + +procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +var a: integer; +begin + Quitting:=true; + for a:=1 to length(fDevices) do + pcap_breakloop(fDevices[a-1].Handle); + LabRADServer1.Active:=False; +end; + +function TMainForm.LabRADServer1NewContext(Sender: TObject; Context: TLabRADContext; Source: Cardinal): Pointer; +begin + Result:=TDEContext.Create(Context, LabRADServer1); +end; + +procedure TMainForm.Timer1Timer(Sender: TObject); +var Ctxts: TLabRADContextDataArray; + D: TDateTime; + a: integer; +begin + D:=now; + Ctxts:=LabRADServer1.AllContexts; + for a:=1 to length(Ctxts) do + TDEContext(Ctxts[a-1]).CheckTimeout(D); + if fDbgTimeouts then begin + ErrorLogMemo.Lines.Add('<- Context timeouts operational'); + fDbgTimeouts:=False; + end; +end; + +procedure TMainForm.SpeedButton1Click(Sender: TObject); begin TileMode:=tbVertical; Tile; end; +procedure TMainForm.SpeedButton2Click(Sender: TObject); begin TileMode:=tbHorizontal; Tile; end; +procedure TMainForm.SpeedButton3Click(Sender: TObject); begin Cascade; end; + +procedure TMainForm.LabRADServer1ExpireContext(Sender: TObject; Context: TLabRADContext; ContextData: Pointer); +var Ctxt: TDEContext; +begin + CleanupTrigger(Context); + Ctxt:=ContextData; + if not assigned(Ctxt) then exit; + if (Ctxt.Adapter>=0) and (Ctxt.Adapter=length(fDevices)) then raise EUnknownAdapterError(a); + end else begin + a:=0; + while (aData.GetString) do inc(a); + if a=length(fDevices) then raise EUnknownAdapterError(Data.GetString); + end; + if (Ctxt.Adapter>=0) and (Ctxt.Adapter=0) and (Ctxt.Adapter=length(fDevices)) then raise ENotConnectedError.Create; + if not Ctxt.DestMAC.Valid then raise ENoDestinationMACError.Create; + fDevices[Ctxt.Adapter].Send(Ctxt.SourceMAC, Ctxt.DestMAC, GetString(Data), Ctxt.EtherType); + inc(Ctxt.Sent); + Ctxt.LastSent:=trunc(now*24*3600*2)*2; + Result:=TLabRADData.Create; + end; + + 100, 101, 110, 111: // MAC Filtering + begin + if Data.IsString then begin + s:=Data.GetString; + end else begin + MAC.Valid:=true; + for a:=0 to 5 do MAC.MAC[a]:=Data.GetWord(a); + s:=MACToStr(MAC); + end; + Ctxt.AddFilter(TMACFilter.Create(s, Setting in [100,101], Setting in [101,111])); + Result:=TLabRADData.Create('s'); + Result.SetString(s); + end; + + 120, 121: // Length Filter + begin + Ctxt.AddFilter(TLengthFilter.Create(Data.GetWord, Setting=121)); + Result:=TLabRADData.Create; + end; + + 130, 131: // Ether Type Filter + begin + Ctxt.AddFilter(TProtocolFilter.Create(Data.GetInteger, Setting=131)); + Result:=TLabRADData.Create; + end; + + 140, 141: // Content Filter + begin + if Data.IsString(1) then begin + s:=Data.GetString(1); + end else begin + setlength(s, Data.GetArraySize(1)[0]); + for a:=1 to length(s) do + s[a]:=chr(Data.GetWord([1,a-1])); + end; + Ctxt.AddFilter(TContentFilter.Create(Data.GetWord(0), s, Setting=131)); + Result:=TLabRADData.Create; + end; + + 200: // Send Trigger + begin + a:=Data.GetWord(0); + if a=0 then a:=Source; + SendTrigger(a, Data.GetWord(1)); + Result:=TLabRADData.Create; + end; + + 201: // Wait For Trigger + begin + if Data.IsWord then a:=Data.GetWord else a:=1; + Result:=WaitForTrigger(Context, a); + end; + else + raise EUnknownSettingError.Create(Setting); + end; +end; + +procedure TMainForm.LabRADServer1Error(Sender: TObject; Error: String); +begin + LogPanel.Visible:=true; + ErrorLogMemo.Lines.Add(Error); +end; + +procedure TMainForm.ClrErrorLogBtnClick(Sender: TObject); +begin + ErrorLogMemo.Lines.Clear; + LogPanel.Visible:=false; +end; + +procedure TMainForm.LabRADServer1Disconnect(Sender: TObject); +begin + LogPanel.Visible:=true; + ErrorLogMemo.Lines.Add('Disconnected'); +end; + +procedure TMainForm.SpeedButton4Click(Sender: TObject); +var Pkt: TLabRADPacket; + a: integer; +begin + LogPanel.Visible:=true; + + ErrorLogMemo.Lines.Add('-> Checking context timeouts...'); + fDbgTimeouts:=True; + + for a:=1 to length(fDevices) do begin + ErrorLogMemo.Lines.Add('-> Pinging Adapter '+inttostr(fDevices[a-1].Adapter)+' Message Loop...'); + fDevices[a-1].PacketQueue.Send(12345); + ErrorLogMemo.Lines.Add('-> Checking Adapter '+inttostr(fDevices[a-1].Adapter)+' Updates...'); + fDevices[a-1].fDbgTimeouts:=True; + end; + + ErrorLogMemo.Lines.Add('-> Pinging LabRAD Manager...'); + Pkt:=TLabRADPacket.Create(0,1,1,1); + Pkt.AddRecord(10); + LabRADServer1.Request(Pkt, OnManagerResponse); + + ErrorLogMemo.Lines.Add('-> Pinging Myself...'); + Pkt:=TLabRADPacket.Create(0,1,1,LabRADServer1.ID); + Pkt.AddRecord(1); + LabRADServer1.Request(Pkt, OnSelfResponse); +end; + +procedure TMainForm.OnManagerResponse(Sender: TObject; + const Packet: TLabRADPacket; Data: Integer); +begin + LogPanel.Visible:=true; + ErrorLogMemo.Lines.Add('<- LabRAD Manager reachable'); +end; + +procedure TMainForm.OnSelfResponse(Sender: TObject; + const Packet: TLabRADPacket; Data: Integer); +begin + LogPanel.Visible:=true; + ErrorLogMemo.Lines.Add('<- Myself reachable'); +end; + +end. diff --git a/DirectEthernetServer/Packets.pas b/DirectEthernetServer/Packets.pas new file mode 100755 index 0000000..a47c0da --- /dev/null +++ b/DirectEthernetServer/Packets.pas @@ -0,0 +1,83 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +unit Packets; + +interface + + uses LabRADSharedObjects; + + type + TParsedPacket = class(TLabRADSharedObject) + private + fRaw: string; + fSource: string; + fDest: string; + fID: integer; + fData: string; + fParsed: boolean; + + public + constructor Create(Data: pointer; Size: integer); reintroduce; overload; + + property Source: string read fSource; + property Destination: string read fDest; + property ID: integer read fID; + property Data: string read fData; + property Raw: string read fRaw; + property Parsed: boolean read fParsed; + end; + +implementation + +uses Filters; + +constructor TParsedPacket.Create(Data: pointer; Size: integer); +var ID: word; + MAC: TMAC; +begin + inherited Create; + setlength(fRaw, Size); + if Size>0 then move(Data^, fRaw[1], Size); + if Size<14 then begin + fSource:=''; + fDest :=''; + fID :=0; + fData :=''; + fParsed:=False; + exit; + end; + move(fRaw[13], ID, 2); + ID:=swap(ID); + if (ID<1518) and (Size<>ID+14) then begin + fSource:=''; + fDest :=''; + fID :=0; + fData :=''; + fParsed:=False; + exit; + end; + MAC.Valid:=True; + move(fRaw[1], MAC.MAC[0], 6); + fDest:=MACtoStr(MAC); + move(fRaw[7], MAC.MAC[0], 6); + fSource:=MACtoStr(MAC); + if (ID<1518) then fID:=-1 else fID:=ID; + setlength(fData, Size-14); + if Size>14 then move(fRaw[15], fData[1], Size-14); + fParsed:=True; +end; + +end. diff --git a/DirectEthernetServer/Triggers.pas b/DirectEthernetServer/Triggers.pas new file mode 100755 index 0000000..77e6208 --- /dev/null +++ b/DirectEthernetServer/Triggers.pas @@ -0,0 +1,114 @@ +{ Copyright (C) 2008 Markus Ansmann + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . } + +unit Triggers; + +interface + + uses LabRADDataStructures; + + procedure SendTrigger (CtxtHigh, CtxtLow: Cardinal); + function WaitForTrigger(Context: TLabRADContext; Count: Cardinal): TLabRADData; + procedure CleanupTrigger(Context: TLabRADContext); + function IsWaiting(Context: TLabRADContext): Boolean; + +implementation + +uses Main, SysUtils; + +type + TContextTriggers = record + Context: TLabRADContext; + Count: integer; + Start: TDateTime; + end; + +var + TriggerInfos: array of TContextTriggers; + +procedure SendTrigger(CtxtHigh, CtxtLow: Cardinal); +var a: integer; + D: TLabRADData; +begin + a:=0; + while (aCtxtHigh) or + (TriggerInfos[a].Context.Low <>CtxtLow)) do inc(a); + if a=length(TriggerInfos) then begin + setlength(TriggerInfos, a+1); + TriggerInfos[a].Context.High:=CtxtHigh; + TriggerInfos[a].Context.Low :=CtxtLow; + TriggerInfos[a].Count :=1; + end else begin + TriggerInfos[a].Count:=TriggerInfos[a].Count+1; + if TriggerInfos[a].Count=0 then begin + D:=TLabRADData.Create('v[s]'); + D.SetValue((now-TriggerInfos[a].Start)*24*3600); + MainForm.LabRADServer1.SendReply(TriggerInfos[a].Context, D); + end; + end; +end; + +function WaitForTrigger(Context: TLabRADContext; Count: Cardinal): TLabRADData; +var a: integer; +begin + if Count=0 then begin + Result:=TLabRADData.Create('v[s]'); + Result.SetValue(0); + exit; + end; + Result:=nil; + a:=0; + while (aContext.High) or + (TriggerInfos[a].Context.Low <>Context.Low)) do inc(a); + if a=length(TriggerInfos) then begin + setlength(TriggerInfos, a+1); + TriggerInfos[a].Context:=Context; + TriggerInfos[a].Count :=-Count; + TriggerInfos[a].Start :=now; + end else begin + TriggerInfos[a].Count :=TriggerInfos[a].Count-Count; + if TriggerInfos[a].Count>=0 then begin + Result:=TLabRADData.Create('v[s]'); + Result.SetValue(0); + end else begin + TriggerInfos[a].Start:=now; + end; + end; +end; + +procedure CleanupTrigger(Context: TLabRADContext); +var a: integer; +begin + a:=0; + while (aContext.High) or + (TriggerInfos[a].Context.Low <>Context.Low)) do inc(a); + if a=length(TriggerInfos) then exit; + for a:=a+1 to high(TriggerInfos) do + TriggerInfos[a-1]:=TriggerInfos[a]; + setlength(TriggerInfos, length(TriggerInfos)-1); +end; + +function IsWaiting(Context: TLabRADContext): Boolean; +var a: integer; +begin + Result:=False; + a:=0; + while (aContext.High) or + (TriggerInfos[a].Context.Low <>Context.Low)) do inc(a); + if a=length(TriggerInfos) then exit; + Result:=TriggerInfos[a].Count<0; +end; + +end. diff --git a/DirectEthernetServer/link_idle.bmp b/DirectEthernetServer/link_idle.bmp new file mode 100755 index 0000000000000000000000000000000000000000..42bb411bc228bf255b20bdfec9e2b14ff5cdd863 GIT binary patch literal 822 zcmb7>!G^<76oxxyKV~_PFi+42m|f{CN`(lORg`S1RH+amM5qvRsiekN9mt_f2u#zO%Y&H~wAOKIC&u5te5={W6X<|dyb-Yo*54Wai z&}BUNcDuzxTf~*{55=-9S{x3Cs;aPo9|B}u*DaoeaVC?As;cAhm?bbH0hi6(Z5|JT zj)Kq>hUtY3rehVdLuApBdy((=dj@RRXxla{G4FD@BzGJ~rZi21GEV4)Rf1k(|Ma4c zPXuKO{|*>S1|}L^d702ztyVnAcyhY1DAZUcub$^&jKDwB-GRG4{{=>bpYka64Rs49 AKL7v# literal 0 HcmV?d00001 diff --git a/DirectEthernetServer/link_idle_no_listen.bmp b/DirectEthernetServer/link_idle_no_listen.bmp new file mode 100755 index 0000000000000000000000000000000000000000..29673f0181abcbdf1ac08bf38f56da8c76375bff GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C76%bW_#hZ2@N^VVH3YVA-@bnR`n7A zr)TNXr3)4;m^W`;eSJMpS9W%GT3T9pc{z~X)YOEm<;IO0K$C$kS+QaTPzw+M?E-29 ziU92bl0bI?4Mf&*?%X+`vcA4PpfZR>V0{Z9=2TTx0i}@D1KB`ZfB^+Gt+TTeDBIrN a4s;k00NoGt9hzcXT#^(64FN_9rcnTXN^uMT literal 0 HcmV?d00001 diff --git a/DirectEthernetServer/link_idle_no_listen_stop.bmp b/DirectEthernetServer/link_idle_no_listen_stop.bmp new file mode 100755 index 0000000000000000000000000000000000000000..5a6b10d7982da570570d8f13bfba06e706384a77 GIT binary patch literal 1334 zcmeH_PiT^H7{`BZx_3?Ys^w<7_Q$QveB0J+YOlRpuWPGT)14z6(W35=5TbbzL=Zvr zB7#U_h@eIxZ;f4~-2%Odmt6)z>=KMFJAHfKSvz#@66_1#hu`OU9=?Z%--^efASZIj z39*PT&2P)dU~eGSJ-TNi6G1W|pePD7O@m<=*laeiEDNprG0ZcsV70yl&-3v4eDM4I z2m}HM27?HNLI{V$7*Z6Vq~1ZJEI_Mz4^_VaS|Ny;J22`$V#4qNlg2MFjqSj_l*HDP zDxPkA!i((+UT#;>r|CdGx(~Bu56tXWIGx`>^oJn2pU{p215;fXm_ryW!1UY!O!EN0 z{vDf}z_aH+@cPXWB9RE9(I{fE7~=6b5{U$o$s|w>K5GMNmr*(`Fo9P;@*3WWlS z#Ue_j63XQ=DwPUqwHoU6Is`!wGmcQL9^>=wF&d2qn$0F!trpttHaeXSy4@}$Nw+)m z*$w{ZKj8TndU%cy`GeD>N0ffVINpES7@KA+Q=^v@(!%PBo7c=+%~wnYnZyeV!%E#f zuh)BRq)%dpbIEmnZSLyz*$YDw-(6hhCN8htzcDjFOT6J??{JeBb=tvO%0;QM&e?A- ea~$VlRd$Iz8>{S1yG^YgcAns$@)vsCy}>Vo`>$#M literal 0 HcmV?d00001 diff --git a/DirectEthernetServer/link_idle_stop.bmp b/DirectEthernetServer/link_idle_stop.bmp new file mode 100755 index 0000000000000000000000000000000000000000..0b70f4ff65ef07cd7c7d27d5830f658b2259f3e6 GIT binary patch literal 1334 zcmeH{-%DCy7{`y*$(EH`o$A=KansS5pUmMCIL_7#02#_QRi9`a5qCnF$R4Ns8IvwOv2bArvpiz6E z(Rg7to58XyIF5tOW`o^shr{83)9HlE<-+{@Jlt+K78e(>w6uifDp2 z@OV7%dcE-Ze5fT8kci(xCP_eE_YRHHG@9z)qpmWC2J$1s;xACrAJD1z4E=Bj243!k z3|=nmqC!?cRm*qu_8mame}JK(Zy;KaK{Wq{yaTB2DuUJ?gH{8ofgkAB0ebUKSgpYG z7r*fO%?bQ|Ki1dR5eNhj3Rqv$>l{7Ode=M*@cjtEh8XB@tqwEBL``1?M+ zFWWU=Z4$pdmtju{!-__Yi$_-?Yk7Y%;>$jsKUdv;o_GCo*75r(i|>aFzwcN7vP1aG zE{ThM46EwY@7_3$tmVtefS-r?zU<|E+RJdGmEl}H$ZcX=4?d#XCU%PhgDlh=5{Bki9t{%v^ zyEFDoEyKZbhOPOaKxhGjnwpx@($bkTXCkYdIB_D7`{+dDgCk9M4>#P{SATg|9Z+!c zut00Gc0phlnw&@LbebSKb2WG&~;odYWC>+1t5 zgIEOCw*X>JRaF&G3Ryjn4YUOqP(afr2yN6vrPg^E!1)Q|E2dO6N?itXYaoVTWBnb);TiDZHdhC;|_ z%%-vyUJz_Lmn7bhM3Qy2C9u>H7!^^NY9yFxCRmi) zy;lqvTS77NG7N?nd@QR7tgi{azaf~{aIvZ*Snc(~uVHsklT6q~0zi%Vf-(ocM9AgUjv#)5!#H#s|2%ni0ks1~+INX~}Ao ziw9649)u&y3TOWnMDnK*6FZH>#LplBHV{7w>`=gkw+>E>4IDlY5%&Y(@jzYb)B?+R)zKj*gBFs8lMb)oOHhcA~4R3*Ft_&}cN!YPHbmbkOVd=E~FTX~FXBJNtQ?7#!Tjm}MJFOG~hRo5hNC9#*Rr z>+9>FgMRz}`nT`E{(tRpYPalVVaQ&$Qxgw{`}_Is3q2v-!LyOc#}kgm^CJSd^|X-^ zb6z1|WmT2u8t&xXE;{c??>;H1mR!Ex&~*2jD~o1XWyM2D uPF6;`d%0H$Z8S^752_^+No9q%m}a@Gw&K3{9-Hk`wu5`=FO=8p4t@hxI2R27 literal 0 HcmV?d00001 diff --git a/DirectEthernetServer/link_send.bmp b/DirectEthernetServer/link_send.bmp new file mode 100755 index 0000000000000000000000000000000000000000..9e406b2b97719b64ea57b4aa9990b450577ad828 GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C76%bW_#hZ2@Du~goH-Li45vV6XJ=Yk8cu0c382ZP zrKJT01z}-ffq{WOK0cnFo_i?i{Mxrz=*hXlZF#x^(G+1qCb)Va1L&Q&xVXs3$dHf_U?4D*-(aXd$53*RA#Z!+q+`e` zZ?(d_-iP;`wUdlN&-3Wm6O4Eehla<;nEtVh;z^2Q6pp0`S^-(9EuH0=Iq(f1u_ zmwL~4#kNlpO<#oDzX07C(2nAxwP#)#^?%|k`=ZtP-Fo6r>z?l>y*~~5zo>V8k?#Q7 zxIeUW7qS&V_Q~t7O4hv9>Uhgg^^~FYE<@dAhKiF6dDj^7&iQm5K~s#2%awD^sRKRP O;8F|}&s_2VQx*UYfg1<_ literal 0 HcmV?d00001 diff --git a/DirectEthernetServer/link_send_no_listen.bmp b/DirectEthernetServer/link_send_no_listen.bmp new file mode 100755 index 0000000000000000000000000000000000000000..abbedd770317969670acb2f5dc72741d6939fcc9 GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C76%bW_#hZ2@N^VVH3S+r-mY75t#0|{>SgC@mYyMK zHbeOhhU#++B?lSuwnt7nhO9oWdn+;*!d7d1B;WAfaN>8h?)MDod;EG%!qqT_%(N(7 z1?NH-MXO$MR=jtZ^3$sCi)Qa9hN5c>*_#+rRxrfPW60mdkh9gLW<9c&lQ&)%_PkYU z{q8#Lr(yR`i@xtbyVQHWE4F=-X!;`D{srjHfc8zuTGpOMYL^+mn|Xyg9S&Rxjrf$WplUzMzRtJU$Aq3S6^>s^Mr%M2AK8S<_%8WN-e8HQ#7Wo2pDi@jiwFWj^>FBmJ9o69zrFO*|z zuKQkf#g<)AtgW%QadU9tMyzscZfuUl*cco8U48rgB>f9oSDx*A&iS14Jm=zho;{X6 z1D|Y}fk%jn$;5xfAw~HHzgMrCyXvYJnj*9Kwk@_~#6KwMwo81!Sv z@d0MfA_~ND@T%6KRE42#{t83;Du^TrQjtYj9Z*=GfK-!&R0SwnHXv^WRJQNX+I}+g zA`sq*fVe{-o)wUBCLfD|Oss+2i-X)xpxBcJbvFxB&nB!^V8oe*+mk{6qh$=t1VN_O zQU35ZWDnAiO=qB-+<>2pxc%Z6TuVu~-=;A6{s+9?4E%l?A3xK0 zx0*yK6hbr_MJyJ>%C{s|;+se$5@3zJlU?ne!T)#zqyNHgG5-tCu`_8%P%f^l;qDZw z_BS=|E0gls1vf5Vx+prTRLJWpI4tX1ny5;aOU5i#@-NJ2m MsDC@l$E*492lRd48~^|S literal 0 HcmV?d00001 diff --git a/DirectEthernetServer/link_send_rec.bmp b/DirectEthernetServer/link_send_rec.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a674c23a5509f4041058d8e083dfe6afb6074989 GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C76%bW_#hZ2@Du}_T%Cp?hEw3&GN(NqtT?4nCGKwb zeXxMx#&m{VMGWh67#626EJ$Wp)g-%TN%oB^M^V*2eRVAQ?FP>8XB@tqwEBL``1?M+ zFWWU=Z4$pdmtju{!-__Yi$_-?Yk7Y%;>$jsKUdv;o_GCo*75r(i|>aFzwcN7vP1aG zE{ThM46EwY@7_3$tmVtefS-r?zU<|E+RJdGmEl}H$ZcXu)wUUsf#=^3EPFBdc6 z>Vb^AJ7dq(G8`;t*qRRt1cve(4AtitN)9sQZI7IE3|VDd_tr;1aH8?Sk*2$c8*c2Y zzr3qXt?`k3!+XPt-_^R`Gop2P6!Wc5sqI4CU3t<$kdc|4s-eJm5tG+Lqy`LD0 zt}$e9Vn|uR5I2t@e-}f}R+pOf$XZU`cwyM{R;l&7>$IPS-9Ih*z60%2@APEw$@KOnU@%ZyY2?y=!IgT!cMXCc4-4!~f>EPj*qqCFvtaV5VCs0VvnUvD&tT-#3I^LW z-0KmzE(#ueA-Mawnwd+2nSlk&ejkT4mWX#G73oF_l0A*zE@$Gqm5+2Y8|mjf}s;?d}K9A6(`e6WFOyBXKm3H(##c<=1N=cr{_ z%9kiteMX$(3b8R?p^P6QAz>JG@?{dEY^W4Jp;X#goMuD4^d=SS`w)#bMAI)+n1+Z< zauL16O^#*)?dl11>!uK?Uc@4a!_K=)zA6m;SMb=reJN)E!NoYI$tnHnnuvenY>Zi0vqNqDS$(aB}eSXUN0_^CT zL~n7@a@C3X+BD|D`;_+w*nA})Y^2mScfBZMz;CyI`!!pl>OXgiji&iX4QY}bKUDF$i z&t$GESe>7jy*xR+Q!bv(dMZW;#gi*nEnRq4F4ihb_2qF<8JgThC34=fqvoaU8xx{) zwCc33w$>BR9e8DD^$VLL7NthzbpYby5+c2n!mCLLigLh>eX!rBb0*tI=pQ==FNS6_?qz zxeA@O0fWJS(P*Tgpn$@{LW+utC@wChw6v76vNFoc%c-cSpt7i%fj*-0SCE3SZ5xwl1Qm^^VEcM|78aI;4Ils0-Wp$aO0oBV058S^48Qi_@pzb?o@VL~A5(L0@p`>Tkp9O1{BOTO%L>e)wpy!_R#j-a zL8XX`jY%>!t=QTdHPv^_x2x7Glyy>Y_vW{eLdZ7Vyron=kOE88_MJPT!#A34CwwD$ zZQ8*DAM8qvFqzcK`me8C-f|{$f5yI)u*CSaak(EK+oQ3!wzht>bB*nuwf5}iWd++B zPJejlRPs9M?DZ2@OAefDoAdU3Dg})fP8O9He|hnIzV0*0 cw|rOm#V5v`pY7s_fL?EnA( literal 0 HcmV?d00001 diff --git a/DirectEthernetServer/thread_debug.bmp b/DirectEthernetServer/thread_debug.bmp new file mode 100755 index 0000000000000000000000000000000000000000..9d8f513ac879d668694673e2ada9e8005073dcbd GIT binary patch literal 822 zcmZ9J|4S2b7{~1k{n8H_QbfNPK}-a*g6xY#Q1nAYUno{irKKwxv8bS>tfrC9{0)M)48@J87n|Hh2*R|cgxWUvP1V#MCf1)Q(L_F^E@I0S;z2DDspU?F>^#{tf zo_dJYuqw9KzOv(6`(@kT)k2MOuDItN_hK(iub#g!I$ZAZ4$c18$9N^Thk-IOA5SC| zF|+W|Y7K|Oe!ss_rz`KQyM#PEWxdEL+1(PyHh6M$78X4IQjLSji30;qFoGPrAMCxE$!6sRkW$n zToX^FL4p&M+wIQfax_f~f}n9c?w7oVP`7@zvngoN2F%UB+dHU{b7S`pzN=DO;BzFv zB>6wqI`u>HPmuHq-)+LU5w~^4kp{HokhNCI7AB{>1A{|Orz@FEG7KY%;(63?#@Skf zG@rI>Z((mhbz{&*I`DNQ%W`sZ@gT)Es7p6J}Y~WHODRo^44w1MueNCXggaMIsTE$1rSa z$_xDZ`Z~1m`hM-SNTxF|B**ijlBZ%ZxNG>k!1Oeq%KpGGxc5MCb_Z4yDU+8n3veTG jmR(z0TU}iR5=wAj<