void sock_setmark(int icmp_sock) { #ifdef SO_MARK if (options & F_MARK) { int ret; enable_capability_admin(); ret = setsockopt(icmp_sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)); disable_capability_admin(); if (ret == -1) { /* we probably dont wanna exit since old kernels * dont support mark .. */ fprintf(stderr, "Warning: Failed to set mark %d\n", mark); } } #endif }
void setup(int icmp_sock) { int hold; struct timeval tv; sigset_t sset; if ((options & F_FLOOD) && !(options & F_INTERVAL)) interval = 0; if (uid && interval < MINUSERINTERVAL) { fprintf(stderr, "ping: cannot flood; minimal interval, allowed for user, is %dms\n", MINUSERINTERVAL); exit(2); } if (interval >= INT_MAX/preload) { fprintf(stderr, "ping: illegal preload and/or interval\n"); exit(2); } hold = 1; if (options & F_SO_DEBUG) setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG, (char *)&hold, sizeof(hold)); if (options & F_SO_DONTROUTE) setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE, (char *)&hold, sizeof(hold)); #ifdef SO_TIMESTAMP if (!(options&F_LATENCY)) { int on = 1; if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) fprintf(stderr, "Warning: no SO_TIMESTAMP support, falling back to SIOCGSTAMP\n"); } #endif #ifdef SO_MARK if (options & F_MARK) { int ret; enable_capability_admin(); ret = setsockopt(icmp_sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)); disable_capability_admin(); if (ret == -1) { /* we probably dont wanna exit since old kernels * dont support mark .. */ fprintf(stderr, "Warning: Failed to set mark %d\n", mark); } } #endif /* Set some SNDTIMEO to prevent blocking forever * on sends, when device is too slow or stalls. Just put limit * of one second, or "interval", if it is less. */ tv.tv_sec = 1; tv.tv_usec = 0; if (interval < 1000) { tv.tv_sec = 0; tv.tv_usec = 1000 * SCHINT(interval); } setsockopt(icmp_sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv)); /* Set RCVTIMEO to "interval". Note, it is just an optimization * allowing to avoid redundant poll(). */ tv.tv_sec = SCHINT(interval)/1000; tv.tv_usec = 1000*(SCHINT(interval)%1000); if (setsockopt(icmp_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv))) options |= F_FLOOD_POLL; if (!(options & F_PINGFILLED)) { int i; u_char *p = outpack+8; /* Do not forget about case of small datalen, * fill timestamp area too! */ for (i = 0; i < datalen; ++i) *p++ = i; } ident = htons(getpid() & 0xFFFF); set_signal(SIGINT, sigexit); set_signal(SIGALRM, sigexit); set_signal(SIGQUIT, sigstatus); sigemptyset(&sset); sigprocmask(SIG_SETMASK, &sset, NULL); gettimeofday(&start_time, NULL); if (deadline) { struct itimerval it; it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 0; it.it_value.tv_sec = deadline; it.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &it, NULL); } if (isatty(STDOUT_FILENO)) { struct winsize w; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) { if (w.ws_col > 0) screen_width = w.ws_col; } } }