ARP是一种协议,用于将 IP地址解析成 MAC 地址。当主机想要与同一局域网内的另一台主机通讯时,它必要知道目标主机的 MAC 地址。ARP 就是用来完成这一使命的协议。ARP 哀求是通过广播方式举行的,所有接收到 ARP 哀求的设备都会查抄是否哀求的是自己的 IP 地址,如果是,则响应自己的 MAC 地址。
Ping ip的流程
当你使用 Ping 向某个 IP 地址发送数据包时,首先必要知道该 IP 地址对应的 MAC 地址。这就是 ARP 的作用
一台计算机 A 要 Ping 另一台计算机 B,过程如下:
A 查询自己的 ARP 缓存表,看是否有 B 的 IP 地址对应的 MAC 地址记录。
如果找不到,则 A 发送一个 ARP 哀求到局域网内所有设备(广播),询问谁拥有 B 的 IP 地址。
B 接收到 ARP 哀求后,如果匹配自己的 IP 地址,就回复 ARP 响应给 A,告诉它自己的 MAC 地址。
A 收到 ARP 响应后,记录下 B 的 MAC 地址,并更新 ARP 缓存表。
A 然后构造一个 ICMP Echo Request 数据包,并使用 B 的 MAC 地址发送给 B。
#include <avahi-common/poll.h>#include <avahi-core/core.h>#include <avahi-client/client.h>#include <stdio.h>#include <stdlib.h>static void service_resolved(AvahiServiceResolvedEvent *event, void *userdata) { printf("Found service '%s' at '%s', port %d.\n", event->name, event->address, event->port);}static void client_callback(AvahiClient *client, AvahiClientState state, void *userdata) { AvahiEntryGroup *group; AvahiEntryGroupState group_state; AvahiServiceResolver *res; if (state != AVAHI_CLIENT_S_RUNNING) return; /* Create a new entry group */ if ((group = avahi_client_new_entry_group(client)) == NULL) { fprintf(stderr, "No memory, aborting.\n"); return; } /* Setup callback for the entry group */ avahi_entry_group_set_callback(group, entry_group_state_callback, userdata); /* Add a service browser to the entry group */ if (avahi_entry_group_add_service_browser(group, AVAHI_IF_UNSPECIFIED, AVAHI_PROTO_INET, "_service._tcp", NULL, NULL) < 0) { fprintf(stderr, "Could not add service browser to entry group.\n"); avahi_entry_group_free(group); return; } /* Commit the entry group */ if (avahi_entry_group_commit(group) < 0) { fprintf(stderr, "Could not commit entry group.\n"); avahi_entry_group_free(group); return; } /* Wait until the entry group is ready */ do { avahi_entry_group_get_state(group, &group_state); } while (group_state != AVAHI_ENTRY_GROUP_COMMITTED); /* Now we can resolve services */ if ((res = avahi_client_alloc_service_resolver(client)) == NULL) { fprintf(stderr, "No memory, aborting.\n"); return; } avahi_service_resolver_set_callback(res, service_resolved, NULL); /* Resolve the first found service */ avahi_service_resolver_resolve(res, AVAHI_IF_UNSPECIFIED, AVAHI_PROTO_INET, "my-service", "local", NULL);}int main(int argc, char *argv[]) { AvahiClient *client; AvahiClientState initial_state; /* Initialize Avahi library */ avahi_init();
/* Create a new client object */ if ((client = avahi_client_new(avahi_poll_get(), AVAHI_CLIENT_FLAG_USE_MULTICAST, client_callback, NULL)) == NULL) { fprintf(stderr, "Failed to create client.\n"); return 1; } /* Get the initial client state */ avahi_client_get_state(client, &initial_state); /* Main loop */ while (initial_state != AVAHI_CLIENT_S_RUNNING) { avahi_client_wait(client, 1000); avahi_client_get_state(client, &initial_state); } /* Clean up */ avahi_client_free(client); return 0;}