(C++) SpaceSockets2 ile "ping" klonu bir araç yapalım! - Bölüm 3

Selamlar herkese!

Bu yazımda sizler ile birlikte SpaceSockets2 kullanarak bir "ping" klonu yapacağız.

Hala SpaceSockets2 indirmediyseniz, buradan edinebilirsiniz.

Ping'in ne olduğunu bilmeyenler için; Ping uzaktaki bilgisayara "ICMP echo request" paketleri yollar ve o bilgisayardan cevap bekler. Eğer o bilgisayar da ICMP paketleri ile cevap veriyorsa, buna "pong" denir ve bilgisayarımızın aktif olduğunu gösterir.

Öyleyse, gelin başlayalım.

Başlamadan önce önemli bir not

SpaceSockets2'nin ICMP sınıfı, sadece POSIX uyumlu sistemlerde çalışmaktadır. Derleyiciden "struct icmphdr" hatası alırsanız, yaptığımız bu araç çalışmayacaktır. SpaceSockets2'nin ilerleyen versiyonlarında bu durumu boş paketleri ICMP paketleri yaparak ortadan kaldıracağız ve çoğu işletim sistemi ile çalışacak.

Başlayalım

Öncelikle, iskelet programımızı yazalım.

C++:
#include <SpaceSockets2.hpp>

void ping_req(char ip_address[], int pkg_amount);
int main(int argc, char* argv){
   

   
   
    return 0;
}

Görmüş olduğunuz gibi, bize daha da yardımcı olacak bir adet ping isteklerini gerçekleştiren fonksiyonumuz olacak. Hadi devam edelim.

C++:
#include <SpaceSockets2.hpp>



void ping_req(char ip_address[], int pkg_amount);

int main(int argc, char* argv){



    return 0;

}
void ping_req(char ip_address[], int pkg_amount){
   
    unsigned int success_count = 0, failed_count = 0; //Başarılı veya başarısız olmuş olabilir paket gönderimi. Bu konuda da kullanıcıyı bilgilendirebilmek için bu değişkenleri kullanacağız.
    char data[2048]; //Gönderilecek paketimiz olacak, SpaceSockets2'ye bu buffer'ı vereceğiz ve ICMP bilgileri ile doldurup uzak diyarlara gönderecek.
    SpaceSockets2::icmp ping(ip_address,NO_DEBUG_INFORMATION);
    /*
    ICMP sınıfımızın tanımlanması, NO_DEBUG_INFORMATION flag'ı, SpaceSockets2 log mesajlarımızın görüntülenmemesini söylemektedir.
   
    SpaceSockets2'de 3 adet flag vardır. Bunlar:
    -NO_DEBUG_INFORMATION: SpaceSockets2'ye ait log bilgisini hiç bir yere yazma.
    -WRITE_TO_FILE: Log bilgisini dosyaya yaz.
    -WRITE_TO_TERMINAL: Log bilgisini terminal'e (veya konsola) yaz.
    */
   
   
}

"ping_req" fonksiyonumuza, yavaş yavaş ping klonu aracımız için bilgiler doldurmaya başladık. Gönderilecek veriyi tutacak buffer ve soket bilgisi gibi şeyleri tamamladık bile şu anda. Devam edelim.

C++:
#include <SpaceSockets2.hpp>



void ping_req(char ip_address[], int pkg_amount);

int main(int argc, char* argv){



    return 0;

}
void ping_req(char ip_address[], int pkg_amount){
   
    unsigned int success_count = 0, failed_count = 0; //Başarılı veya başarısız olmuş olabilir paket gönderimi. Bu konuda da kullanıcıyı bilgilendirebilmek için bu değişkenleri kullanacağız.
    char data[2048]; //Gönderilecek paketimiz olacak, SpaceSockets2'ye bu buffer'ı vereceğiz ve ICMP bilgileri ile doldurup uzak diyarlara gönderecek.
    SpaceSockets2::icmp ping(ip_address,NO_DEBUG_INFORMATION);
    /*
    ICMP sınıfımızın tanımlanması, NO_DEBUG_INFORMATION flag'ı, SpaceSockets2 log mesajlarımızın görüntülenmemesini söylemektedir.
   
    SpaceSockets2'de 3 adet flag vardır. Bunlar:
    -NO_DEBUG_INFORMATION: SpaceSockets2'ye ait log bilgisini hiç bir yere yazma.
    -WRITE_TO_FILE: Log bilgisini dosyaya yaz.
    -WRITE_TO_TERMINAL: Log bilgisini terminal'e (veya konsola) yaz.
    */
    ping.set_connection_timeout(5);
    /*
    Bilindiği üzere, ping isteklerinde zaman aşımı süresi bulunmakta. Bu süreyi 5 saniye olarak
    ayarlamış bulunmaktayız.
    */
    std::cout<<"Su adrese ping istekleri yollaniyor: "<<get_ip_address(spaceping.get_valid_address())<<"\n";
   
}

