Example #1
0
 // コンストラクタ
 // その他のパケットをベースに作成
 public DhcpPacket(DhcpPacket basePacket, DhcpPacket.MessageType message_type, DhcpLeases dhcplease)
     : this()
 {
     if (message_type == MessageType.DHCPOFFER)
     {
         BuildDHCPOFFER(basePacket, dhcplease);
     }
     if (message_type == MessageType.DHCPACK)
     {
         BuildDHCPACK(basePacket, dhcplease);
     }
 }
Example #2
0
        // UDP送信
        private void SendUDP(IPAddress sourceIPAddress, int sourcePort, IPAddress remoteIPAddress, int remotePort)
        {
            // 送信元
            var localEP = new IPEndPoint(sourceIPAddress, sourcePort);
            // 送信先
            var remoteEP = new IPEndPoint(remoteIPAddress, remotePort);
            // 送信データ
            DhcpPacket rcv_packet = new DhcpPacket(this.lastRcvBytes_);

            DhcpPacket.MessageType snd_message_type =
                (rcv_packet.message_type_ == DhcpPacket.MessageType.DHCPDISCOVER)? DhcpPacket.MessageType.DHCPOFFER:
                (rcv_packet.message_type_ == DhcpPacket.MessageType.DHCPREQUEST)? DhcpPacket.MessageType.DHCPACK:
                DhcpPacket.MessageType.unknown;
            if (snd_message_type == DhcpPacket.MessageType.unknown)
            {
                return;
            }
            DhcpPacket snd_packet = new DhcpPacket(rcv_packet, snd_message_type, this.dhcplease_);

            byte[] msg = snd_packet.GetPacketBytes();

            //データを文字列に変換する
            string rcvMsg = "0x" + snd_packet.xid_.ToString("X4") + ", " + snd_packet.message_type_;

            //送信したデータの情報をRichTextBoxに表示する
            string displayMsg = string.Format("{0} [{1} ({2})] > {3}",
                                              DateTime.Now.ToString("HH:mm:ss.fff"), remoteEP.Address, remoteEP.Port, rcvMsg);

            textBoxRcvData.BeginInvoke(
                new Action <string>(ShowReceivedString), displayMsg);

            // 送信イベントデータ
            var ev = new SocketAsyncEventArgs();

            ev.RemoteEndPoint = remoteEP;
            ev.SetBuffer(msg, 0, msg.Length);
            // UDP送信
            var socket = new Socket(SocketType.Dgram, ProtocolType.Udp);

            socket.Bind(localEP);   // bindしたIP、ポートと異なる送信元としたい(場合がある)のでudpClient_は使用しない
            socket.SendToAsync(ev); // 非同期で送信
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }
Example #3
0
        private void BuildDHCPACK(DhcpPacket basePacket, DhcpLeases dhcplease)
        {
            DhcpLeaseItem item = dhcplease.GetItem(basePacket.chaddr_);

            this.op_     = OP.BOOTREPLY;
            this.htype_  = basePacket.htype_;
            this.hlen_   = basePacket.hlen_;
            this.xid_    = basePacket.xid_;
            this.ciaddr_ = basePacket.ciaddr_;
            this.yiaddr_ = item.yiaddr_;
            this.siaddr_ = new IPAddress(0); // 仮
            this.giaddr_ = basePacket.giaddr_;
            this.chaddr_ = basePacket.chaddr_;

            this.options_ = new DhcpOptions(
                DhcpPacket.MessageType.DHCPACK,
                basePacket.chaddr_,
                basePacket.dhcpoption55_,
                dhcplease
                );
        }
Example #4
0
        // 送信パケットを作成
        public byte[] GetPacketBytes()
        {
            List <byte> list = new List <byte>();

            DhcpPacket.addBigEndian(ref list, (byte)(this.op_));
            DhcpPacket.addBigEndian(ref list, this.htype_);
            DhcpPacket.addBigEndian(ref list, this.hlen_);
            DhcpPacket.addBigEndian(ref list, (byte)0);        // hops
            DhcpPacket.addBigEndian(ref list, this.xid_);
            DhcpPacket.addBigEndian(ref list, (UInt16)0);      // secs
            DhcpPacket.addBigEndian(ref list, (UInt16)0x8000); // flags // 決め打ち
            DhcpPacket.addBigEndian(ref list, this.ciaddr_);
            DhcpPacket.addBigEndian(ref list, this.yiaddr_);
            DhcpPacket.addBigEndian(ref list, this.siaddr_);
            DhcpPacket.addBigEndian(ref list, this.giaddr_);
            DhcpPacket.addBigEndian(ref list, this.chaddr_);
            list.AddRange(new byte[64 + 128]);             // sname, file

            list.AddRange(this.options_.GetPacketBytes()); // options

            return(list.ToArray());
        }
Example #5
0
        //データを受信した時
        private void ReceiveCallback(IAsyncResult ar)
        {
            System.Net.Sockets.UdpClient udp =
                (System.Net.Sockets.UdpClient)ar.AsyncState;

            //非同期受信を終了する
            System.Net.IPEndPoint remoteEP = null;
            byte[] rcvBytes;
            try
            {
                rcvBytes = udp.EndReceive(ar, ref remoteEP);
            }
            catch (System.Net.Sockets.SocketException ex)
            {
                Console.WriteLine("受信エラー({0}/{1})",
                                  ex.Message, ex.ErrorCode);
                return;
            }
            catch (ObjectDisposedException ex)
            {
                //すでに閉じている時は終了
                Console.WriteLine("Socketは閉じられています。");
                return;
            }

            // 処理対象?
            DhcpPacket rcv_packet = new DhcpPacket(rcvBytes);
            Boolean    reply      = this.dhcplease_.AutoReply(rcv_packet.chaddr_);
            Boolean    match      = this.dhcplease_.Matches(rcv_packet.chaddr_);

            {
                // 受信情報を控えておく(送信データに載せるため)
                // 受信データ
                lastRcvBytes_ = new byte[rcvBytes.Length];
                Array.Copy(rcvBytes, 0, lastRcvBytes_, 0, rcvBytes.Length);
                // 受信元
                lastRemoteEP_ = remoteEP;
            }

            //データを文字列に変換する
            string rcvMsg = "0x" + rcv_packet.xid_.ToString("X4") + ", " + rcv_packet.message_type_;

            //受信したデータと送信者の情報をRichTextBoxに表示する
            string displayMsg = string.Format("{0} [{1} ({2})] < {3}",
                                              DateTime.Now.ToString("HH:mm:ss.fff"), remoteEP.Address, remoteEP.Port, rcvMsg);

            textBoxRcvData.BeginInvoke(
                new Action <string>(ShowReceivedString), displayMsg);

            // 応答する
            if (match && (!reply))
            {
                // 当該MACアドレスが登録されていて、
                // かつ、「自動応答」が明示的にOFFされている場合は応答しない
            }
            else
            {
                // それ以外は応答する

                // 送信先のIPアドレスは remoteEP.Address ではなく、ブロードキャスト
                SendUDP(sourceIPAddress_, sourcePort_, IPAddress.Broadcast, remoteEP.Port);
            }

            //再びデータ受信を開始する
            udp.BeginReceive(ReceiveCallback, udp);
        }