ping
Last updated
Last updated
Network üzerinden yapılan işlemlerin vazgeçilmezi ping-pong mekanizması muhtemelen yakından tanıdığınız bir yapıya sahiptir. Burada ping komutunun pratik birkaç kullanımını göstermeden önce programın tarihinden bahsedeceğiz ve ICMP (Internet Control Messaging Protocol) paket yapısını inceleyeceğiz.
Ping programı Mike Muuss tarafından Aralık 1983 yılında geliştirildi. ABD Ordusu Balistik Araştırma Laboratuvarında çalışan Muuss, ağ trafiğinde bir gariplik sezince trafik üzerindeki gecikmeyi ölçen bir program yazmak istedi. Temmuz 1983'te Norçev'te katıldığı bir DARPA toplantısında Dr. Dave Mills'le yaptığı bir tartışmayı hatırlayıp, ping programını yazdı. Programa ping ismini vermesinin sebebini, üniversitedeyken sonar ve radar sistemlerinin modellemesini sıkça yapması ve bu sistemlerin de programın kendisi gibi "echo-location" kullanmasından kaynaklandığını belirtiyor.
I named it after the sound that a sonar makes, inspired by the whole principle of echo-location. In college I'd done a lot of modeling of sonar and radar systems, so the "Cyberspace" analogy seemed very apt.
İlerleyen yıllarda ping için "Packet InterNet Grouper"ın kısaltması olduğu iddia edildiyse de, Mike Muuss durumun kesinlikle böyle olmadığını belirtmiştir.
Ping programı yaklaşık 1000 satırlık bir C programıdır ve tek gecede yazılmıştır. Bedava olan ve ağ trafiğini incelemekte çok faydalı olan bu program ilerleyen yıllarda pek çok işletim sistemi tarafından hızla benimsenip dağıtılmıştır, hatta 1993 yılında program, Muuss'a The USENIX Association tarafından Yaşam Boyu Başarı Ödülü kazandırmıştır. Muuss her zaman "bu kadar popüler olacağını bilseydim üzerinde birkaç gün daha çalışırdım" demiştir.
TTCP ve BIND gibi yazılımlara da katkı sağlayan Mike Muuss, 2000 yılında bir trafik kazasında hayatını kaybetmiştir.
Ping programı hakkında kendi yazdığı özete ABD Ordu Araştırma Laboratuvarı sayfalarından erişebilirsiniz: http://ftp.arl.mil/mike/ping.html
ping tek başına kullanıldığında sonsuza kadar işlemi sürdürür, ancak Ctrl+c
ile programı durdurursanız, veya kill
ile PID'yi öldürürseniz durur.
Ancak program daha çalıştırılırken -c
parametresiyle kaç defa ping atıp sonlanacağını belirtebilirsiniz.
Yukarıdaki örneğin sonunda, ping istatistiğimizin yansıtıldığını görebilirsiniz. -q
komutu (quiet output) sadece ping işleminin başını ve sonundaki istatistiği gösterir. -c
ile birleştirilmezse, programı durdurmadan istatistiği göremeyiz.
Eğer program sonlanmadan mevcut istatistiği görmek isterseniz, Ctrl+|
sinyalini gönderebilirsiniz (Türkçe klavyelerde bunu gerçekleştirmek için Ctrl+Shift+<
tuşlarına basmak gerekir).
Yukarıdaki çıktıda 3/3
ve 7/7
ile başlayan satırlardan hemen önce Ctrl+|
sinyali gönderilmiştir.
Dilerseniz programa "x saniye boyunca ping gönder ve sonlandır" diyebilirsiniz. Böylece gelen paket cevabından ve sayısından bağımsız olarak işlemi sonlandırır. -w
ile belirtilen değer, saniye cinsindendir.
Eğer hem -w
hem de -c
değerlerini tanımlarsanız, hangisi önce sonlanırsa o dikkate alınır.
Örneğin 15 paketi 20 saniyede göndermeye çalışırsanız aşağıdaki yapıyı uygulayabilirsiniz.
Bu durumda eğer 20 saniyeden kısa sürede 15 paket gönderilirse program sona erecektir. Veya 20 saniye dolarsa ve hala 15 paket gönderilmemişse bile program sona erecektir.
Yukarıdaki örneklerimizde, ping mesajımızın gönderilmesini ifade eden satırda kaç Byte veri gönderdiğimizi görebilirsiniz. 56 Byte veri gönderiyoruz, aslında bu kısım "payload" olan kısım, yani ilettiğimiz anlamsız veri. Bu verinin IPv4 üzerinden iletilebilmesi için 28 byte veri daha iletmemiz gerekiyor. 20 Byte IP adresi, 8 Byte ICMP başlığı. Bu durumda payload + başlık bilgileri toplam 56+28=84 Byte veri iletiyoruz. ping komutu çıktısında 56(84) bytes of data
ile ifade edilen değer bunu gösteriyor.
NOT: Aslında yukarıdaki "20 Byte IP adresi" ifadesi teknik olarak doğru değildir. Buradaki 20 Byte, IPv4 datagramının başlığıdır ancak bu ifadenin ne anlama geldiği bu başlığın kapsamı dışındadır.
Dilersek bu değeri -s
parametresiyle değiştirebiliriz. Örneğin 20 Byte payload göndermek için,
Parametre belirtmediğimizde google.com'a 56(+28) Byte gönderip 64 Byte cevap almıştık. Son örneğimizdeyse 20(+28) Byte veri gönderip, 28 Byte cevap aldık. Gördüğünüz üzere cevaplar her zaman 8 Byte ekstra bilgi içermeli, çünkü bu bilgi gönderdiğimiz ICMP başlığının karşılığını içermektedir. Örneğin paket numarasını içermektedir. Ping mesajlarını gönderirken bir paket numarası veririz, cevap aldığımızda da hangi paketin cevabı olduğunu karşı taraftan öğreniriz. Bu sayede hem hangi paketin ne kadar sürede gidip geldiğini hesaplayabiliriz, hem de yolda kaybolan paketlerin sayısını anlarız. Ping gönderirken gördüğünüz icmp_seq
paket sayısını (sequence) göstermektedir.
Bu durumda tahmin edeceğiniz üzere, gönderebileceğimiz en küçük paket 0 Byte payload içerip sadece IP adresi ve ICMP başlığından oluşan paket olacaktır. 0+28 Byte'lık bu pakete karşılık alacağımız cevap 8 Byte'lık ICMP başlığı karşılığı olmalıdır.
Burada atlanmaması gereken bir nokta var. Google'dan aldığımız cevapta tabii ki bizim IP adresimiz de vardı (yoksa paket bize ulaşmazdı) dolayısıyla gelen cevabın boyutu aslında program tarafından 20 Byte eksik gösterilmektedir.
Aşağıdaki tcpdump
çıktısı bunu göstermektedir.
Yukarıda gördüğünüz tcpdump çıktısı bir ping işleminin (ICMP paketinin) yapısını göstermektedir. tcpdump kullanımını bilmiyorsanız şimdilik bunu önemsemenize gerek yok, ilerleyen bölümlerde göreceğiz, ancak proto ICMP (1), length 28
yazan satır, gelen verinin aslında 8 byte değil, 28 byte olduğunu göstermektedir. Hemen altındaki satır, artık IPv4 başlık bilgilerinden paketi ayıklamıştır, burada length 8
yazdığını görebilirsiniz.
Fark ettiyseniz 0 byte payload ile veri gönderdiğimizde, ICMP paketlerinin sırasını ve cevap aldığımızı gördük, ancak kaç ms (milisaniye) içinde cevap aldığımız bilgisi gelmedi. Bunun sebebi, bu bilginin payload'a yazılmasıdır. Karşı tarafa paket gönderdiğimizde, cevap vereceği zaman paketin payload kısmına zaman bilgisini de yerleştirir. Payload uzunluğunu 0 byte yaptığımızda timestamp göndermedik, dolayısıyla cevap olarak almadık. Bu durumda da zaman bilgisi edinmemiş olduk.
ping programının man sayfalarında -s
ile belirttiğimiz Byte boyutu en az program içindeki timeval
değeri kadarsa, timestamp dahil edileceğini belirtir. Bu değeri test ederek bulabilirsiniz.
Yukarıdaki örneklerden gördüğünüz gibi, en az 16 Byte'lık alan bıraktığımızda paketin seyahat süresini öğrenebiliyoruz.
Öte yandan dilediğimiz kadar büyük paketler de gönderebiliriz. Örneğin
Ping programı timestamp dışındaki bilgileri ASCII karakterlerle doldurur. Aşağıda iki tcpdump çıktısı görüyorsunuz, paketlerin sonunda ABCDEFG
... şeklinde devam eden kısım, söz ettiğimiz ASCII karakterlerdir.
Gördüğünüz gibi aldığımız cevabın boyutu, gönderdiğimiz paketin boyutuna bağlı. Bu durum çok rağbet gören sistemlerin gereksiz yere çok paket transfer etmesine sebep olabilir. Örneğin Google muhtemelen gün içerisinde çok ciddi sayıda ping isteği alıyordur. Gelen bütün ping paketlerine, paketin isteği kadar boyutta cevap vermek gereksiz trafik yüküne sebep olabilir. Bunun önüne geçmek için paketi küçültürler.
Yukarıdaki örnekte gördüğünüz (truncated)
ifadesi paketin istediğimiz değerden küçük geldiği anlamına gelir. Gerçekten de 65 byte veri gönderdik, 65+8=73 byte cevap beklerdik ancak 72 byte geldi. Google, bu kitabın yazıldığı tarihte ICMP cevaplarını en fazla 72 byte olacak şekilde düzenlemiştir.
Linux üzerinde ICMP paketlerini gözardı etmenin pek çok yolu var, ancak bu pek tavsiye edilmez. Yine de IPTABLES gibi kompleks yöntemler yerine basitçe paketleri gözardı etmek isterseniz aşağıdaki yöntemleri kullanabilirsiniz.
İki ardışık ICMP paketi arasındaki süreyi -i
parametresiyle saniye cinsinden düzenleyebilirsiniz.
Kesirli değerler verebilirsiniz.
Tahmin edeceğiniz üzere, çok küçük değerler birim zamanda çok sayıda paket gönderilmesine sebep olur. Bu durum bilgisayarınızı "saldırgan" pozisyonuna düşürebilir. Bunu engellemek için 0.2 saniyenin altındaki değerler için root yetkisi gerekmektedir.
Herhangi bir sebeple birim zamanda çok sayıda paket göndermek isterseniz, ping komutunun flood özelliğini kullanabilirsiniz. Bu durumda çok sayıda paket gönderilip alınacağı için tamamı ekrana yazdırılmaz, ancak her paket gönderildiğinde ekrana bir . (nokta) işareti yazdırılır, her paket alındığındaysa bir backspace işareti yazdırılır, yani bir önceki nokta silinir.
Yukarıdaki örnekte 20 saniye içerisinde 9461 paket gönderilmiş, 9430 cevap alınmıştır. Bu yüzden ^C işaretinden önce (9461-9430=) 31 tane nokta işareti var, bunlar cevapsız paketleri gösterir.
ping programı IPv4 için kullanılır. Eğer ICMP paketlerini IPv6 protokolü ile göndermek isterseniz, ping6
programını kullanmanız gerekir. Kullandığınız makinada IPv6 yoksa, program beklendiği üzere paket gönderemeyecektir.
Yukarıdaki örnekte kullanılan makinada IPv6 adresi bulunmamaktadır.
Yukarıdaki örnekteyse IPv6 adresimizin olduğunu görebilirsiniz.
ping gönderdiğimiz makinanın IPv6 adresini öğrenmek için pratik bir yol, programı -n
ile çalıştırmaktır.
-n
parametresi her paket gönderiminde DNS lookup yapmaz, böylece doğrudan IP adresi görülür. Aynı kullanım IPv4 için ping programında da bulunur.