SpaceSockets2'nin içindeki "get_ip_address" fonksiyonu, girilen "in_addr" şeklindeki IP adresi bilgisini C++ string'ine dönüştürmekte. ICMP sınıfındaki "get_valid_address" ise, in_addr hali ile IP adresimizi döndürmekte. Devam edelim.

C++:
#include <SpaceSockets2.hpp>







void ping_req(char ip_address[], int pkg_amount);



int main(int argc, char* argv){







    return 0;



}

void ping_req(char ip_address[], int pkg_amount){

   

    unsigned int success_count = 0, failed_count = 0; //Başarılı veya başarısız olmuş olabilir paket gönderimi. Bu konuda da kullanıcıyı bilgilendirebilmek için bu değişkenleri kullanacağız.

    char data[2048]; //Gönderilecek paketimiz olacak, SpaceSockets2'ye bu buffer'ı vereceğiz ve ICMP bilgileri ile doldurup uzak diyarlara gönderecek.

    SpaceSockets2::icmp ping(ip_address,NO_DEBUG_INFORMATION);

    /*

    ICMP sınıfımızın tanımlanması, NO_DEBUG_INFORMATION flag'ı, SpaceSockets2 log mesajlarımızın görüntülenmemesini söylemektedir.

   

    SpaceSockets2'de 3 adet flag vardır. Bunlar:

    -NO_DEBUG_INFORMATION: SpaceSockets2'ye ait log bilgisini hiç bir yere yazma.

    -WRITE_TO_FILE: Log bilgisini dosyaya yaz.

    -WRITE_TO_TERMINAL: Log bilgisini terminal'e (veya konsola) yaz.

    */

    ping.set_connection_timeout(5);

    /*

    Bilindiği üzere, ping isteklerinde zaman aşımı süresi bulunmakta. Bu süreyi 5 saniye olarak

    ayarlamış bulunmaktayız.

    */

    std::cout<<"Su adrese ping istekleri yollaniyor: "<<get_ip_address(spaceping.get_valid_address())<<"\n";

    for(int i = 0; i < pkg_amount; i++){ //Kaç tane yollanacaksa o kadar paket yollamalıyız.
               
            spaceping.send_icmp_message(&data); /*ICMP sınıfının mesaj yollama fonksiyonuna veri buffer'ımızın referansını vermiş bulunmaktayız.*/
            if(spaceping.wait_for_response(&data) == NO_REPLY){ /*Eğer uzak sunucu yanıt vermemişse...*/
               
                std::cout<<"Su uzak sunucudan baglanti yaniti alinamadi: "<<get_ip_address(spaceping.get_valid_address())<<std::endl;
                exit(0);

            }
           
                if(!spaceping.get_received_info_type()){ /*Eğer alınan ICMP paketinin türü 0 ise, yani echo request reply ise, o adresten yanıt almışız demektir.*/

                    success_count++;
                    std::cout<<"Su adresten 'pong' geldi: "<<get_ip_address(spaceping.get_valid_address())<<"!"<<std::endl;

                }
                else{ /*Paket biciminde yanit yoksa...*/

                    failed_count++;
                    std::cout<<"Su adresten herhangi bir paket yaniti alinamadi: "<<get_ip_address(spaceping.get_valid_address())<<"!"<<std::endl;
                   
                }


               

        }
    std::cout<<"Islem tamamlandi, "<<(success_count+failed_count)<<" paket yollandi, "<<success_count<<" paket basarili sonuc verirken, "<<failed_count<<" paket basarisiz sonuc verdi."<<std::endl;
}

Görmüş olduğunuz gibi, paket yollayan ana kısmı hazırladık ve gayet basit ve sade bir kodumuz oldu. Şimdi bu kodu bir de ana fonksiyonumuz ile birleştirmeyi deneyelim.

C++:
#include "SpaceSockets2.hpp"

void ping_req(char ip_address[], int pkg_amount);

