1 Star 0 Fork 2

HoperunHarmony/stress-ng

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
stress-icmp-flood.c 4.70 KB
一键复制 编辑 原始数据 按行查看 历史
/*
* Copyright (C) 2013-2021 Canonical, Ltd.
* Copyright (C) 2022 Colin Ian King.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "stress-ng.h"
#include "core-capabilities.h"
#if defined(HAVE_NETINET_IP_H)
#include <netinet/ip.h>
#endif
#if defined(HAVE_NETINET_IP_ICMP_H)
#include <netinet/ip_icmp.h>
#endif
#include <arpa/inet.h>
static const stress_help_t help[] = {
{ NULL, "icmp-flood N", "start N ICMP packet flood workers" },
{ NULL, "icmp-flood-ops N", "stop after N ICMP bogo operations (ICMP packets)" },
{ NULL, NULL, NULL }
};
#if defined(HAVE_NETINET_IP_H) && \
defined(HAVE_NETINET_IP_ICMP_H) && \
defined(HAVE_ICMPHDR)
#define MAX_PAYLOAD_SIZE (1000)
/*
* stress_icmp_flood_supported()
* check if we can run this as root
*/
static int stress_icmp_flood_supported(const char *name)
{
if (!stress_check_capability(SHIM_CAP_NET_RAW)) {
pr_inf_skip("%s stressor will be skipped, "
"need to be running with CAP_NET_RAW "
"rights for this stressor\n", name);
return -1;
}
return 0;
}
/*
* stress_icmp_flood
* stress local host with ICMP flood
*/
static int stress_icmp_flood(const stress_args_t *args)
{
int fd, rc = EXIT_FAILURE;
const int set_on = 1;
const unsigned long addr = inet_addr("127.0.0.1");
struct sockaddr_in servaddr;
uint64_t counter, sendto_fails = 0;
fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (fd < 0) {
pr_fail("%s: socket failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
goto err;
}
if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL,
(const char *)&set_on, sizeof(set_on)) < 0) {
pr_fail("%s: setsockopt IP_HDRINCL failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
goto err_socket;
}
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
(const char *)&set_on, sizeof(set_on)) < 0) {
pr_fail("%s: setsockopt SO_BROADCAST failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
goto err_socket;
}
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = (in_addr_t)addr;
(void)memset(&servaddr.sin_zero, 0, sizeof(servaddr.sin_zero));
stress_set_proc_state(args->name, STRESS_STATE_RUN);
do {
const size_t payload_len = (stress_mwc32() % MAX_PAYLOAD_SIZE) + 1;
const size_t pkt_len =
sizeof(struct iphdr) + sizeof(struct icmphdr) + payload_len;
char pkt[pkt_len];
struct iphdr *const ip_hdr = (struct iphdr *)pkt;
struct icmphdr *const icmp_hdr = (struct icmphdr *)(pkt + sizeof(struct iphdr));
(void)memset(pkt, 0, sizeof(pkt));
ip_hdr->version = 4;
ip_hdr->ihl = 5;
ip_hdr->tos = 0;
ip_hdr->tot_len = htons(pkt_len);
ip_hdr->id = stress_mwc16();
ip_hdr->frag_off = 0;
ip_hdr->ttl = 64;
ip_hdr->protocol = IPPROTO_ICMP;
ip_hdr->saddr = (in_addr_t)addr;
ip_hdr->daddr = (in_addr_t)addr;
icmp_hdr->type = ICMP_ECHO;
icmp_hdr->code = 0;
icmp_hdr->un.echo.sequence = stress_mwc16();
icmp_hdr->un.echo.id = stress_mwc16();
/*
* Generating random data is expensive so do it every 64 packets
*/
if ((get_counter(args) & 0x3f) == 0)
stress_strnrnd(pkt + sizeof(struct iphdr) +
sizeof(struct icmphdr), payload_len);
icmp_hdr->checksum = stress_ipv4_checksum((uint16_t *)icmp_hdr,
sizeof(struct icmphdr) + payload_len);
if ((sendto(fd, pkt, pkt_len, 0,
(struct sockaddr*)&servaddr, sizeof(servaddr))) < 1) {
sendto_fails++;
}
inc_counter(args);
} while (keep_stressing(args));
counter = get_counter(args);
pr_dbg("%s: %.2f%% of %" PRIu64 " sendto messages succeeded.\n",
args->name,
100.0 * (double)(counter - sendto_fails) / (double)counter,
counter);
rc = EXIT_SUCCESS;
err_socket:
stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
(void)close(fd);
err:
stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
return rc;
}
stressor_info_t stress_icmp_flood_info = {
.stressor = stress_icmp_flood,
.supported = stress_icmp_flood_supported,
.class = CLASS_OS | CLASS_NETWORK,
.verify = VERIFY_ALWAYS,
.help = help
};
#else
stressor_info_t stress_icmp_flood_info = {
.stressor = stress_not_implemented,
.class = CLASS_OS | CLASS_NETWORK,
.help = help
};
#endif
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/hoperun_harmony/stress-ng.git
git@gitee.com:hoperun_harmony/stress-ng.git
hoperun_harmony
stress-ng
stress-ng
master

搜索帮助