ping zero ทำงานอย่างไร


16

ใครสามารถอธิบายวิธีการที่ไม่งานและมันแปลให้ping 0127.0.0.1

[champu@testsrv ]$ ping 0
PING 0 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.039 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.013 ms

--- 0 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.013/0.026/0.039/0.013 ms

คุณกำลังกระตุกตัวเอง: P
Alko

คำตอบ:


21

พิเศษ (และ AFAICT) พฤติกรรมที่อยู่ภายใต้เอกสารเล็กน้อยในiputils ping : คุณ ping ตัวเอง

หากคุณping 0เป็นสิ่งที่เกิดขึ้น (แก้ไขอย่างหนักและแสดงความคิดเห็นเพื่อความชัดเจน):

if (inet_aton(target, &whereto.sin_addr)) == 1) {
    // convert string to binary in_addr
}
// inet_aton returns 1 (success) and leaves the `in_addr` contents all zero.

if (source.sin_addr.s_addr == 0) {    
    // determine IP address of src interface, via UDP connect(), getsockname()
}

// special case for 0 dst address
if (whereto.sin_addr.s_addr == 0)
        whereto.sin_addr.s_addr = source.sin_addr.s_addr;

inet_aton()ไม่ใช่ POSIX แต่ฉันสมมติว่าเป็นการคัดลอกพฤติกรรมของinet_addr()เมื่อมีการแปลงทศนิยมน้อยกว่า 4 จุด ในกรณีที่มีหมายเลขเดียวแบบจุดน้อยมันจะถูกเก็บไว้ในที่อยู่เครือข่ายไบนารีและ0x00000000เทียบเท่ากับรูปแบบจุด0.0.0.0เทียบเท่ากับแบบฟอร์มการประ

คุณสามารถดูสิ่งนี้ได้หากคุณstrace(ในฐานะรูท):

# strace -e trace=network ping  0
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(1025), 
    sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(58056),   
    sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
...
PING 0 (127.0.0.1) 56(84) bytes of data.

นอกจากนี้คุณยังสามารถเห็นการเปลี่ยนแปลงหากคุณผูกกับอินเทอร์เฟซเฉพาะแทน:

# strace -e trace=network ping -I eth0  0
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
setsockopt(4, SOL_SOCKET, SO_BINDTODEVICE, "eth0\0", 5) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(1025), 
    sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(58408),    
    sin_addr=inet_addr("192.168.0.123")}, [16]) = 0
setsockopt(3, SOL_RAW, ICMP_FILTER,  ...)
[...]
PING 0 (192.168.0.123) from 192.168.0.123 eth0: 56(84) bytes of data.

ในขณะที่ 0 อาจถือว่าเป็น 0.0.0.0 และที่อยู่ออกอากาศในหลายกรณีที่เห็นได้ชัดว่าไม่ใช่สิ่งที่ ping กำลังทำอยู่ เป็นกรณีพิเศษนี้หมายถึง "IP หลักของอินเทอร์เฟซที่สงสัย" (โดยมีการจัดการพิเศษสำหรับกรณีแบบหลายผู้รับ / การออกอากาศ)

RFC 1122 §3.2.1.3อธิบายพฤติกรรม: ทั้ง 0.0.0.0 และที่อยู่ IP ที่ปิดบังเครือข่าย ("หมายเลขโฮสต์" เช่น 0.0.0.1 ในกรณีของลูปแบ็ค) หมายถึง "โฮสต์บนเครือข่ายนี้"

       (a)  { 0, 0 }

            This host on this network.  MUST NOT be sent, except as
            a source address as part of an initialization procedure
            by which the host learns its own IP address.

            See also Section 3.3.6 for a non-standard use of {0,0}.

       (b)  { 0, <Host-number> }

            Specified host on this network.  It MUST NOT be sent,
            except as a source address as part of an initialization
            procedure by which the host learns its full IP address.

อย่างน้อยในกรณีที่ 0 หรือ 0.0.0.0 นั่นคือpingลักษณะการทำงานของiputils , ping อื่น ๆ และระบบปฏิบัติการอื่น ๆ อาจทำงานแตกต่างกัน ตัวอย่างเช่น FreeBSD ส่ง Ping 0.0.0.0 ผ่านเส้นทางเริ่มต้น (ซึ่งฉันไม่คิดว่าเป็นพฤติกรรม "ถูกต้อง")

ping 1หรือ0.0.0.1ไม่ได้ผลเท่าที่ควร (ไม่ใช่สำหรับฉันiputils-sss20101006 )


@ mr.spuratic .. สิ่งที่ฉันคาดหวัง .. ขอบคุณ
Rahul Patil

ไม่ได้ในทางเทคนิครักษามันเป็น 0.0.0.0 แล้วภายหลังพิเศษปลอก0.0.0.0หมายถึง "ทรัพย์สินทางปัญญาหลักของอินเตอร์เฟซ"? จะเกิดอะไรขึ้นถ้าคุณ ping 0.0.0.0
Random832

@ Random832 ใช่ถูกต้อง
mr.spuratic
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.