int main(int argc, char* argv){
   
        char ip_address[20];
        int amount = 1;
        std::cout<<"Lutfen hedef IP adresinizi girin, veya -1 yazarak uygulamayi kapatin."<<std::endl;
        std::cin>>ip_address;
            if(strcmp(ip_address,"-1") == 0){

                std::cout<<"Pekala adamim, bunu sen istedin."<<std::endl;
                return -1;

        }
        std::cout<<"Su adrese gonderilecek paket sayisini girin: "<<ip_address<<std::endl;
        std::cin>>amount;
        ping_req(ip_address, amount);

    return 0;
}

void ping_req(char ip_address[], int pkg_amount){

    unsigned int success_count = 0, failed_count = 0; //Başarılı veya başarısız olmuş olabilir paket gönderimi. Bu konuda da kullanıcıyı bilgilendirebilmek için bu değişkenleri kullanacağız.

    char data[2048]; //Gönderilecek paketimiz olacak, SpaceSockets2'ye bu buffer'ı vereceğiz ve ICMP bilgileri ile doldurup uzak diyarlara gönderecek.

    SpaceSockets2::icmp ping(SpaceSockets2::dns_resolve(ip_address),NO_DEBUG_INFORMATION);

    /*

    ICMP sınıfımızın tanımlanması, NO_DEBUG_INFORMATION flag'ı, SpaceSockets2 log mesajlarımızın görüntülenmemesini söylemektedir.

    SpaceSockets2'de 3 adet flag vardır. Bunlar:

    -NO_DEBUG_INFORMATION: SpaceSockets2'ye ait log bilgisini hiç bir yere yazma.

    -WRITE_TO_FILE: Log bilgisini dosyaya yaz.

    -WRITE_TO_TERMINAL: Log bilgisini terminal'e (veya konsola) yaz.

    */

    ping.set_connection_timeout(5);

    /*

    Bilindiği üzere, ping isteklerinde zaman aşımı süresi bulunmakta. Bu süreyi 5 saniye olarak

    ayarlamış bulunmaktayız.

    */

    std::cout<<"Su adrese ping istekleri yollaniyor: "<<get_ip_address(ping.get_valid_address())<<"\n";

    for(int i = 0; i < pkg_amount; i++){ //Kaç tane yollanacaksa o kadar paket yollamalıyız.

            ping.send_icmp_message(&data); /*ICMP sınıfının mesaj yollama fonksiyonuna veri buffer'ımızın referansını vermiş bulunmaktayız.*/

            if(ping.wait_for_response(&data) == NO_REPLY){ /*Eğer uzak sunucu yanıt vermemişse...*/

                std::cout<<"Su uzak sunucudan baglanti yaniti alinamadi: "<<get_ip_address(ping.get_valid_address())<<std::endl;

                exit(0);

            }

                if(!ping.get_received_info_type()){ /*Eğer alınan ICMP paketinin türü 0 ise, yani echo request reply ise, o adresten yanıt almışız demektir.*/

                    success_count++;

                    std::cout<<"Su adresten 'pong' geldi: "<<get_ip_address(ping.get_valid_address())<<"!"<<std::endl;

                }

                else{ /**/

                    failed_count++;

                    std::cout<<"Su adresten herhangi bir paket yaniti alinamadi: "<<get_ip_address(ping.get_valid_address())<<"!"<<std::endl;

                }

        }

    std::cout<<"Islem tamamlandi, "<<(success_count+failed_count)<<" paket yollandi, "<<success_count<<" paket basarili sonuc verirken, "<<failed_count<<" paket basarisiz sonuc verdi."<<std::endl;

}

Evet, uygulamamız hazır. Uygulamamızın son halinin kodunda, "ping_req" fonksiyonunda ufak bir ekleme yaparak DNS adreslerini çözebilme özelliği ekledim uygulamamıza. SpaceSockets2 namespace'i içinde bulunan "dns_resolve" fonksiyonu ile alan adlarını da çözebildik.

Bu da uygulamamız çalışırken:

spacesockets2-ping.png

Wireshark ile gözlem yapmadan olmaz tabii ki:

wireshark-spacesockets2.png


Evet, bir sonraki yazımızda görüşmek üzere, hoşçakalın!

Bu örneği SpaceSockets2'nin repo'sunda "SpacePing" ismi ile bulabilirsiniz.

Yorumlar

Gösterilecek yorum bulunamadı.

Blog girdisi detayları

Ekleyen
TerabyteForever
Okuma süresi
5 dakika okuma
Görüntüleme
288
Son güncelleme

Yazılım kategorisindeki diğer girdiler

TerabyteForever adlı kullanıcının diğer girdileri

Bu girdiyi paylaş

Geri
Yukarı