static void irqcb_recv(struct qm_queue *queue) { u32 phys; queue_ack_irq(queue); while ((phys = queue_get_entry(queue))) recv_pack(queue, phys); }
int main(int c, char **v) { int sfd, ret, ifindex, i = 1; char ipsrc[16], ipdst[16], iptmp[16]; char device[12], src_mac[ETH_ALEN]; struct in_addr src, gatWay, traget; struct sockaddr_ll from; send_arping_t rbuf, gatWaybuf; setuid(0); sfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (sfd == -1){ perror("socket:"); return 1; } gethostip(sfd, device, &ifindex, ipsrc, sizeof(ipsrc)); inet_pton(AF_INET, ipsrc, &src.s_addr); gethostmac(sfd, device, src_mac); init_sfd(sfd, ifindex); packed_for_ip(ipsrc, iptmp); sprintf(ipdst, "%s%d", iptmp, i); inet_pton(AF_INET, ipdst, &gatWay.s_addr); while (1){ send_pack(sfd, src_mac, ifindex, &src, &gatWay); if (recv_pack(sfd, &gatWay, &gatWaybuf)) continue; else break; } while (1){ printf("which one you want to attacked: "); fflush(stdout); //printf("ipdst:%s ipsrc:%s\n", ipdst, ipsrc); ret = read(0, iptmp, sizeof(iptmp)); iptmp[ret - 1] = '\0'; inet_pton(AF_INET, iptmp, &traget.s_addr); break; } send_attack(sfd, ifindex, &traget, &gatWaybuf); return 0; }
/*在新的进程里一直循环执行的函数,实现数据的接收和发送*/ static int echodemo_run() { int ret, send_len, recv_len = 0; char send_packet_buf[PACKET_BUF_SIZE]; char recv_packet_buf[PACKET_BUF_SIZE]; unsigned char send_flag , recv_flag; while(1) { rtdb_get_data_value_by_name("sys_set","send_pack_flag",&send_flag);//查询是否有数据发送 if(send_flag == 1) { rtdb_get_data_value_by_name("sys_set","send_pack",send_packet_buf);//复制数据 send_flag = 0; rtdb_set_data_value_by_name("sys_set","send_pack_flag",&send_flag); ret = send_pack(send_packet_buf);//数据发送 } ret = recv_pack(recv_packet_buf, sizeof(recv_packet_buf), &recv_len,100); #if debug if(SERIAL_STATUS_TIMEOUT != ret) rtdb_set_data_value_by_name("test_parm","ret",&ret); if(recv_len != 0) rtdb_set_data_value_by_name("test_parm","rec_len",&recv_len); #endif serial_flush(serial_id, SERIAL_FLUSH_RX);//清空接收缓存 if(ret == SERIAL_STATUS_OK)//成功接收一帧消息 { rtdb_set_data_value_by_name("sys_set", "recv_pack", recv_packet_buf); recv_flag = 1; rtdb_set_data_value_by_name("sys_set", "recv_pack_flag", &recv_flag);//接收到一帧 debug_printf("recv 1 pack\n"); } memset(recv_packet_buf , 0 , PACKET_BUF_SIZE); } return SERIAL_STATUS_OK; }
int amservicestart() { pthread_mutex_init(&net_mutex, NULL); seminit(); sockfd = dtcmr_client_creat("127.0.0.1",12580, IPPROTO_TCP); if (sockfd<0){ printf("dtcmr_client_creat is error\n"); return -1; } memset(sddata,2,1024); send_pthread_init(); while(1) { pthread_mutex_lock(&net_mutex); printf("while recv_pack\n"); recv_pack(); pthread_mutex_unlock(&net_mutex); usleep(5000); } }
int arping_main(int argc UNUSED_PARAM, char **argv) { const char *device = "eth0"; char *source = NULL; char *target; unsigned char *packet; char *err_str; INIT_G(); sock_fd = xsocket(AF_PACKET, SOCK_DGRAM, 0); // Drop suid root privileges // Need to remove SUID_NEVER from applets.h for this to work //xsetuid(getuid()); err_str = xasprintf("interface %s %%s", device); { unsigned opt; char *str_timeout; /* Dad also sets quit_on_reply. * Advert also sets unsolicited. */ opt_complementary = "=1:Df:AU:c+"; opt = getopt32(argv, "DUAqfbc:w:I:s:", &count, &str_timeout, &device, &source); if (opt & 0x80) /* -w: timeout */ timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000; //if (opt & 0x200) /* -s: source */ option_mask32 &= 0x3f; /* set respective flags */ } target = argv[optind]; xfunc_error_retval = 2; { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy_IFNAMSIZ(ifr.ifr_name, device); /* We use ifr.ifr_name in error msg so that problem * with truncated name will be visible */ ioctl_or_perror_and_die(sock_fd, SIOCGIFINDEX, &ifr, err_str, "not found"); me.sll_ifindex = ifr.ifr_ifindex; xioctl(sock_fd, SIOCGIFFLAGS, (char *) &ifr); if (!(ifr.ifr_flags & IFF_UP)) { bb_error_msg_and_die(err_str, "is down"); } if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { bb_error_msg(err_str, "is not ARPable"); return (option_mask32 & DAD ? 0 : 2); } } /* if (!inet_aton(target, &dst)) - not needed */ { len_and_sockaddr *lsa; lsa = xhost_and_af2sockaddr(target, 0, AF_INET); dst = lsa->u.sin.sin_addr; if (ENABLE_FEATURE_CLEAN_UP) free(lsa); } if (source && !inet_aton(source, &src)) { bb_error_msg_and_die("invalid source address %s", source); } if ((option_mask32 & (DAD|UNSOLICITED)) == UNSOLICITED && src.s_addr == 0) src = dst; if (!(option_mask32 & DAD) || src.s_addr) { struct sockaddr_in saddr; int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0); setsockopt_bindtodevice(probe_fd, device); memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; if (src.s_addr) { /* Check that this is indeed our IP */ saddr.sin_addr = src; xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); } else { /* !(option_mask32 & DAD) case */ /* Find IP address on this iface */ socklen_t alen = sizeof(saddr); saddr.sin_port = htons(1025); saddr.sin_addr = dst; if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) bb_perror_msg("setsockopt(SO_DONTROUTE)"); xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) { bb_perror_msg_and_die("getsockname"); } if (saddr.sin_family != AF_INET) bb_error_msg_and_die("no IP address configured"); src = saddr.sin_addr; } close(probe_fd); } me.sll_family = AF_PACKET; //me.sll_ifindex = ifindex; - done before me.sll_protocol = htons(ETH_P_ARP); xbind(sock_fd, (struct sockaddr *) &me, sizeof(me)); { socklen_t alen = sizeof(me); if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1) { bb_perror_msg_and_die("getsockname"); } } if (me.sll_halen == 0) { bb_error_msg(err_str, "is not ARPable (no ll address)"); return (option_mask32 & DAD ? 0 : 2); } he = me; memset(he.sll_addr, -1, he.sll_halen); if (!(option_mask32 & QUIET)) { /* inet_ntoa uses static storage, can't use in same printf */ printf("ARPING to %s", inet_ntoa(dst)); printf(" from %s via %s\n", inet_ntoa(src), device); } signal_SA_RESTART_empty_mask(SIGINT, (void (*)(int))finish); signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher); catcher(); packet = xmalloc(4096); while (1) { sigset_t sset, osset; struct sockaddr_ll from; socklen_t alen = sizeof(from); int cc; cc = recvfrom(sock_fd, packet, 4096, 0, (struct sockaddr *) &from, &alen); if (cc < 0) { bb_perror_msg("recvfrom"); continue; } sigemptyset(&sset); sigaddset(&sset, SIGALRM); sigaddset(&sset, SIGINT); sigprocmask(SIG_BLOCK, &sset, &osset); recv_pack(packet, cc, &from); sigprocmask(SIG_SETMASK, &osset, NULL); } }
int arping_main(int argc, char **argv) { const char *device = "eth0"; int ifindex; char *source = NULL; char *target; s = xsocket(PF_PACKET, SOCK_DGRAM, 0); // Drop suid root privileges xsetuid(getuid()); { unsigned opt; char *_count, *_timeout; /* Dad also sets quit_on_reply. * Advert also sets unsolicited. */ opt_complementary = "Df:AU"; opt = getopt32(argc, argv, "DUAqfbc:w:i:s:", &_count, &_timeout, &device, &source); cfg |= opt & 0x3f; /* set respective flags */ if (opt & 0x40) /* -c: count */ count = xatou(_count); if (opt & 0x80) /* -w: timeout */ timeout = xatoul_range(_timeout, 0, INT_MAX/2000); //if (opt & 0x100) /* -i: interface */ if (strlen(device) > IF_NAMESIZE) { bb_error_msg_and_die("interface name '%s' is too long", device); } //if (opt & 0x200) /* -s: source */ } argc -= optind; argv += optind; if (argc != 1) bb_show_usage(); target = *argv; xfunc_error_retval = 2; { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, device, IFNAMSIZ - 1); if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { bb_error_msg_and_die("interface %s not found", device); } ifindex = ifr.ifr_ifindex; if (ioctl(s, SIOCGIFFLAGS, (char *) &ifr)) { bb_error_msg_and_die("SIOCGIFFLAGS"); } if (!(ifr.ifr_flags & IFF_UP)) { bb_error_msg_and_die("interface %s is down", device); } if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { bb_error_msg("interface %s is not ARPable", device); return (cfg & dad ? 0 : 2); } } if (!inet_aton(target, &dst)) { len_and_sockaddr *lsa; lsa = xhost_and_af2sockaddr(target, 0, AF_INET); memcpy(&dst, &lsa->sin.sin_addr.s_addr, 4); if (ENABLE_FEATURE_CLEAN_UP) free(lsa); } if (source && !inet_aton(source, &src)) { bb_error_msg_and_die("invalid source address %s", source); } if (!(cfg & dad) && (cfg & unsolicited) && src.s_addr == 0) src = dst; if (!(cfg & dad) || src.s_addr) { struct sockaddr_in saddr; int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0); if (device) { if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1) bb_error_msg("warning: interface %s is ignored", device); } memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; if (src.s_addr) { saddr.sin_addr = src; xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); } else if (!(cfg & dad)) { socklen_t alen = sizeof(saddr); saddr.sin_port = htons(1025); saddr.sin_addr = dst; if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) bb_perror_msg("warning: setsockopt(SO_DONTROUTE)"); xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) { bb_error_msg_and_die("getsockname"); } src = saddr.sin_addr; } close(probe_fd); } me.sll_family = AF_PACKET; me.sll_ifindex = ifindex; me.sll_protocol = htons(ETH_P_ARP); xbind(s, (struct sockaddr *) &me, sizeof(me)); { socklen_t alen = sizeof(me); if (getsockname(s, (struct sockaddr *) &me, &alen) == -1) { bb_error_msg_and_die("getsockname"); } } if (me.sll_halen == 0) { bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device); return (cfg & dad ? 0 : 2); } he = me; memset(he.sll_addr, -1, he.sll_halen); if (!(cfg & quiet)) { printf("ARPING to %s from %s via %s\n", inet_ntoa(dst), inet_ntoa(src), device ? device : "unknown"); } if (!src.s_addr && !(cfg & dad)) { bb_error_msg_and_die("no src address in the non-DAD mode"); } { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_RESTART; sa.sa_handler = (void (*)(int)) finish; sigaction(SIGINT, &sa, NULL); sa.sa_handler = (void (*)(int)) catcher; sigaction(SIGALRM, &sa, NULL); } catcher(); while (1) { sigset_t sset, osset; RESERVE_CONFIG_UBUFFER(packet, 4096); struct sockaddr_ll from; socklen_t alen = sizeof(from); int cc; cc = recvfrom(s, packet, 4096, 0, (struct sockaddr *) &from, &alen); if (cc < 0) { bb_perror_msg("recvfrom"); continue; } sigemptyset(&sset); sigaddset(&sset, SIGALRM); sigaddset(&sset, SIGINT); sigprocmask(SIG_BLOCK, &sset, &osset); recv_pack(packet, cc, &from); sigprocmask(SIG_SETMASK, &osset, NULL); RELEASE_CONFIG_BUFFER(packet); } }
/** * main program */ int main(int argc, char *argv[]) { char *intf = DEFAULT_INTERFACE; char *script = NULL; struct sockaddr_ll sockAddr; struct pollfd fds[1]; struct arp_packet arpPack; struct ifreq ifr; struct ether_addr ethAddr; struct timeval tv; struct in_addr ip = {0}; int fd; int quit = 0; int ready = 0; int foreground = 0; int timeout = 0; int nprobes = 0; int nclaims = 0; int failby = 0; int i = 1; int ret = 0; int ifindex=0; int listenfd; // receive patch - recv_pack args int packet_size = 0; char packet[4096]; struct sockaddr_ll from; int alen; // init gettimeofday(&tv, NULL); prog = argv[0]; // parse arguments while (i < argc) { char *arg = argv[i++]; if (strcmp(arg, "-q") == 0) { quit = 1; } else if (strcmp(arg, "-f") == 0) { foreground = 1; } else if (strcmp(arg, "-v") == 0) { #ifdef DEBUG verbose = 1; #endif } else if (strcmp(arg, "-n") == 0) { failby = time(0) + FAILURE_INTERVAL / 1000; } else if (strcmp(arg, "-i") == 0) { if ((intf = argv[i++]) == NULL) { usage("interface name missing"); } } else if (strcmp(arg, "-s") == 0) { if ((script = argv[i++]) == NULL) { usage("script missing"); } } else if (strcmp(arg, "-ip") == 0) { char *ipstr = argv[i++]; if (ipstr == NULL) { usage("ip address missing"); } if (inet_aton(ipstr, &ip) == 0) { usage("invalid ip address"); } #ifndef DEBUG if ((ntohl(ip.s_addr) & LINKLOCAL_MASK) != LINKLOCAL_ADDR) { usage("invalid linklocal address"); } #endif } else { usage("invald argument"); } } // get a socket handle fd = socket(PF_PACKET, SOCK_DGRAM, 0); if (fd < 0){ perror("open failed"); exit(fd); } // interface set up and connectivity tests memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, intf, IFNAMSIZ - 1); if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { perror("Interface not found"); exit(2); } ifindex = ifr.ifr_ifindex; if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { perror("SIOCGIFFLAGS"); exit(2); } if (!(ifr.ifr_flags & IFF_UP)) { perror("Interface is down"); exit(2); } if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { perror("Interface is not ARPable"); exit(2); } if (ret = ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl failed"); exit(ret); } memcpy(ðAddr, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); #ifdef DEBUG printf("interface: %s\n",ether2str(ðAddr)); #endif // initialize socket address memset( &sockAddr, 0, sizeof( sockAddr ) ); sockAddr.sll_family = AF_PACKET; sockAddr.sll_ifindex = ifindex; sockAddr.sll_protocol = htons(ETH_P_ARP); // bind to the ARP socket { ret = bind(fd, ( struct sockaddr * ) &sockAddr, sizeof(sockAddr)); if (ret < 0) { perror("bind failed"); exit(ret); } alen = sizeof(sockAddr); if (getsockname(fd, (struct sockaddr *) &sockAddr, &alen) == -1) { perror("getsockname"); exit(2); } } // initialize the interface run(script, "init", intf, NULL); // initialize pseudo random selection of IP addresses { srandom((ethAddr.ether_addr_octet[ETHER_ADDR_LEN-4] << 24) | (ethAddr.ether_addr_octet[ETHER_ADDR_LEN-3] << 16) | (ethAddr.ether_addr_octet[ETHER_ADDR_LEN-2] << 8) | (ethAddr.ether_addr_octet[ETHER_ADDR_LEN-1] << 0)); // pick an ip address if (ip.s_addr == 0) { pick(&ip); } } // prepare for polling fds[0].fd = fd; fds[0].events = POLLIN | POLLERR; while (1) { #ifdef DEBUG if (verbose) { printf("%s %s: polling %d, nprobes=%d, nclaims=%d\n", prog, intf, timeout, nprobes, nclaims); } #endif fds[0].revents = 0; switch (poll(fds, 1, timeout)) { case 0: //sending // timeout if ((failby != 0) && (failby < time(0))) { fprintf(stderr, "%s %s: failed to obtain address\n", prog, intf); exit(1); } if (nprobes < NPROBES) { // ARP probe #ifdef DEBUG if (verbose) { fprintf(stderr, "%s %s: ARP probe %s\n", prog, intf, inet_ntoa(ip)); } #endif arp(fd, &sockAddr, ARPOP_REQUEST, ðAddr, null_ip, &null_addr, ip); nprobes++; timeout = PROBE_INTERVAL; } else if (nclaims < NCLAIMS) { // ARP claim #ifdef DEBUG if (verbose) { fprintf(stderr, "%s %s: ARP claim %s\n", prog, intf, inet_ntoa(ip)); } #endif arp(fd, &sockAddr, ARPOP_REQUEST, ðAddr, ip, ðAddr, ip); nclaims++; timeout = CLAIM_INTERVAL; } else { // ARP take #ifdef DEBUG if (verbose) { fprintf(stderr, "%s %s: use %s\n", prog, intf, inet_ntoa(ip)); } #endif ready = 1; timeout = -1; failby = 0; run(script, "config", intf, &ip); if (quit) { shutdown( fd, 0x02 ); close( fd ); exit(0); } if (!foreground) { if (daemon(0, 0) < 0) { perror("daemon failed"); exit(1); } } } break; case 1: // i/o event if ((fds[0].revents & POLLIN) == 0) { if (fds[0].revents & POLLERR) { fprintf(stderr, "%s %s: I/O error\n", prog, intf); exit(1); } continue; } // read ARP packet to a buffer alen = sizeof(from); if ((packet_size = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr *) &from, &alen)) < 0) { perror("recv failed"); exit(1); } // parse arp packet into arp_packet p if (!recv_pack(packet, packet_size, &from, &arpPack )) continue; #ifdef DEBUG if (verbose) { printf("%s %s: recv arp op=%d, ", prog, intf, ntohs(arpPack.arp_hdr.ar_op)); printf("source=%s %s,", ether2str(&arpPack.source_addr), inet_ntoa(arpPack.source_ip)); printf("target=%s %s\n", ether2str(&arpPack.target_addr),inet_ntoa(arpPack.target_ip)); } #endif if (arpPack.source_ip.s_addr == ip.s_addr) { #ifdef DEBUG if (verbose) { fprintf(stderr, "%s %s: ARP conflict %s\n", prog, intf, inet_ntoa(ip)); } #endif //restart ip request pick(&ip); timeout = 0; nprobes = 0; nclaims = 0; if (ready) { ready = 0; run(script, "deconfig", intf, 0); } } break; default: perror("poll failed"); exit(1); } } }
int arping_main(int argc, char **argv) { char *device = "eth0"; int ifindex; char *source = NULL; char *target; s = socket(PF_PACKET, SOCK_DGRAM, 0); ifindex = errno; // Drop suid root privileges xsetuid(getuid()); { unsigned long opt; char *_count, *_timeout, *_device; /* Dad also sets quit_on_reply. * Advert also sets unsolicited. */ bb_opt_complementally = "Df:AU"; opt = bb_getopt_ulflags(argc, argv, "DUAqfbc:w:i:s:", &_count, &_timeout, &_device); cfg |= opt & 63; /* set respective flags */ if (opt & 64) /* count */ count = atoi(_count); if (opt & 128) /* timeout */ timeout = atoi(_timeout); if (opt & 256) { /* interface */ if (strlen(_device) > IF_NAMESIZE) { bb_error_msg_and_die("Interface name `%s' must be less than %d", _device, IF_NAMESIZE); } device = _device; } if (opt & 512) /* source */ source = optarg; } argc -= optind; argv += optind; if (argc != 1) bb_show_usage(); target = *argv; if (s < 0) { bb_default_error_retval = ifindex; bb_perror_msg_and_die("socket"); } bb_default_error_retval = 2; { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, device, IFNAMSIZ - 1); if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { bb_error_msg_and_die("Interface %s not found", device); } ifindex = ifr.ifr_ifindex; if (ioctl(s, SIOCGIFFLAGS, (char *) &ifr)) { bb_error_msg_and_die("SIOCGIFFLAGS"); } if (!(ifr.ifr_flags & IFF_UP)) { bb_error_msg_and_die("Interface %s is down", device); } if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { bb_error_msg("Interface %s is not ARPable", device); exit(cfg&dad ? 0 : 2); } } if (!inet_aton(target, &dst)) { struct hostent *hp; hp = gethostbyname2(target, AF_INET); if (!hp) { bb_error_msg_and_die("invalid or unknown target %s", target); } memcpy(&dst, hp->h_addr, 4); } if (source && !inet_aton(source, &src)) { bb_error_msg_and_die("invalid source address %s", source); } if (!(cfg&dad) && cfg&unsolicited && src.s_addr == 0) src = dst; if (!(cfg&dad) || src.s_addr) { struct sockaddr_in saddr; int probe_fd = socket(AF_INET, SOCK_DGRAM, 0); /* maybe use bb_xsocket? */ if (probe_fd < 0) { bb_error_msg_and_die("socket"); } if (device) { if (setsockopt (probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1) bb_error_msg("WARNING: interface %s is ignored", device); } memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; if (src.s_addr) { saddr.sin_addr = src; if (bind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { bb_error_msg_and_die("bind"); } } else if (!(cfg&dad)) { int on = 1; socklen_t alen = sizeof(saddr); saddr.sin_port = htons(1025); saddr.sin_addr = dst; if (setsockopt (probe_fd, SOL_SOCKET, SO_DONTROUTE, (char *) &on, sizeof(on)) == -1) bb_perror_msg("WARNING: setsockopt(SO_DONTROUTE)"); if (connect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { bb_error_msg_and_die("connect"); } if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) { bb_error_msg_and_die("getsockname"); } src = saddr.sin_addr; } close(probe_fd); }; me.sll_family = AF_PACKET; me.sll_ifindex = ifindex; me.sll_protocol = htons(ETH_P_ARP); if (bind(s, (struct sockaddr *) &me, sizeof(me)) == -1) { bb_error_msg_and_die("bind"); } { socklen_t alen = sizeof(me); if (getsockname(s, (struct sockaddr *) &me, &alen) == -1) { bb_error_msg_and_die("getsockname"); } } if (me.sll_halen == 0) { bb_error_msg("Interface \"%s\" is not ARPable (no ll address)", device); exit(cfg&dad ? 0 : 2); } he = me; memset(he.sll_addr, -1, he.sll_halen); if (!(cfg&quiet)) { printf("ARPING to %s from %s via %s\n", inet_ntoa(dst), inet_ntoa(src), device ? device : "unknown"); } if (!src.s_addr && !(cfg&dad)) { bb_error_msg_and_die("no src address in the non-DAD mode"); } { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_RESTART; sa.sa_handler = (void (*)(int)) finish; sigaction(SIGINT, &sa, NULL); sa.sa_handler = (void (*)(int)) catcher; sigaction(SIGALRM, &sa, NULL); } catcher(); while (1) { sigset_t sset, osset; RESERVE_CONFIG_UBUFFER(packet, 4096); struct sockaddr_ll from; socklen_t alen = sizeof(from); int cc; if ((cc = recvfrom(s, packet, 4096, 0, (struct sockaddr *) &from, &alen)) < 0) { bb_perror_msg("recvfrom"); continue; } sigemptyset(&sset); sigaddset(&sset, SIGALRM); sigaddset(&sset, SIGINT); sigprocmask(SIG_BLOCK, &sset, &osset); recv_pack(packet, cc, &from); sigprocmask(SIG_SETMASK, &osset, NULL); RELEASE_CONFIG_BUFFER(packet); } }