📄 icmp.c
字号:
/* * $Id: icmp.c,v 1.69 1998/12/05 00:54:29 wessels Exp $ * * DEBUG: section 37 ICMP Routines * AUTHOR: Duane Wessels * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * * Squid is the result of efforts by numerous individuals from the * Internet community. Development is led by Duane Wessels of the * National Laboratory for Applied Network Research and funded by the * National Science Foundation. Squid is Copyrighted (C) 1998 by * Duane Wessels and the University of California San Diego. Please * see the COPYRIGHT file for full details. Squid incorporates * software developed and/or copyrighted by other sources. Please see * the CREDITS file for full details. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"#if USE_ICMP#define S_ICMP_ECHO 1#if ALLOW_SOURCE_PING#define S_ICMP_ICP 2#endif#define S_ICMP_DOM 3static PF icmpRecv;static void icmpSend(pingerEchoData * pkt, int len);#if ALLOW_SOURCE_PINGstatic void icmpHandleSourcePing(const struct sockaddr_in *from, const char *buf);#endifstatic voidicmpSendEcho(struct in_addr to, int opcode, const char *payload, int len){ static pingerEchoData pecho; if (payload && len == 0) len = strlen(payload); pecho.to = to; pecho.opcode = (unsigned char) opcode; pecho.psize = len; xmemcpy(pecho.payload, payload, len); icmpSend(&pecho, sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ + len);}static voidicmpRecv(int unused1, void *unused2){ int n; static int fail_count = 0; pingerReplyData preply; static struct sockaddr_in F; commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0); memset(&preply, '\0', sizeof(pingerReplyData)); Counter.syscalls.sock.recvfroms++; n = recv(icmp_sock, (char *) &preply, sizeof(pingerReplyData), 0); if (n < 0) { debug(50, 1) ("icmpRecv: recv: %s\n", xstrerror()); if (++fail_count == 10 || errno == ECONNREFUSED) icmpClose(); return; } fail_count = 0; if (n == 0) /* test probe from pinger */ return; F.sin_family = AF_INET; F.sin_addr = preply.from; F.sin_port = 0; switch (preply.opcode) { case S_ICMP_ECHO: break;#if ALLOW_SOURCE_PING case S_ICMP_ICP: icmpHandleSourcePing(&F, preply.payload); break;#endif case S_ICMP_DOM: netdbHandlePingReply(&F, preply.hops, preply.rtt); break; default: debug(37, 1) ("icmpRecv: Bad opcode: %d\n", (int) preply.opcode); break; }}static voidicmpSend(pingerEchoData * pkt, int len){ int x; if (icmp_sock < 0) return; x = send(icmp_sock, (char *) pkt, len, 0); if (x < 0) { debug(50, 1) ("icmpSend: send: %s\n", xstrerror()); if (errno == ECONNREFUSED) { icmpClose(); return; } } else if (x != len) { debug(37, 1) ("icmpSend: Wrote %d of %d bytes\n", x, len); }}#if ALLOW_SOURCE_PINGstatic voidicmpHandleSourcePing(const struct sockaddr_in *from, const char *buf){ const cache_key *key; icp_common_t header; const char *url; xmemcpy(&header, buf, sizeof(icp_common_t)); url = buf + sizeof(icp_common_t); key = icpGetCacheKey(url, (int) header.reqnum); debug(37, 3) ("icmpHandleSourcePing: from %s, key '%s'\n", inet_ntoa(from->sin_addr), storeKeyText(key)); /* call neighborsUdpAck even if ping_status != PING_WAITING */ neighborsUdpAck(key, &header, from);}#endif#endif /* USE_ICMP */voidicmpPing(struct in_addr to){#if USE_ICMP icmpSendEcho(to, S_ICMP_ECHO, NULL, 0);#endif}#if ALLOW_SOURCE_PINGvoidicmpSourcePing(struct in_addr to, const icp_common_t * header, const char *url){#if USE_ICMP char *payload; int len; int ulen; debug(37, 3) ("icmpSourcePing: '%s'\n", url); if ((ulen = strlen(url)) > MAX_URL) return; payload = memAllocate(MEM_8K_BUF); len = sizeof(icp_common_t); xmemcpy(payload, header, len); strcpy(payload + len, url); len += ulen + 1; icmpSendEcho(to, S_ICMP_ICP, payload, len); memFree(payload, MEM_8K_BUF);#endif}#endifvoidicmpDomainPing(struct in_addr to, const char *domain){#if USE_ICMP debug(37, 3) ("icmpDomainPing: '%s'\n", domain); icmpSendEcho(to, S_ICMP_DOM, domain, 0);#endif}voidicmpOpen(void){#if USE_ICMP char *args[2]; int x; int rfd; int wfd; args[0] = "(pinger)"; args[1] = NULL; x = ipcCreate(IPC_UDP_SOCKET, Config.Program.pinger, args, "Pinger Socket", &rfd, &wfd); if (x < 0) return; assert(rfd == wfd); icmp_sock = rfd; commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0); commSetTimeout(icmp_sock, -1, NULL, NULL); debug(29, 1) ("Pinger socket opened on FD %d\n", icmp_sock);#endif}voidicmpClose(void){#if USE_ICMP if (icmp_sock < 0) return; debug(29, 1) ("Closing Pinger socket on FD %d\n", icmp_sock); comm_close(icmp_sock); icmp_sock = -1;#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -