Changeset View
Changeset View
Standalone View
Standalone View
head/sbin/ping/ping.c
Show First 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | |||||
/* nonzero if we've been told to finish up */ | /* nonzero if we've been told to finish up */ | ||||
static volatile sig_atomic_t finish_up; | static volatile sig_atomic_t finish_up; | ||||
static volatile sig_atomic_t siginfo_p; | static volatile sig_atomic_t siginfo_p; | ||||
static cap_channel_t *capdns; | static cap_channel_t *capdns; | ||||
static void fill(char *, char *); | static void fill(char *, char *); | ||||
static u_short in_cksum(u_short *, int); | static u_short in_cksum(u_char *, int); | ||||
static cap_channel_t *capdns_setup(void); | static cap_channel_t *capdns_setup(void); | ||||
static void check_status(void); | static void check_status(void); | ||||
static void finish(void) __dead2; | static void finish(void) __dead2; | ||||
static void pinger(void); | static void pinger(void); | ||||
static char *pr_addr(struct in_addr); | static char *pr_addr(struct in_addr); | ||||
static char *pr_ntime(n_time); | static char *pr_ntime(n_time); | ||||
static void pr_icmph(struct icmp *); | static void pr_icmph(struct icmp *); | ||||
static void pr_iph(struct ip *); | static void pr_iph(struct ip *); | ||||
▲ Show 20 Lines • Show All 820 Lines • ▼ Show 20 Lines | if (timing) | ||||
bcopy((void *)&tv32, | bcopy((void *)&tv32, | ||||
(void *)&outpack[ICMP_MINLEN + phdr_len], | (void *)&outpack[ICMP_MINLEN + phdr_len], | ||||
sizeof(tv32)); | sizeof(tv32)); | ||||
} | } | ||||
cc = ICMP_MINLEN + phdr_len + datalen; | cc = ICMP_MINLEN + phdr_len + datalen; | ||||
/* compute ICMP checksum here */ | /* compute ICMP checksum here */ | ||||
icp->icmp_cksum = in_cksum((u_short *)icp, cc); | icp->icmp_cksum = in_cksum((u_char *)icp, cc); | ||||
if (options & F_HDRINCL) { | if (options & F_HDRINCL) { | ||||
cc += sizeof(struct ip); | cc += sizeof(struct ip); | ||||
ip = (struct ip *)outpackhdr; | ip = (struct ip *)outpackhdr; | ||||
ip->ip_len = htons(cc); | ip->ip_len = htons(cc); | ||||
ip->ip_sum = in_cksum((u_short *)outpackhdr, cc); | ip->ip_sum = in_cksum(outpackhdr, cc); | ||||
packet = outpackhdr; | packet = outpackhdr; | ||||
} | } | ||||
i = send(ssend, (char *)packet, cc, 0); | i = send(ssend, (char *)packet, cc, 0); | ||||
if (i < 0 || i != cc) { | if (i < 0 || i != cc) { | ||||
if (i < 0) { | if (i < 0) { | ||||
if (options & F_FLOOD && errno == ENOBUFS) { | if (options & F_FLOOD && errno == ENOBUFS) { | ||||
usleep(FLOOD_BACKOFF); | usleep(FLOOD_BACKOFF); | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 279 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* in_cksum -- | * in_cksum -- | ||||
* Checksum routine for Internet Protocol family headers (C Version) | * Checksum routine for Internet Protocol family headers (C Version) | ||||
*/ | */ | ||||
u_short | u_short | ||||
in_cksum(u_short *addr, int len) | in_cksum(u_char *addr, int len) | ||||
{ | { | ||||
int nleft, sum; | int nleft, sum; | ||||
u_short *w; | u_char *w; | ||||
union { | union { | ||||
u_short us; | u_short us; | ||||
u_char uc[2]; | u_char uc[2]; | ||||
} last; | } last; | ||||
u_short answer; | u_short answer; | ||||
nleft = len; | nleft = len; | ||||
sum = 0; | sum = 0; | ||||
w = addr; | w = addr; | ||||
/* | /* | ||||
* Our algorithm is simple, using a 32 bit accumulator (sum), we add | * Our algorithm is simple, using a 32 bit accumulator (sum), we add | ||||
* sequential 16 bit words to it, and at the end, fold back all the | * sequential 16 bit words to it, and at the end, fold back all the | ||||
* carry bits from the top 16 bits into the lower 16 bits. | * carry bits from the top 16 bits into the lower 16 bits. | ||||
*/ | */ | ||||
while (nleft > 1) { | while (nleft > 1) { | ||||
sum += *w++; | u_short data; | ||||
nleft -= 2; | |||||
memcpy(&data, w, sizeof(data)); | |||||
sum += data; | |||||
w += sizeof(data); | |||||
nleft -= sizeof(data); | |||||
} | } | ||||
/* mop up an odd byte, if necessary */ | /* mop up an odd byte, if necessary */ | ||||
if (nleft == 1) { | if (nleft == 1) { | ||||
last.uc[0] = *(u_char *)w; | last.uc[0] = *w; | ||||
last.uc[1] = 0; | last.uc[1] = 0; | ||||
sum += last.us; | sum += last.us; | ||||
} | } | ||||
/* add back carry outs from top 16 bits to low 16 bits */ | /* add back carry outs from top 16 bits to low 16 bits */ | ||||
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | ||||
sum += (sum >> 16); /* add carry */ | sum += (sum >> 16); /* add carry */ | ||||
answer = ~sum; /* truncate to 16 bits */ | answer = ~sum; /* truncate to 16 bits */ | ||||
▲ Show 20 Lines • Show All 410 Lines • Show Last 20 Lines |