2013-08-22 27 views
5

Çok noktaya yayın adresleri listesi için tcpdump çıktısını izleyecek basit bir bekletme komut dosyası yapıyorum. Paketlerin zaman aşımına uğramadan önce listedeki her çoklu yayın adresinden alınıp alınmadığını bilmek istiyorum.Tüm öğeler bulunana veya belirlenen bir süre geçinceye kadar bir listede saklanan birden fazla desen nasıl aranır?

Çalışan bir çözümüm var, ancak verimsiz ve beklediğim tam gücü ve tcl'yi kullanmadığımı düşünüyorum.

set multicast_list {225.0.0.1 225.0.0.2 225.0.0.3} 

send "tcpdump -i ixp1\r" 
# If tcpdump does not start, unzip it and run it again 
expect { 
    "tcpdump: listening on ixp1" {} 
    "sh: tcpdump: not found" { 
    send "gunzip /usr/sbin/tcpdump.gz\r" 
    expect "# " 
    send "tcpdump -i ixp1\r" 
    exp_continue 
    } 
} 
# Set timeout to the number of seconds expect will check for ip addresses 
set timeout 30 
set found [list] 
set not_found [list] 
foreach ip $multicast_list { 
    expect { 
    "> $ip" { lappend found "$ip" } 
    timeout { lappend not_found "$ip" } 
    } 
} 
set timeout 5 
# Send ^c to stop tcpdump 
send -- "\003" 
expect "# " 

Yani komut dosyası bir anda her ip adresi bir arayacaktır ve ip görülür eğer Bulunan adresler listesine ekler görebileceğiniz gibi: Neyse burada benim şimdiki komut dosyasıdır. Zaman aşımına uğrarsa, adresi not_found listesine ekler ve bir sonraki adresi arar.

Şimdi soruma geri dön: Belirli bir süre boyunca eş zamanlı olarak tüm IP adresleri için tcpdump'ı izleyebileceğim bir yol var mı? Adres bulunacaksa, bulunan adresler listesine eklemek ve ideal olarak beklemeyi durdurmak istiyorum (bu mümkün olmayabilir, emin değilim). Anahtar, listedeki tüm IP'leri paralel olarak izlemek için komut dosyasına ihtiyacım var. Her adresi farklı kodlayamıyorum çünkü her seferinde farklı olacaklar ve aradığım adres miktarı da değişecektir. Beklediğim bir guru lol'dan biraz yardım alabilirim.

Teşekkür ederiz!

cevap

0

İşte benim bitmiş komutum. Aynı kodu Donal'ın çözümünden kullanır, ancak hesaplanmayan bazı sorunları gidermek için birkaç kontrol ekledim.

set multicast_list {225.0.0.1 225.0.0.2 225.0.0.3} 
set tcpdump_timeout 10 

spawn /bin/bash 
expect "] " 

# Create the runtime-generated expbody to use later 
# Generate the timeout clause as a normal literal 
set expbody { 
timeout { 
    set not_found [array names waiting] 
    unset waiting 
} 
} 
foreach ip $multicast_list { 
    set waiting($ip) "dummy" 
    # Generate the per-ip clause as a multi-line string; beware a few backslashes 
    append expbody "\"> $ip\" { 
    set currentTime \[clock seconds\] 
    if { \$currentTime < \$endTime } { 
     if { \[ info exists waiting($ip) \] } { 
     lappend found $ip 
     unset waiting($ip) 
     } 
     if {\[array size waiting\]} exp_continue 
    } 
}\n" 
} 

# Set expect timeout and create empty lists for tcpdump results 
set timeout $tcpdump_timeout 
set found [list] 
set not_found [list] 

# Start tcpdump 
send "tcpdump -i ixp1\r" 
expect "tcpdump: listening on ixp1" 

# Get the time to stop tcpdump 
set endTime [ expr [clock seconds] + $tcpdump_timeout ] 

# Feed expbody into expect; it's none-the-wiser that it was runtime-generated 
expect $expbody 
set not_found [array names waiting] 
unset waiting 
# Send ^c to stop tcpdump 
send -- "\003" 
expect "# " 
3

Bu ilginç bir sorundur. En kolay yol, muhtemelen, beklenen komut dosyasının çekirdeğinin çalışma zamanı oluşturmasıdır. Neyse ki, Tcl'nin numarası çok bu tür şeylerde iyidir. (Not: Ben IP adresleri tüm IPv4 adresleri ve sadece numaraları ve süreleri oluşmaktadır farz ediyorum; bu bir genel dize sokulması olsaydı, biraz daha dikkatli olmak gerekir.)

set timeout 30 
set found [list] 
set not_found [list] 
# Generate the timeout clause as a normal literal 
set expbody { 
    timeout { 
     set not_found [array names waiting] 
     unset waiting 
    } 
} 
foreach ip $multicast_list { 
    set waiting($ip) "dummy" 
    # Generate the per-ip clause as a multi-line string; beware a few backslashes 
    append expbody "\"> $ip\" { 
     lappend found $ip 
     unset waiting($ip) 
     if {\[array size waiting\]} exp_continue 
    }\n" 
} 
# Feed into expect; it's none-the-wiser that it was runtime-generated 
expect $expbody 
set timeout 5 
# Send ^c to stop tcpdump 
send -- "\003" 
expect "# " 

İlk birkaç kez puts $expbody'u isteyebilirsiniz, böylece doğru şeyi yaptığınızdan emin olabilirsiniz.

+0

Teşekkür ederim Donnal! Bu kesinlikle beni doğru yola koydu, ama hala bazı sorunlarım var. Şimdi asıl sorunum, tcpdump'un multicast_list içindeki adreslerden çok noktaya yayın paketlerini sürekli almasıdır. Bu yüzden bir kez 225.0.0.1'den bir paket görmeyi beklerseniz, onu harika bulunan bulunan listeye ekleyecektir. Fakat sonra aynı adreste başka bir paket alacak ve göz ardı etmek yerine tekrar tetikleyeceğini umuyorum. Bu, beklemenin asla zaman aşımına uğramasına neden olur. Ayrıca kodunuzda bir hata alıyorum çünkü zaten kaldırılmış olsa bile adresi bekleme listesinden kaldırmaya çalışır. –