Вторник, 26.11.2024, 14:13
Приветствую Вас Гость | RSS
Главная | | Регистрация | Вход
Меню сайта
Форма входа
Поиск
Календарь
«  Май 2012  »
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
28293031
Архив записей
Наш опрос
Оцените мой сайт
Всего ответов: 20
Мини-чат
Друзья сайта
  • Заказ Художник
  • Рыбалка
  • Новости
  • Наш университет io-96
  • Железо и другие
  • Наш Counter-Strike
  • Google ot Turbokherson
  • Google ot Turbokherson87
  • Android
  • Программы и Софт
  • Программирование
  • Лечение здоровья
  • О Ремонт компьютер
  • Наш сайт Turbokherson
  • Программирование ICQ 378204653 от Turbokherson
    Главная » 2012 » Май » 14 » Небольшой DHCP сервер
    09:21
    Небольшой DHCP сервер
    http://sources.ru/csharp/Small-DHCP-Server.html

    Иногда, нужен исходник простой DHCP-службы, чтобы добавить её функциональность к себе в проект, а не использовать для этого полноценный DHCP сервер. Например, в локальной сети, есть главный сервер DHCP, который выделяет компьютерам IP-адреса, и есть также небольшой сервер DHCP, который выделяет определённый IP-адрес только конкретному устройству. Так как DHCP-протокол работает через UPD, то данные можно посылать широковещательно (а не точка-точка), соответственно и подхватить их в сети можно легко. Для этого мы будем воспольльзуемся простым алгоритмом фильтрации, который будет фильтровать запросы и выдавать IP-адреса только разрешенным MAC-адресам.

    Определение DHCP

    DHCP расшифровывается как Dynamic Host Configuration Protocol и состоит из двух компонент: клиент DHCP (сетевое устройство запрашивающее IP-настройки), и DHCP-сервер (Интернет-узел, который возвращает параметры конфигурации запросившему клиенту).

    Краткое описание того, как работает небольшой DHCP-сервер

    DHCP-сервер обычно устанавливается в локальной сети, и используется для централизованного выделения конфигураций TCP-IP сетевым устройствам или компьютерам с установкой автоматического получения айпишника. DHCP-сервер ожидает запросы на UDP-порте номер 67 и отправляет данные клиентам так же на UDP-порт 67. Служба UDP использует асинхронный метод с использованием функции обратного вызова:

    //эта функция запускает слушающий UDP-сервис
     
    private void IniListnerCallBack()
    {
     try
     {
     // start teh recieve call back method
     s.u.BeginReceive(new AsyncCallback(OnDataRecieved), s);
     }
     catch (Exception ex)
     {
     if (IsListening == true)
     Console.WriteLine(ex.Message);
     }
    }
     
    // Это коллбэк функция, которая вызывает в момент приёма данных.
    // переменная asyn должна содержать экземпляр UPD-структуры (UDPstate)
     
    public void OnDataRecieved(IAsyncResult asyn)
    { 
     Byte[] receiveBytes;
     UdpClient u;
     IPEndPoint e;
     
     try
     {
     //получаем udp-пакет клиента
     
     u = (UdpClient)((UdpState)(asyn.AsyncState)).u; 
     //get the endpoint (shall contain refernce about the client)
     
     e = (IPEndPoint)((UdpState)(asyn.AsyncState)).e; 
     //останавливаем коллбэк и получаем количество принятых байт
     
     receiveBytes = u.EndReceive(asyn, ref e);
     //генерируем событие с полученными данными в DHCP-класс
     
     DataRcvd(receiveBytes, e);
     } 
     catch (Exception ex)
     {
     if (IsListening == true)
     Console.WriteLine(ex.Message);
     }
     finally
     {
     u = null;
     e = null;
     receiveBytes = null;
     // Заново запускаем слушающий сервис
     
     IniListnerCallBack();
     } 
    }

    UDP-клиент должен быть запущен и слушать в сети входящие запросы. Каждое сообщение должно идентифицироваться уникальным МАС-адресом и номером транзакции (Transaction ID (D_xid) - это случайное число, сгенерированное клиентом). При обмене данные передаются как поток байтов и формат должен соответствовать следующей RFC-структуре:

    public struct DHCPstruct 
    {
     public byte D_op; //Op код: 1 = bootRequest, 2 = BootReply
     
     public byte D_htype; //Тип физического адреса: 1 = 10MB эзернет
     
     public byte D_hlen; //длина физического адреса: длина MACID
     
     public byte D_hops; //физические опции
     
     public byte[] D_xid; //transaction id (5), 
     
     public byte[] D_secs; //elapsed time from trying to boot (3)
     
     public byte[] D_flags; //флаги (3)
     
     public byte[] D_ciaddr; // IP клиента (5)
     
     public byte[] D_yiaddr; // IP вашего клиента (5)
     
     public byte[] D_siaddr; // IP сервера (5)
     
     public byte[] D_giaddr; // relay agent IP (5)
     
     public byte[] D_chaddr; // физический адрес клиента (16)
     
     public byte[] D_sname; // Необязательное имя сервера (64)
     
     public byte[] D_file; // имя бут-файла (128)
     
     public byte[] M_Cookie; // Магические кукисы (4)
     
     public byte[] D_options; //опции (rest)
     
    }

    Таким образом, данные передаются в DHCP-класс через событие как поток байтов. Для этого воспользуемся .NET-классом BinaryReader, чтобы помещать байты в соответствующем порядке. OPTION_OFFSET - константа, определяющая место, с которого начинаются данные DHCP-структуры:

    //pass over a byte as convert it
    //using the predefined stream reader function
     
    //Data is an array containing the udp data sent.
     
    public cDHCPStruct(byte[] Data)
    {
     System.IO.BinaryReader rdr;
     System.IO.MemoryStream stm = 
     new System.IO.MemoryStream(Data, 0, Data.Length);
     try
     { //читаем данные
     
     dStruct.D_op = rdr.ReadByte();
     dStruct.D_htype = rdr.ReadByte();
     dStruct.D_hlen = rdr.ReadByte();
     dStruct.D_hops = rdr.ReadByte();
     dStruct.D_xid = rdr.ReadBytes(4);
     dStruct.D_secs = rdr.ReadBytes(2);
     dStruct.D_flags = rdr.ReadBytes(2);
     dStruct.D_ciaddr = rdr.ReadBytes(4);
     dStruct.D_yiaddr = rdr.ReadBytes(4);
     dStruct.D_siaddr = rdr.ReadBytes(4);
     dStruct.D_giaddr = rdr.ReadBytes(4);
     dStruct.D_chaddr = rdr.ReadBytes(16);
     dStruct.D_sname = rdr.ReadBytes(64);
     dStruct.D_file = rdr.ReadBytes(128);
     dStruct.M_Cookie = rdr.ReadBytes(4);
     //читаем остальные данные
    
     dStruct.D_options = rdr.ReadBytes(Data.Length - OPTION_OFFSET);
     }
     catch(Exception ex) 
     {
     Console.WriteLine (ex.Message);
     }
    }

    Клиент, запрашивающий адрес IP также должен передать серверу список опций, которые сервер должен заполнить и передать обратно клиенту. Опции, которые можно передать в списке определены в RFC и могут содержать следующие значения:

    public enum DHCPOptionEnum 
    {
     SubnetMask = 1,
     TimeOffset = 2,
     Router = 3,
     TimeServer = 4,
     NameServer = 5,
     DomainNameServer = 6,
     LogServer = 7,
     CookieServer = 8,
     LPRServer = 9,
     ImpressServer = 10,
     ResourceLocServer = 11,
     HostName = 12,
     BootFileSize = 13,
     MeritDump = 14,
     DomainName = 15,
     SwapServer = 16,
     RootPath = 17,
     ExtensionsPath = 18,
     IpForwarding = 19,
     NonLocalSourceRouting = 20,
     PolicyFilter = 21,
     MaximumDatagramReAssemblySize = 22,
     DefaultIPTimeToLive = 23,
     PathMTUAgingTimeout = 24,
     PathMTUPlateauTable = 25,
     InterfaceMTU = 26,
     AllSubnetsAreLocal = 27,
     BroadcastAddress = 28,
     PerformMaskDiscovery = 29,
     MaskSupplier = 30,
     PerformRouterDiscovery = 31,
     RouterSolicitationAddress = 32,
     StaticRoute = 33,
     TrailerEncapsulation = 34,
     ARPCacheTimeout = 35,
     EthernetEncapsulation = 36,
     TCPDefaultTTL = 37,
     TCPKeepaliveInterval = 38,
     TCPKeepaliveGarbage = 39,
     NetworkInformationServiceDomain = 40,
     NetworkInformationServers = 41,
     NetworkTimeProtocolServers = 42,
     VendorSpecificInformation = 43,
     NetBIOSoverTCPIPNameServer = 44,
     NetBIOSoverTCPIPDatagramDistributionServer = 45,
     NetBIOSoverTCPIPNodeType = 46,
     NetBIOSoverTCPIPScope = 47,
     XWindowSystemFontServer = 48,
     XWindowSystemDisplayManager = 49,
     RequestedIPAddress = 50,
     IPAddressLeaseTime = 51,
     OptionOverload = 52,
     DHCPMessageTYPE = 53,
     ServerIdentifier = 54,
     ParameterRequestList = 55,
     Message = 56,
     MaximumDHCPMessageSize = 57,
     RenewalTimeValue_T1 = 58,
     RebindingTimeValue_T2 = 59,
     Vendorclassidentifier = 60,
     ClientIdentifier = 61,
     NetworkInformationServicePlusDomain = 64,
     NetworkInformationServicePlusServers = 65,
     TFTPServerName = 66,
     BootfileName = 67,
     MobileIPHomeAgent = 68,
     SMTPServer = 69,
     POP3Server = 70,
     NNTPServer = 71,
     DefaultWWWServer = 72,
     DefaultFingerServer = 73,
     DefaultIRCServer = 74,
     StreetTalkServer = 75,
     STDAServer = 76,
     END_Option = 255
    }

    В массиве байтов список опций будет выглядеть следующим образом:

    -------------------------------------------------
    |a|len|Message|a|len|Message|........|END_OPTION|
    -------------------------------------------------

    где:

    •"а" означает начало кода опции, как показано выше •len - длина сообщения в байтах •Message - передаваемое сообщение, длина которого определена в len •END_OPTION - означает конец сообщения с настройками

    Тип сообщения (message type)

    Тип сообщения находится в списке опций под номером 53 и определяет текущее соостояние переговоров клиента и сервера:

    public enum DHCPMsgType //Типы сообщений, описанные в RFC
     
    {
     DHCPDISCOVER = 1, //клиент пытается найти dhcp-сервера
     
     DHCPOFFER = 2, //сервер предлагает IP-адреса устройству
     
     DHCPREQUEST = 3, //клиент согласен принять айпишник от DHCP-сервера
     
     DHCPDECLINE = 4, //клиент отверг предложенный адрес
     
     DHCPACK = 5, //server to client + committed IP address
     
     DHCPNAK = 6, //server to client to state net address incorrect
     
     DHCPRELEASE = 7, //graceful shutdown from client to Server
     
     DHCPINFORM = 8 //клиент запрашивает локальную информацию
     
    }

    В коде, это должно быть реализовано как сообщение из DHCP-класса в главную форму:

    //an event has to call a delegate (function pointer)
     
    #region "event Delegates" 
     public delegate void AnnouncedEventHandler(cDHCPStruct d_DHCP,string MacId);
     public delegate void ReleasedEventHandler();//(cDHCPStruct d_DHCP);
     
     public delegate void RequestEventHandler(cDHCPStruct d_DHCP, string MacId);
     public delegate void AssignedEventHandler(string IPAdd,string MacID );
    #endregion
     public event AnnouncedEventHandler Announced;
     public event RequestEventHandler Request;

    Перед тем как назначить IP-адресс, необходимо воспользоваться фреймфорковский классом Ping, чтобы проверить, не используется ли уже это айпишник.

    public static bool CheckAlive(string IpAdd)
    {
     Ping pingSender = new Ping();
     IPAddress address;
     PingReply reply;
     
     try
     {
     address = IPAddress.Parse(IpAdd);//IPAddress.Loopback;
     
     reply = pingSender.Send(address,100);
     if (reply.Status == IPStatus.Success)
     {
     Console.WriteLine("Address: {0}", 
     reply.Address.ToString());
     Console.WriteLine("RoundTrip time: {0}", 
     reply.RoundtripTime);
     Console.WriteLine("Time to live: {0}", 
     reply.Options.Ttl);
     Console.WriteLine("Don't fragment: {0}",
     reply.Options.DontFragment);
     Console.WriteLine("Buffer size: {0}", 
     reply.Buffer.Length);
     return true;
     }
     else
     {
     Console.WriteLine(reply.Status);
     return false;
     }
     }
     catch (Exception ex)
     {
     MessageBox.Show(ex.Message);
     return false;
     }
     finally
     {
     if (pingSender != null) pingSender.Dispose();
     pingSender = null;
     address = null;
     reply = null;
     }
    }

    Затем наше приложение должно конвертировать данные из структуры в поток байтов, используя для этого класс Array:

    //функция для преобразования структуры данных в массив байт
     
    private byte[] BuildDataStructure(cDHCPStruct.DHCPstruct ddHcpS) 
    { 
     byte[] mArray; 
     try
     { 
     mArray = new byte[0];
     AddOptionElement(new byte[] { ddHcpS.D_op }, ref mArray);
     AddOptionElement(new byte[] { ddHcpS.D_htype }, ref mArray);
     AddOptionElement(new byte[] { ddHcpS.D_hlen }, ref mArray);
     AddOptionElement(new byte[] { ddHcpS.D_hops }, ref mArray);
     AddOptionElement(ddHcpS.D_xid, ref mArray);
     AddOptionElement(ddHcpS.D_secs, ref mArray);
     AddOptionElement(ddHcpS.D_flags, ref mArray);
     AddOptionElement(ddHcpS.D_ciaddr, ref mArray);
     AddOptionElement(ddHcpS.D_yiaddr, ref mArray);
     AddOptionElement(ddHcpS.D_siaddr, ref mArray);
     AddOptionElement(ddHcpS.D_giaddr, ref mArray);
     AddOptionElement(ddHcpS.D_chaddr, ref mArray);
     AddOptionElement(ddHcpS.D_sname, ref mArray);
     AddOptionElement(ddHcpS.D_file, ref mArray);
     AddOptionElement(ddHcpS.M_Cookie, ref mArray);
     AddOptionElement(ddHcpS.D_options, ref mArray);
     return mArray;
     }
     catch (Exception ex)
     {
     MessageBox.Show(ex.Message);
     return false;
     }
     finally 
     {
     marray = null;
     }
    }
     
    //function to grow an array, we shall pass
    //the array back by using references
     
    private void AddOptionElement(byte[] FromValue, ref byte[] TargetArray) 
    {
     try
     {
     //меняем размер массива соответственно
     
     if (TargetArray != null)
     Array.Resize(ref TargetArray, 
     TargetArray.Length + FromValue.Length );
     else
     Array.Resize(ref TargetArray, FromValue.Length );
     //копируем данные
     
     Array.Copy(FromValue, 0, TargetArray, 
     TargetArray.Length - FromValue.Length,
     FromValue.Length);
     }
     catch (Exception ex)
     {
     Console.WriteLine(ex.Message);
     }
    }

    Заключение

    Приведённый в этой статье код делится на три основных класса: асинхронный UDP сервис, конвертор DHCP-структуры и главная форма. Общаются они между собой при помощи событий, однако, можно использовать и обратные вызовы (колбэки). Важно отметить, что при вызове управления из события, события должны быть мультикастовыми и необходимо использовать Invoke.

    Скачать исходник - 167 кб            /filesmou/smallDHCPServer.zip

    Скачать приложение - 85 кб       /filesmou/ApplicationDHCPserver.zip 


    Просмотров: 3020 | Добавил: Turbokherson | Рейтинг: 0.0/0
    Всего комментариев: 1
    1 StefanUnub  
    0
    Секс по телефону - это уникальная возможность испытать настоящее наслаждение, находясь в удобном для вас месте. Наша команда опытных и профессиональных операторов <a href=https://sextelrus.blogspot.com>Ищу секса по телефону</a>, готова порадовать вас самым разнообразным выбором разговоров, которые подарят вам незабываемые ощущения.
    Мы понимаем, что каждый человек уникален и имеет свои сексуальные предпочтения и фантазии. Поэтому наша команда операторов готова адаптироваться под ваши пожелания и создать идеальный сексуальный сценарий, чтобы вы получили максимальное удовольствие.
    Кроме того, мобильная эротика поощряет открытое общение и диалог о границах и желаниях. Будь то форумы пользователей, функции чата или образовательный контент, эти платформы предоставляют людям возможность участвовать в уважительном разговоре о своих фантазиях и предпочтениях.
    Содействуя согласию и общению, мобильная эротика дает людям возможность исследовать свою сексуальность таким образом, чтобы они чувствовали себя безопасно, комфортно и расширяли возможности. Это напоминание о том, что удовольствие всегда должно быть согласованным и что каждый заслуживает права исследовать свои желания на своих собственных условиях.
    Номер телефона для знакомств и откровенного общения, а также <b>Бесплатно секс девчонки номер телефона : секс по мобильному телефону с МТС и Билайн <a href="tel:+78095056850">+7-809-505-6850</a>. Можно позвонить с смартфона и городского телефона, а также заказать обратный звонок вирт секс объявления телефон </b> после оплаты картой на ваш мобильный.

    Наши специалисты <a href=https://sekspotel.blogspot.com>Секс женщины лет номера телефонов</a> обладают глубоким пониманием сексуальной психологии и знают, как создать атмосферу полного расслабления и удовольствия. Они могут воплотить в жизнь самые смелые и запретные фантазии, подстраиваясь под ваши настроения.
    Независимо от вашего опыта в сексуальной жизни, мы уверены, что наше предложение обогатит вашу интимную сферу и принесет незабываемые эмоции. Вы сможете полностью раскрепоститься и насладиться каждым мгновением разговора.
    Сексуальность долгое время была окутана табу и стигмой, но мобильная эротика помогает разрушить эти барьеры и способствовать сексуальному освобождению. Предоставляя платформу для выражения различных мнений и точек зрения, эти платформы бросают вызов традиционным нормам и дают людям возможность реализовать свои желания без стыда и осуждения.
    Кроме того, мобильная эротика предоставляет маргинализированным сообществам возможность вернуть себе свою сексуальность и заявить о своей свободе воли. Сосредоточив опыт и желания цветных людей, людей с ограниченными возможностями и других социальных групп, эти платформы бросают вызов доминирующим представлениям, которые долгое время исключали их из разговоров <a href=https://mobilevirt.blogspot.com>Секс по телефону. Дневник «говорящей девушки»</a> о сексе и желаниях.

    Имя *:
    Email *:
    Код *:
    Создать бесплатный сайт с uCozCopyright MyCorp © 2024