{"id":412921,"date":"2024-06-29T22:49:30","date_gmt":"2024-06-29T22:49:30","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=412921"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=412921","title":{"rendered":"<span>\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433: \u0438\u0437\u043c\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e C++<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0418\u0437\u043c\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Zabbix External Check \u0438 C++ Boost.Asio<\/h2>\n<h4>\u041d\u0430\u0447\u0430\u043b\u043e<\/h4>\n<p>\u0412\u0441\u0435\u043c \u0445\u043e\u0440\u043e\u0448 Zabbix, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432 \u0434\u043b\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a. \u0412 \u0444\u0430\u0439\u043b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0443\u043a\u0430\u0437\u0430\u043d \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 30 \u0441\u0435\u043a\u0443\u043d\u0434, \u0447\u0435\u0433\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043f\u0438\u043d\u0433\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c 10 000 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0432 100 \u043c\u0441. \u041a\u0430\u043a \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u043f\u043e \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u0438\u043c \u043d\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u0430\u043c \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0432 \u0441\u0435\u0442\u044f\u0445 \u0441\u0432\u044f\u0437\u0438 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043f\u0430\u043a\u0435\u0442 \u043d\u0430 \u0442\u044b\u0441\u044f\u0447\u0443. \u041e\u0441\u043e\u0431\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0438 \u0442\u0440\u0430\u043a\u0442\u0443\u044e\u0442 \u044d\u0442\u0443 \u0446\u0438\u0444\u0440\u0443 \u043f\u043e-\u0441\u0432\u043e\u0435\u043c\u0443: \u0432\u0441\u0451 \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043b\u0438 \u0440\u0430\u0432\u043d\u043e 0,05% \u043c\u043e\u0436\u043d\u043e \u043e\u043a\u0440\u0443\u0433\u043b\u0438\u0442\u044c \u0434\u043e \u0442\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 0,1% \u0438\u043b\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u043d\u0430 \u0442\u044b\u0441\u044f\u0447\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u0434\u043b\u044f \u0441\u0430\u043c\u044b\u0445 \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u044b\u0445 \u0443\u0437\u043b\u043e\u0432, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0438 \u0437\u0430\u044f\u0432\u043a\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 (\u043d\u0430\u0437\u043e\u0432\u0451\u043c \u0435\u0451 <code>losshd<\/code>), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u0431\u0430\u0437\u0443, \u0430 \u0434\u043b\u044f Zabbix \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443 (\u043d\u0430\u0437\u043e\u0432\u0451\u043c \u0435\u0451 <code>getloss<\/code>), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u044b\u0442\u0430\u0449\u0438\u0442 \u0438\u0437 \u0431\u0430\u0437\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0420\u0430\u0441\u043f\u0438\u0448\u0435\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443<br \/> <code>getloss -hlocalhost --dbname=zabbix --dbuser=zabbix --dbpass=mypassword      --address=192.168.0.1<\/code><br \/> \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0435\u0441\u0442\u044c \u043b\u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0430 losshd \u0430\u0434\u0440\u0435\u0441 192.168.0.1. \u0415\u0441\u043b\u0438 \u0434\u0430 \u2013 \u0434\u043e\u0441\u0442\u0430\u0451\u0442 \u0438\u0437 \u0431\u0430\u0437\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f loss \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442 \u2013 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 0 (\u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0442\u0435\u0440\u044c \u043d\u0435\u0442, \u043f\u043e\u043a\u0430 \u0438\u0445 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043d\u0435 \u0434\u043e\u043a\u0430\u0437\u0430\u043d\u043e);<\/p>\n<\/li>\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0441\u0447\u0451\u0442\u0447\u0438\u043a <code>last_read<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0410 \u0432\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u0435\u043c\u043e\u043d\u0430 <code>losshd<\/code>:<\/p>\n<ol>\n<li>\n<p>\u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0437 \u0431\u0430\u0437\u044b \u0432\u0441\u0435 ip-\u0430\u0434\u0440\u0435\u0441\u0430, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 ICMP Echo Request \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 (\u0434\u0430\u043b\u0435\u0435 &#8212; <em>\u0441\u0435\u043d\u0434\u0435\u0440\u044b<\/em>);<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0434\u0438\u043d \u043e\u0431\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0434\u043b\u044f \u043b\u043e\u0432\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u2013 ICMP Echo Reply (\u0434\u0430\u043b\u0435\u0435 &#8212; <em>\u0440\u0435\u0441\u0438\u0432\u0435\u0440<\/em>);<\/p>\n<\/li>\n<li>\n<p>\u041e\u0436\u0438\u0434\u0430\u0435\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0441\u0435\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u043f\u043e\u0442\u0435\u0440\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e IP;<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0431\u0430\u0437\u0443;<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 <code>last_read<\/code> \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043d\u0435\u0434\u0435\u043b\u0438 \u043d\u0430\u0437\u0430\u0434. \u0422\u0430\u043a \u043c\u044b \u0441\u043d\u0438\u0437\u0438\u043c \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0434\u0435\u043c\u043e\u043d <code>losshd<\/code>, \u0443\u0431\u0438\u0440\u0430\u044f \u043d\u0435\u0432\u043e\u0441\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0432\u0441\u0451 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430.<\/p>\n<\/li>\n<\/ol>\n<p>\u0418\u0442\u0430\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u0432\u0435\u0441\u044c \u043a\u043e\u0434, \u0438\u043d\u0430\u0447\u0435 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043e\u0431\u044a\u0451\u043c\u043d\u043e\u0439. \u041c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0435\u0433\u043e \u0432 \u043c\u043e\u0451\u043c \u0433\u0438\u0442\u0445\u0430\u0431\u0435: <a href=\"https:\/\/github.com\/Lordgprs\/losshd\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Lordgprs\/losshd<\/a>.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0451 \u0432  \u0442\u043e\u0439 \u0436\u0435 \u0431\u0430\u0437\u0435, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 Zabbix server. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e PostgreSQL:<\/p>\n<pre><code class=\"sql\">CREATE TABLE ext_packetlosshd_dbg (   ip inet NOT NULL PRIMARY KEY,   loss DOUBLE PRECISION NOT NULL DEFAULT 0,   last_update TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(),   last_read TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW() );<\/code><\/pre>\n<p>\u041d\u0430\u0448 \u043a\u043e\u0434 \u043d\u0430 C++ \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0448\u0435\u0441\u0442\u0438 \u0444\u0430\u0439\u043b\u043e\u0432: <code>options.h<\/code>, <code>options.cpp<\/code>, <code>getloss.h<\/code>, <code>getloss.cpp<\/code>, <code>losshd.h<\/code>, <code>losshd.cpp<\/code>. \u042f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0432\u044b\u0431\u043e\u0440\u043e\u0447\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e. <\/p>\n<h4>\u0423\u0442\u0438\u043b\u0438\u0442\u0430 getloss<\/h4>\n<p>\u041f\u0438\u0448\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">class Options { public:   Options() = delete;   Options(const Options &amp;) = delete;   Options(const Options &amp;&amp;) = delete;   Options &amp; operator=(const Options &amp;) = delete;   Options &amp; operator=(const Options &amp;&amp;) = delete;   Options (int, char **); protected:   po::options_description desc_;   po::variables_map vm_; };  Options::Options(int argc, char **argv): desc_(\"Allowed options\") { }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u0432\u0441\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 <code>argc<\/code> \u0438 <code>argv<\/code> (\u0432\u043f\u0440\u043e\u0447\u0435\u043c, \u0442\u043e\u0436\u0435 \u043f\u0443\u0441\u0442\u043e\u0439). \u041f\u0435\u0440\u0435\u0447\u0435\u043d\u044c \u043e\u043f\u0446\u0438\u0439 \u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0441\u0430\u0445-\u043f\u043e\u0442\u043e\u043c\u043a\u0430\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0435\u043b\u0430\u0435\u043c \u0438\u0445 <code>protected<\/code>. <\/p>\n<p>\u041f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u043e\u043f\u0446\u0438\u0439 \u0434\u043b\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u044b <code>getloss<\/code>:<\/p>\n<pre><code class=\"cpp\">class OptionsGetloss : public Options { public:   OptionsGetloss() = delete;   OptionsGetloss(const OptionsGetloss &amp;) = delete;   OptionsGetloss(const OptionsGetloss &amp;&amp;) = delete;   OptionsGetloss &amp; operator=(const OptionsGetloss &amp;) = delete;   OptionsGetloss &amp; operator=(const OptionsGetloss &amp;&amp;) = delete;   OptionsGetloss(int argc, char **argv);   void CheckOptions();   std::string get_dbname() const;   std::string get_dbhost() const;   std::string get_dbuser() const;   std::string get_dbpass() const;   std::string get_address() const; };<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0438 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b:<\/p>\n<pre><code class=\"cpp\">OptionsGetloss::OptionsGetloss(int argc, char *argv[]) : Options(argc, argv) {   desc_.add_options()     (\"help\", \"this help\")     (\"dbname,n\", po::value&lt;std::string>(), \"database name\")     (\"dbhost,h\", po::value&lt;std::string>(), \"database server address\")     (\"dbuser,U\", po::value&lt;std::string>(), \"database user name\")     (\"dbpass,P\", po::value&lt;std::string>(), \"database password\")     (\"address,A\", po::value&lt;std::string>(), \"address to ping\");   po::store(po::parse_command_line(argc, argv, desc_), vm_);   po::notify(vm_);    CheckOptions(); }  void OptionsGetloss::CheckOptions() {   if (vm_.count(\"help\") != 0) {     std::cout &lt;&lt; desc_ &lt;&lt; std::endl;     std::exit(EXIT_SUCCESS);   }   if (     vm_.count(\"dbname\") == 0 ||     vm_.count(\"dbhost\") == 0 ||     vm_.count(\"dbuser\") == 0 ||     vm_.count(\"address\") == 0    ) {     std::cerr &lt;&lt; \"Error via processing arguments!\" &lt;&lt; std::endl &lt;&lt; std::endl;     std::cerr &lt;&lt; desc_ &lt;&lt; std::endl;     std::exit(EXIT_FAILURE);   } }<\/code><\/pre>\n<p>\u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0421\u0423\u0411\u0414:<\/p>\n<pre><code class=\"cpp\">class Database { public:   Database() = delete;   Database(const OptionsGetloss &amp;);   ~Database();   double get_loss(const std::string &amp;) const; private:   pqxx::connection conn_;   pqxx::work mutable txn_; };  double Database::get_loss(const std::string &amp;ip) const {   double loss = 0;   std::string req = \"SELECT loss FROM ext_packetlosshd_dbg WHERE ip = '\" + ip + \"'\";   auto result = txn_.exec(req);   if (result.size() > 0) {     loss = result[0][0].as&lt;double>();     txn_.exec(\"UPDATE ext_packetlosshd_dbg SET last_read = NOW() WHERE ip = '\" + ip + \"'\");   }   else     txn_.exec(\"INSERT INTO ext_packetlosshd_dbg (ip) VALUES ('\" + ip + \"')\");   return loss; }<\/code><\/pre>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>main()<\/code> \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043e\u043f\u0446\u0438\u0439 \u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0421\u0423\u0411\u0414 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0446\u0438\u0444\u0440\u0443 \u0441 \u043f\u043e\u0442\u0435\u0440\u044f\u043c\u0438 \u0438\u0437 \u0431\u0430\u0437\u044b \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0432\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u043c\u0443 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0443:<\/p>\n<pre><code class=\"cpp\">int main(int argc, char **argv) {   OptionsGetloss options(argc, argv);   Database db(options);   std::cout &lt;&lt; db.get_loss(options.get_address()) &lt;&lt; std::endl;   return EXIT_SUCCESS; }<\/code><\/pre>\n<p>\u0412\u044b\u0432\u043e\u0434\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0440\u0432\u0435\u0440 Zabbix \u0441\u043c\u043e\u0433 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u043e\u0442\u0442\u0443\u0434\u0430. \u041f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0434\u0435\u0441\u044c \u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 &#8212; \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043d\u0451\u043c \u043d\u0435\u0442.<\/p>\n<h4>\u0414\u0435\u043c\u043e\u043d losshd<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0439\u043c\u0451\u043c\u0441\u044f \u0441\u0435\u0440\u0434\u0446\u0435\u043c \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438: \u0434\u0435\u043c\u043e\u043d\u043e\u043c <code>losshd<\/code>. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 <code>Ipv4<\/code> \u0438 <code>Icmp<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432\u0437\u044f\u0442\u044b \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043a Boost.Asio:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Ipv4 \u0438 Icmp<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">class Ipv4 { public:   Ipv4();   char8_t version() const;   uint16_t header_length() const;   char8_t tos() const;   uint32_t time_to_live() const;   boost::asio::ip::address_v4 source_address() const;   uint32_t source_address_uint32() const;   friend std::istream &amp;operator>>(std::istream &amp;is, Ipv4 &amp;header);  private:   char8_t data_[60]; };  class Icmp { public:   enum {     kEchoReply = 0,     kDestinationUnreachable = 3,     kSourceQuench = 4,     kRedirect = 5,     kEchoRequest = 8,     kTimeExceeded = 11,     kParameterProblem = 12,     kTimestampRequest = 13,     kTimestampReply = 14,     kInfoRequest = 15,     kInfoReply = 16,     kAddressRequest = 17,     kAddressReply = 18   };   Icmp();   char8_t type() const;   char8_t code() const;   uint16_t identifier() const;   uint16_t sequence_number() const;   void type(char8_t);   void code(char8_t);   void checksum(uint16_t);   void identifier(uint16_t);   void sequence_number(uint16_t);   void CalculateChecksum(auto body_begin, auto body_end);   friend std::istream&amp; operator>>     (std::istream &amp;inputStream, Icmp &amp;header);   friend std::ostream&amp; operator&lt;&lt;     (std::ostream &amp;outputStream, const Icmp &amp;header);  private:   uint16_t Decode(int32_t a, int32_t b) const;   void Encode(int32_t a, int32_t b, uint16_t n);    char8_t data_[8]; };  Ipv4::Ipv4() {   std::fill (data_, data_ + sizeof(data_), 0); }  char8_t Ipv4::version() const {   return (data_[0] >> 4) &amp; 0xF; }  uint16_t Ipv4::header_length() const {   return (data_[0] &amp; 0xF) &lt;&lt; 2; }  char8_t Ipv4::tos() const {   return data_[1]; }  uint32_t Ipv4::time_to_live() const {   return data_[8]; }  boost::asio::ip::address_v4 Ipv4::source_address() const {   boost::asio::ip::address_v4::bytes_type bytes = {     {data_[12], data_[13], data_[14], data_[15]}   };   return boost::asio::ip::address_v4(bytes); }  uint32_t Ipv4::source_address_uint32() const {   return (data_[12] &lt;&lt; 24) |      (data_[13] &lt;&lt; 16) |      (data_[14] &lt;&lt; 8) |     data_[15]; }  Icmp::Icmp() {   std::fill(data_, data_ + sizeof(data_), 0); }  char8_t Icmp::type() const {   return data_[0]; }  char8_t Icmp::code() const {   return data_[1]; }  uint16_t Icmp::identifier() const {   return Decode(4, 5); }  uint16_t Icmp::sequence_number() const {   return Decode(6, 7); }  void Icmp::type(char8_t n) {   data_[0] = n; }  void Icmp::code(char8_t n) {   data_[1] = n; }  void Icmp::checksum(uint16_t n) {   Encode(2, 3, n); }  void Icmp::identifier(uint16_t n) {   Encode(4, 5, n); }  void Icmp::sequence_number(uint16_t n) {   Encode(6, 7, n); }  void Icmp::CalculateChecksum(auto body_begin, auto body_end) {   uint32_t sum = (type() &lt;&lt; 8) + code() + identifier() + sequence_number();   auto body_iterator = body_begin;   while (body_iterator != body_end) {     sum += (static_cast&lt;char8_t>(*body_iterator++) &lt;&lt; 8);     if (body_iterator != body_end)       sum += static_cast&lt;char8_t>(*body_iterator++);   }    sum = (sum >> 16) + (sum &amp; 0xFFFF);   sum += (sum >> 16);   checksum(static_cast&lt;uint16_t>(~sum)); }  uint16_t Icmp::Decode(const int32_t a, const int32_t b) const {   return (data_[a] &lt;&lt; 8) + data_[b]; }  void Icmp::Encode(const int32_t a, const int32_t b, const uint16_t n) {   data_[a] = static_cast&lt;char8_t>(n >> 8);   data_[b] = static_cast&lt;char8_t>(n &amp; 0xFF); }  std::istream&amp; operator>>(std::istream&amp; input_stream, Icmp &amp;header) {   return input_stream.read(reinterpret_cast&lt;char *>(header.data_), 8); }  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; output_stream, const Icmp &amp;header) {   return output_stream.write(     reinterpret_cast&lt;const char *>(header.data_), 8); }  std::istream &amp;operator>>(std::istream &amp;is, Ipv4 &amp;header) {   is.read(reinterpret_cast&lt;char *>(header.data_), 20);   if (header.version() != 4)     is.setstate(std::ios::failbit);   std::streamsize options_length = header.header_length() - 20;   if (options_length &lt; 0 || options_length > 40)     is.setstate(std::ios::failbit);   else     is.read(reinterpret_cast&lt;char *>(header.data_) + 20, options_length);   return is; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u044b <code>IcmpSender<\/code> \u0438 <code>IcmpReceiver<\/code> \u0434\u043b\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f icmp-\u043f\u0430\u043a\u0435\u0442\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">class IcmpSender { public:   IcmpSender() = delete;   IcmpSender(const IcmpSender &amp;) = delete;   IcmpSender(const IcmpSender &amp;&amp;) = delete;   IcmpSender &amp; operator=(const IcmpSender &amp;) = delete;   IcmpSender &amp; operator=(const IcmpSender &amp;&amp;) = delete;   IcmpSender(boost::asio::io_context &amp;, const char *, uint16_t,               uint16_t, std::mutex &amp;, std::condition_variable &amp;);  private:   void StartSend();    icmp::endpoint destination_;   icmp::socket socket_;   uint16_t sequence_number_;   uint16_t count_;   chrono::steady_clock::time_point time_sent_;   boost::asio::streambuf reply_buffer_;   std::size_t interval_;   std::size_t size_;   std::mutex &amp;mtx_;   std::condition_variable &amp;condition_; };  class IcmpReceiver { public:   IcmpReceiver() = delete;   IcmpReceiver(const IcmpReceiver &amp;) = delete;   IcmpReceiver(const IcmpReceiver &amp;&amp;) = delete;   IcmpReceiver &amp; operator=(const IcmpReceiver &amp;) = delete;   IcmpReceiver &amp; operator=(const IcmpReceiver &amp;&amp;) = delete;   IcmpReceiver(boost::asio::io_context &amp;, int &amp;,                 std::unordered_map&lt;uint32_t, uint32_t> &amp;,                 std::mutex &amp;, std::condition_variable &amp;);  private:   void StartReceive();   void CheckIfSendersExist();   void HandleReceive(std::size_t length);    icmp::socket socket_;   boost::asio::streambuf reply_buffer_;   int &amp;senders_count_;   std::unordered_map&lt;uint32_t, uint32_t> &amp;ping_results_;   std::mutex &amp;mtx_;   std::condition_variable &amp;condition_;   bool senders_unlocked_ = false;   boost::asio::deadline_timer dt_;   const boost::posix_time::time_duration      kReceiveTimerFrequency = boost::posix_time::seconds(5); }; <\/code><\/pre>\n<p>\u041f\u0440\u043e\u0439\u0434\u0451\u043c\u0441\u044f \u043f\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043f\u043e\u043b\u044f\u043c \u043a\u043b\u0430\u0441\u0441\u0430 <code>IcmpSender<\/code>:<\/p>\n<ul>\n<li>\n<p><code>destination_<\/code> &#8212; IP, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u043d\u0433\u043e\u0432\u0430\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p><code>socket_<\/code> &#8212; \u0441\u043e\u043a\u0435\u0442 Asio \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 ICMP-\u043f\u0430\u043a\u0435\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p><code>sequence_number_<\/code> &#8212; \u043d\u043e\u043c\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u0430 ICMP;<\/p>\n<\/li>\n<li>\n<p><code>count_<\/code>, <code>interval_<\/code>, <code>size_<\/code> &#8212; \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043c\u0435\u0436\u0434\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430\u043c\u0438 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p><code>mtx_<\/code> \u0438 <code>condition_variable_<\/code> &#8212; \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 <code>IcmpReceiver<\/code> \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f:<\/p>\n<ul>\n<li>\n<p>\u0421\u043e\u043a\u0435\u0442 <code>socket_<\/code> \u0438 \u0431\u0443\u0444\u0435\u0440 <code>reply_buffer_<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 ICMP;<\/p>\n<\/li>\n<li>\n<p><code>senders_count_<\/code> &#8212; \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432-\u0441\u0435\u043d\u0434\u0435\u0440\u043e\u0432. \u041a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u043d\u043e \u043d\u0443\u043b\u044e, \u043c\u044b \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u043c \u043b\u043e\u0432\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b;<\/p>\n<\/li>\n<li>\n<p><code>ping_results_<\/code> &#8212; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0438\u043d\u0433\u0430 (\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432). \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c IP-\u0430\u0434\u0440\u0435\u0441, \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0439 \u0432 32-\u0431\u0438\u0442\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e;<\/p>\n<\/li>\n<li>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0432 \u043a\u043b\u0430\u0441\u0441\u0435-\u0441\u0435\u043d\u0434\u0435\u0440\u0435, \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0430\u043c\u0438 \u043d\u0430 \u043e\u0431\u0449\u0438\u0439 \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><code>kReceiveTimerFrequency<\/code> &#8212; \u044d\u0442\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439 \u043c\u044b \u0437\u0430\u0434\u0430\u0451\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0435\u043a\u0443\u043d\u0434, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0442\u0430\u0439\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043b\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438-\u0441\u0435\u043d\u0434\u0435\u0440\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">void IcmpSender::StartSend() {   std::string body(size_ - sizeof(Icmp), '\\0');   \/\/ Create an ICMP header   Icmp icmp;   icmp.type(Icmp::kEchoRequest);   icmp.code(0);   icmp.identifier(static_cast&lt;uint16_t>(getpid()));   for (size_t i = 0; i &lt; count_; i++) {     icmp.sequence_number(++sequence_number_);     icmp.CalculateChecksum(body.begin(), body.end());     \/\/ Encode the request packet     boost::asio::streambuf requestBuffer;     std::ostream outputStream(&amp;requestBuffer);     outputStream &lt;&lt; icmp &lt;&lt; body;      \/\/ Send the request     socket_.send_to(requestBuffer.data(), destination_);     std::this_thread::sleep_for(std::chrono::milliseconds(interval_));   } }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e: \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u0441\u043e\u043a\u0435\u0442 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0441\u0434\u0432\u0438\u0433\u0430. \u041c\u0435\u0436\u0434\u0443 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0441\u044b\u043f\u0430\u0435\u043c \u043d\u0430 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u043b\u0435\u043c <code>interval_<\/code> \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043b\u043e\u0432\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0417\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u0432\u0441\u0451 \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435:<\/p>\n<pre><code class=\"cpp\">void IcmpReceiver::StartReceive() {   \/\/ Discard any data already in the buffer   reply_buffer_.consume(reply_buffer_.size());   if ((!senders_unlocked_) || (senders_unlocked_ &amp;&amp; senders_count_ > 0)) {     socket_.async_receive(reply_buffer_.prepare(65536),       boost::bind(&amp;IcmpReceiver::HandleReceive, this, boost::placeholders::_2));     dt_.async_wait(boost::bind(&amp;IcmpReceiver::CheckIfSendersExist, this));   }   if (!senders_unlocked_) {     {       std::unique_lock&lt;std::mutex> ul(mtx_);       \/\/ Notifying senders: we are ready to catch echo replies       condition_.notify_all();     }     senders_unlocked_ = true;   } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u043a\u0435\u0442 \u043a \u043c\u0435\u0442\u043e\u0434\u0443 <code>HandleReceive<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b. \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0442\u0430\u0439\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0436\u0438\u0432\u044b \u043b\u0438 \u043f\u043e\u0442\u043e\u043a\u0438-\u0441\u0435\u043d\u0434\u0435\u0440\u044b (<code>CheckIfSendersExists<\/code>). \u041c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b &#8212; \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u044d\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u0442\u043e\u043a\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434 <code>notify_all()<\/code> \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u041a\u043e\u0433\u0434\u0430 \u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0438-\u0441\u0435\u043d\u0434\u0435\u0440\u044b \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u044f\u0442 \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443, \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u0430\u0439\u043c\u0435\u0440 \u0438 \u0441\u043e\u043a\u0435\u0442:<\/p>\n<pre><code class=\"cpp\">void IcmpReceiver::CheckIfSendersExist() {   int count;   {     std::unique_lock&lt;std::mutex> ul(mtx_);     count = senders_count_;   }   \/\/ Stopping catching replies if all senders have been finished   if (count == 0) {     dt_.cancel();     socket_.cancel();   } }<\/code><\/pre>\n<p>\u041f\u043e\u043a\u0430 \u0436\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0438\u0434\u0451\u0442, \u043b\u043e\u0432\u0438\u043c \u043f\u0430\u043a\u0435\u0442\u044b:<\/p>\n<pre><code class=\"cpp\">void IcmpReceiver::HandleReceive(std::size_t length) {   reply_buffer_.commit(length);    \/\/ Decode the reply packet   std::istream input_stream(&amp;reply_buffer_);   Ipv4 ipv4;   Icmp icmp;   input_stream >> ipv4 >> icmp;   if (input_stream &amp;&amp; icmp.type() == Icmp::kEchoReply   &amp;&amp; icmp.identifier() == static_cast&lt;uint16_t>(getpid())) {     dt_.cancel();     uint32_t src = ipv4.source_address_uint32();     {       std::lock_guard lg(mtx_);       ping_results_[src]++;     }   }   {     std::lock_guard lg(mtx_);     if(senders_count_ > 0)       StartReceive();   } }<\/code><\/pre>\n<p>\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0434\u043b\u044f IP, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0438\u0448\u0451\u043b \u043e\u0442\u0432\u0435\u0442, \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 <code>ping_results_<\/code>.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u043a\u0430\u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441-\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430:<\/p>\n<pre><code class=\"cpp\">class Scheduler { public:   Scheduler(OptionsLosshd &amp;);   ~Scheduler();   void Run();   void Clean();  private:   uint32_t GetIpFromString (const std::string &amp;str_ip);   std::string GetIpFromUint32 (const uint32_t ip) const;   std::vector&lt;std::string> GetAddressesForPing() const;   auto CreateReceiver();   auto CreateSender();    OptionsLosshd &amp;options_;   pqxx::connection conn_;   pqxx::nontransaction mutable txn_;   std::mutex mtx_;   std::vector&lt;std::string> address_list_;   std::unordered_map&lt;uint32_t, uint32_t> ping_results_;   std::condition_variable condition_; };<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0443 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Scheduler<\/code> \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043e\u043f\u0446\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438. \u041c\u0435\u0442\u043e\u0434\u044b <code>CreateReceiver<\/code> \u0438 <code>CreateSender<\/code> \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430 &#8212; \u043e\u043d\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0435 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043f\u043e\u0442\u043e\u043a\u0430 <code>std::thread<\/code>. \u0423 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0435 \u043f\u043e\u043b\u044f:<\/p>\n<ul>\n<li>\n<p><code>options_<\/code> &#8212; \u043d\u0430\u0431\u043e\u0440 \u043e\u043f\u0446\u0438\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p><code>conn_<\/code> &#8212; \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0421\u0423\u0411\u0414;<\/p>\n<\/li>\n<li>\n<p><code>txn_<\/code> &#8212; \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p><code>address_list_<\/code> &#8212; \u043f\u0435\u0440\u0435\u0447\u0435\u043d\u044c \u0430\u0434\u0440\u0435\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u043d\u0433\u043e\u0432\u0430\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p><code>ping_results_<\/code> &#8212; \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u043d\u0430\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u043f\u0438\u043d\u0433\u0430;<\/p>\n<\/li>\n<li>\n<p><code>condition_<\/code>, <code>mtx_<\/code> &#8212; \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0447\u0435\u043d\u044c \u0430\u0434\u0440\u0435\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u043d\u0433\u043e\u0432\u0430\u0442\u044c, \u043f\u043e\u043f\u0443\u0442\u043d\u043e \u0443\u0434\u0430\u043b\u044f\u044f \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0430\u0434\u0440\u0435\u0441\u0430, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0435 \u0441\u043d\u0438\u043c\u0430\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043d\u0435\u0434\u0435\u043b\u0438:<\/p>\n<pre><code class=\"cpp\">std::vector&lt;std::string> Scheduler::GetAddressesForPing() const {   std::string req = \"\";   std::vector&lt;std::string> addresses;   txn_.exec(\"DELETE FROM ext_packetlosshd_dbg WHERE last_read + interval '7 days' &lt; NOW()\");   for (auto row: txn_.exec(\"SELECT ip FROM ext_packetlosshd_dbg LIMIT 100\"))     addresses.push_back(row[0].c_str());   return addresses; }<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">void Scheduler::Run() {   std::vector&lt;std::thread> threads;   int senders_count = address_list_.size();   \/\/ Starting ICMP receiver   std::thread t(CreateReceiver(), std::ref(senders_count),                  std::ref(ping_results_), std::ref(mtx_), std::ref(condition_));   \/\/ Starting ICMP senders   for (size_t i = 0; i &lt; address_list_.size(); i++) {     std::thread t(CreateSender(), address_list_[i],                    std::ref(senders_count), std::ref(mtx_),                    std::ref(condition_), std::ref(options_));     threads.push_back(std::move(t));   }   \/\/ Joining senders   for (size_t i = 0; i &lt; threads.size(); i++)      threads.at(i).join();   \/\/ Joining receiver   t.join();   std::cout &lt;&lt; \"End of collecting results:\" &lt;&lt; std::endl;   for (auto i: ping_results_) {     std::cout &lt;&lt; \"from IP \" &lt;&lt;  GetIpFromUint32(i.first) &lt;&lt;        \" received: \" &lt;&lt; i.second &lt;&lt; std::endl;     txn_.exec(\"UPDATE ext_packetlosshd_dbg SET \\         loss = \" + std::to_string(           static_cast&lt;double>(options_.get_count() - i.second) \/            options_.get_count() * 100) + \", \" + \" \\         last_update = NOW() \\         WHERE \\         ip = '\" + GetIpFromUint32(i.first) + \"'\");   }   std::cout &lt;&lt; std::endl; }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0438\u0445 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u0442\u043e\u043a-\u0441\u0435\u043d\u0434\u0435\u0440:<\/p>\n<pre><code class=\"cpp\">auto Scheduler::CreateSender() {   return [](std::string address, int &amp;senders, std::mutex &amp;mtx,              std::condition_variable &amp;condition, OptionsLosshd &amp;options) {     {       std::unique_lock&lt;std::mutex> ul(mtx);       \/\/ Waiting for receiver starts       condition.wait(ul);     }     boost::asio::io_context io_context;     IcmpSender pinger(io_context, address.c_str(), options.get_count(),                        options.get_interval(), mtx, condition);     {       std::lock_guard lg(mtx);       senders--;     }   }; }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u043f\u043e\u0442\u043e\u043a\u0438-\u0441\u0435\u043d\u0434\u0435\u0440\u044b \u043d\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 \u043f\u043e\u0442\u043e\u043a\u0430-\u0440\u0435\u0441\u0438\u0432\u0435\u0440\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u0430 <code>notify_all()<\/code>.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043a \u043d\u043e\u0432\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0447\u0435\u043d\u044c \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0438 \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438:<\/p>\n<pre><code class=\"cpp\">void Scheduler::Clean() {   ping_results_.clear();   address_list_ = GetAddressesForPing();   for (auto address: address_list_)     ping_results_.insert({GetIpFromString(address), 0}); }<\/code><\/pre>\n<p>\u041d\u0443 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main()<\/code>:<\/p>\n<pre><code class=\"cpp\">int main(int argc, char *argv[]) {   constexpr auto kPauseBetweenIterations = std::chrono::seconds(5);   OptionsLosshd options(argc, argv);   if (options.is_daemon()) {     std::cout &lt;&lt; \"Running as a daemon...\" &lt;&lt; std::endl;     auto pid = fork();     if (pid > 0)       return EXIT_SUCCESS;     if (pid &lt; 0) {       std::cerr &lt;&lt; \"Error while doing fork()! Exiting...\";       return EXIT_FAILURE;     }     umask(0);     setsid();     if (chdir(\"\/\") &lt; 0) {       std::cerr &lt;&lt; \"Error while attempting chdir()!\" &lt;&lt; std::endl;       return EXIT_FAILURE;     };     close(STDIN_FILENO);     close(STDOUT_FILENO);     close(STDERR_FILENO);   }   Scheduler scheduler(options);   while (true) {     std::cout &lt;&lt; \"New iteration started. Pinging hosts...\" &lt;&lt; std::endl;     scheduler.Run();     scheduler.Clean();     std::this_thread::sleep_for(kPauseBetweenIterations);   }   return EXIT_SUCCESS; }<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0434\u0435\u043c\u043e\u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0434\u043b\u044f UNIX \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>fork()<\/code>.<\/p>\n<h4>\u0421\u0431\u043e\u0440\u043a\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a<\/h4>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442. \u042f \u0431\u0443\u0434\u0443 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 Ubuntu 22.04 LTS \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c CMake \u0438 conan:<\/p>\n<details class=\"spoiler\">\n<summary>conanfile.txt<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>[requires] boost\/1.74.0 libpqxx\/6.4.8  [generators] CMakeDeps CMakeToolchain<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>CMakeLists.txt<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cmake\">cmake_policy(SET CMP0048 NEW) project(LossHD VERSION 1.0.3) cmake_minimum_required(VERSION 3.18) set(CMAKE_CXX_FLAGS \"-O2\") find_package(Boost REQUIRED COMPONENTS program_options REQUIRED) find_package(libpqxx REQUIRED) add_executable(losshd src\/losshd.cpp src\/options.cpp) set_property(TARGET losshd PROPERTY CXX_STANDARD 20) set_property(TARGET losshd PROPERTY CXX_STANDARD_REQUIRED On) set_property(TARGET losshd PROPERTY CXX_EXTENSIONS Off) target_link_libraries(losshd boost_program_options pqxx) add_executable(getloss src\/getloss.cpp src\/options.cpp) set_property(TARGET getloss PROPERTY CXX_STANDARD 20) set_property(TARGET getloss PROPERTY CXX_STANDARD_REQUIRED On) set_property(TARGET getloss PROPERTY CXX_EXTENSIONS Off) target_link_libraries(getloss boost_program_options pqxx)<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<pre><code class=\"bash\">mkdir build cd build conan install .. -of ..\/conan cmake .. -DCMAKE_TOOLCHAIN_FILE=..\/conan\/conan_toolchain.cmake \\   -DCMAKE_BUILD_TYPE=Release cmake --build .<\/code><\/pre>\n<p>\u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 build \u0434\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u0430: <code>getloss<\/code> \u0438 losshd. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <code>losshd<\/code>:<\/p>\n<pre><code class=\"bash\">.\/losshd -nzabbix -h127.0.0.1 -Upostgres -Ppassword -i100 -s1400 -c10000 --daemon<\/code><\/pre>\n<p>\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c <code>getloss<\/code> \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 <code>\/usr\/local\/bin<\/code>. \u0412 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438 zabbix \u0441\u043e\u0437\u0434\u0430\u0451\u043c bash-\u0441\u043a\u0440\u0438\u043f\u0442 <code>getloss.sh<\/code>:<\/p>\n<pre><code class=\"cpp\">#!\/bin\/bash  \/usr\/local\/bin\/getloss -nzabbix -h127.0.0.1 -Upostgres -Ppassword -A $1<\/code><\/pre>\n<h4>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Zabbix<\/h4>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0443\u0441\u0442\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d. \u042f \u043d\u0430\u0437\u0432\u0430\u043b \u0435\u0433\u043e ICMP Packet Loss HD. \u0412 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/659\/41e\/65c\/65941e65cf56deccfd30a9e8963b385d.png\" width=\"642\" height=\"269\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/659\/41e\/65c\/65941e65cf56deccfd30a9e8963b385d.png\"\/><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u0443\u0437\u043b\u0430\u043c \u0441\u0435\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043d\u043e\u0435 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0432\u044f\u0437\u0438. \u0416\u0434\u0451\u043c \u0438 \u043d\u0430\u0441\u043b\u0430\u0436\u0434\u0430\u0435\u043c\u0441\u044f \u0442\u0430\u043a\u0438\u043c\u0438 \u0433\u0440\u0430\u0444\u0438\u043a\u0430\u043c\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3d1\/8a9\/17f\/3d18a917f70dadee192d69c50ad63dfb.png\" width=\"1266\" height=\"354\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3d1\/8a9\/17f\/3d18a917f70dadee192d69c50ad63dfb.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d51\/060\/bf4\/d51060bf4661851706dfd95fb6c9623e.png\" width=\"1266\" height=\"354\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d51\/060\/bf4\/d51060bf4661851706dfd95fb6c9623e.png\"\/><\/figure>\n<h4>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h4>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441\u043e\u043c \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u0441\u0451 \u0436\u0435 \u0434\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0449\u0438:<\/p>\n<ol>\n<li>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0432\u043c\u0435\u0441\u0442\u043e <code>std::cout<\/code>, \u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438 \u0432 \u0431\u0430\u0437\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 libpqxx (\u043e\u0431\u0440\u044b\u0432 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0421\u0423\u0411\u0414 \u0438 \u0442.\u0434.).<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043c\u0435\u043d\u044f \u0435\u0441\u0442\u044c \u043d\u0435\u0445\u0432\u0430\u0442\u043a\u0430 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434-\u0440\u0435\u0432\u044c\u044e, \u0431\u0443\u0434\u0443 \u0440\u0430\u0434 \u043b\u044e\u0431\u043e\u0439 \u043a\u0440\u0438\u0442\u0438\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u043c\u043e\u0439 \u043a\u043e\u0434 \u043b\u0443\u0447\u0448\u0435. \u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0438 \u0432\u0430\u043c \u043f\u043e\u043c\u043e\u0433\u043b\u0430 \u043c\u043e\u044f \u0437\u0430\u043c\u0435\u0442\u043a\u0430.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/732922\/\"> https:\/\/habr.com\/ru\/articles\/732922\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0418\u0437\u043c\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Zabbix External Check \u0438 C++ Boost.Asio<\/h2>\n<h4>\u041d\u0430\u0447\u0430\u043b\u043e<\/h4>\n<p>\u0412\u0441\u0435\u043c \u0445\u043e\u0440\u043e\u0448 Zabbix, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432 \u0434\u043b\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a. \u0412 \u0444\u0430\u0439\u043b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0443\u043a\u0430\u0437\u0430\u043d \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 30 \u0441\u0435\u043a\u0443\u043d\u0434, \u0447\u0435\u0433\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043f\u0438\u043d\u0433\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c 10 000 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0432 100 \u043c\u0441. \u041a\u0430\u043a \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u043f\u043e \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u0438\u043c \u043d\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u0430\u043c \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0432 \u0441\u0435\u0442\u044f\u0445 \u0441\u0432\u044f\u0437\u0438 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043f\u0430\u043a\u0435\u0442 \u043d\u0430 \u0442\u044b\u0441\u044f\u0447\u0443. \u041e\u0441\u043e\u0431\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0438 \u0442\u0440\u0430\u043a\u0442\u0443\u044e\u0442 \u044d\u0442\u0443 \u0446\u0438\u0444\u0440\u0443 \u043f\u043e-\u0441\u0432\u043e\u0435\u043c\u0443: \u0432\u0441\u0451 \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043b\u0438 \u0440\u0430\u0432\u043d\u043e 0,05% \u043c\u043e\u0436\u043d\u043e \u043e\u043a\u0440\u0443\u0433\u043b\u0438\u0442\u044c \u0434\u043e \u0442\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 0,1% \u0438\u043b\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u043d\u0430 \u0442\u044b\u0441\u044f\u0447\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u0434\u043b\u044f \u0441\u0430\u043c\u044b\u0445 \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u044b\u0445 \u0443\u0437\u043b\u043e\u0432, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0438 \u0437\u0430\u044f\u0432\u043a\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 (\u043d\u0430\u0437\u043e\u0432\u0451\u043c \u0435\u0451 <code>losshd<\/code>), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u0431\u0430\u0437\u0443, \u0430 \u0434\u043b\u044f Zabbix \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443 (\u043d\u0430\u0437\u043e\u0432\u0451\u043c \u0435\u0451 <code>getloss<\/code>), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u044b\u0442\u0430\u0449\u0438\u0442 \u0438\u0437 \u0431\u0430\u0437\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0420\u0430\u0441\u043f\u0438\u0448\u0435\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443<br \/> <code>getloss -hlocalhost --dbname=zabbix --dbuser=zabbix --dbpass=mypassword      --address=192.168.0.1<\/code><br \/> \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0435\u0441\u0442\u044c \u043b\u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0430 losshd \u0430\u0434\u0440\u0435\u0441 192.168.0.1. \u0415\u0441\u043b\u0438 \u0434\u0430 \u2013 \u0434\u043e\u0441\u0442\u0430\u0451\u0442 \u0438\u0437 \u0431\u0430\u0437\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f loss \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442 \u2013 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 0 (\u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0442\u0435\u0440\u044c \u043d\u0435\u0442, \u043f\u043e\u043a\u0430 \u0438\u0445 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043d\u0435 \u0434\u043e\u043a\u0430\u0437\u0430\u043d\u043e);<\/p>\n<\/li>\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0441\u0447\u0451\u0442\u0447\u0438\u043a <code>last_read<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0410 \u0432\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u0435\u043c\u043e\u043d\u0430 <code>losshd<\/code>:<\/p>\n<ol>\n<li>\n<p>\u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0437 \u0431\u0430\u0437\u044b \u0432\u0441\u0435 ip-\u0430\u0434\u0440\u0435\u0441\u0430, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 ICMP Echo Request \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 (\u0434\u0430\u043b\u0435\u0435 &#8212; <em>\u0441\u0435\u043d\u0434\u0435\u0440\u044b<\/em>);<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0434\u0438\u043d \u043e\u0431\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0434\u043b\u044f \u043b\u043e\u0432\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u2013 ICMP Echo Reply (\u0434\u0430\u043b\u0435\u0435 &#8212; <em>\u0440\u0435\u0441\u0438\u0432\u0435\u0440<\/em>);<\/p>\n<\/li>\n<li>\n<p>\u041e\u0436\u0438\u0434\u0430\u0435\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0441\u0435\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u043f\u043e\u0442\u0435\u0440\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e IP;<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0431\u0430\u0437\u0443;<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 <code>last_read<\/code> \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043d\u0435\u0434\u0435\u043b\u0438 \u043d\u0430\u0437\u0430\u0434. \u0422\u0430\u043a \u043c\u044b \u0441\u043d\u0438\u0437\u0438\u043c \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0434\u0435\u043c\u043e\u043d <code>losshd<\/code>, \u0443\u0431\u0438\u0440\u0430\u044f \u043d\u0435\u0432\u043e\u0441\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0432\u0441\u0451 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430.<\/p>\n<\/li>\n<\/ol>\n<p>\u0418\u0442\u0430\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u0432\u0435\u0441\u044c \u043a\u043e\u0434, \u0438\u043d\u0430\u0447\u0435 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043e\u0431\u044a\u0451\u043c\u043d\u043e\u0439. \u041c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0435\u0433\u043e \u0432 \u043c\u043e\u0451\u043c \u0433\u0438\u0442\u0445\u0430\u0431\u0435: <a href=\"https:\/\/github.com\/Lordgprs\/losshd\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Lordgprs\/losshd<\/a>.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0451 \u0432  \u0442\u043e\u0439 \u0436\u0435 \u0431\u0430\u0437\u0435, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 Zabbix server. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e PostgreSQL:<\/p>\n<pre><code class=\"sql\">CREATE TABLE ext_packetlosshd_dbg (   ip inet NOT NULL PRIMARY KEY,   loss DOUBLE PRECISION NOT NULL DEFAULT 0,   last_update TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(),   last_read TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW() );<\/code><\/pre>\n<p>\u041d\u0430\u0448 \u043a\u043e\u0434 \u043d\u0430 C++ \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0448\u0435\u0441\u0442\u0438 \u0444\u0430\u0439\u043b\u043e\u0432: <code>options.h<\/code>, <code>options.cpp<\/code>, <code>getloss.h<\/code>, <code>getloss.cpp<\/code>, <code>losshd.h<\/code>, <code>losshd.cpp<\/code>. \u042f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0432\u044b\u0431\u043e\u0440\u043e\u0447\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e. <\/p>\n<h4>\u0423\u0442\u0438\u043b\u0438\u0442\u0430 getloss<\/h4>\n<p>\u041f\u0438\u0448\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">class Options { public:   Options() = delete;   Options(const Options &amp;) = delete;   Options(const Options &amp;&amp;) = delete;   Options &amp; operator=(const Options &amp;) = delete;   Options &amp; operator=(const Options &amp;&amp;) = delete;   Options (int, char **); protected:   po::options_description desc_;   po::variables_map vm_; };  Options::Options(int argc, char **argv): desc_(\"Allowed options\") { }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u0432\u0441\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 <code>argc<\/code> \u0438 <code>argv<\/code> (\u0432\u043f\u0440\u043e\u0447\u0435\u043c, \u0442\u043e\u0436\u0435 \u043f\u0443\u0441\u0442\u043e\u0439). \u041f\u0435\u0440\u0435\u0447\u0435\u043d\u044c \u043e\u043f\u0446\u0438\u0439 \u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0441\u0430\u0445-\u043f\u043e\u0442\u043e\u043c\u043a\u0430\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0435\u043b\u0430\u0435\u043c \u0438\u0445 <code>protected<\/code>. <\/p>\n<p>\u041f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u043e\u043f\u0446\u0438\u0439 \u0434\u043b\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u044b <code>getloss<\/code>:<\/p>\n<pre><code class=\"cpp\">class OptionsGetloss : public Options { public:   OptionsGetloss() = delete;   OptionsGetloss(const OptionsGetloss &amp;) = delete;   OptionsGetloss(const OptionsGetloss &amp;&amp;) = delete;   OptionsGetloss &amp; operator=(const OptionsGetloss &amp;) = delete;   OptionsGetloss &amp; operator=(const OptionsGetloss &amp;&amp;) = delete;   OptionsGetloss(int argc, char **argv);   void CheckOptions();   std::string get_dbname() const;   std::string get_dbhost() const;   std::string get_dbuser() const;   std::string get_dbpass() const;   std::string get_address() const; };<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0438 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b:<\/p>\n<pre><code class=\"cpp\">OptionsGetloss::OptionsGetloss(int argc, char *argv[]) : Options(argc, argv) {   desc_.add_options()     (\"help\", \"this help\")     (\"dbname,n\", po::value&lt;std::string>(), \"database name\")     (\"dbhost,h\", po::value&lt;std::string>(), \"database server address\")     (\"dbuser,U\", po::value&lt;std::string>(), \"database user name\")     (\"dbpass,P\", po::value&lt;std::string>(), \"database password\")     (\"address,A\", po::value&lt;std::string>(), \"address to ping\");   po::store(po::parse_command_line(argc, argv, desc_), vm_);   po::notify(vm_);    CheckOptions(); }  void OptionsGetloss::CheckOptions() {   if (vm_.count(\"help\") != 0) {     std::cout &lt;&lt; desc_ &lt;&lt; std::endl;     std::exit(EXIT_SUCCESS);   }   if (     vm_.count(\"dbname\") == 0 ||     vm_.count(\"dbhost\") == 0 ||     vm_.count(\"dbuser\") == 0 ||     vm_.count(\"address\") == 0    ) {     std::cerr &lt;&lt; \"Error via processing arguments!\" &lt;&lt; std::endl &lt;&lt; std::endl;     std::cerr &lt;&lt; desc_ &lt;&lt; std::endl;     std::exit(EXIT_FAILURE);   } }<\/code><\/pre>\n<p>\u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0421\u0423\u0411\u0414:<\/p>\n<pre><code class=\"cpp\">class Database { public:   Database() = delete;   Database(const OptionsGetloss &amp;);   ~Database();   double get_loss(const std::string &amp;) const; private:   pqxx::connection conn_;   pqxx::work mutable txn_; };  double Database::get_loss(const std::string &amp;ip) const {   double loss = 0;   std::string req = \"SELECT loss FROM ext_packetlosshd_dbg WHERE ip = '\" + ip + \"'\";   auto result = txn_.exec(req);   if (result.size() > 0) {     loss = result[0][0].as&lt;double>();     txn_.exec(\"UPDATE ext_packetlosshd_dbg SET last_read = NOW() WHERE ip = '\" + ip + \"'\");   }   else     txn_.exec(\"INSERT INTO ext_packetlosshd_dbg (ip) VALUES ('\" + ip + \"')\");   return loss; }<\/code><\/pre>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>main()<\/code> \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043e\u043f\u0446\u0438\u0439 \u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0421\u0423\u0411\u0414 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0446\u0438\u0444\u0440\u0443 \u0441 \u043f\u043e\u0442\u0435\u0440\u044f\u043c\u0438 \u0438\u0437 \u0431\u0430\u0437\u044b \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0432\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u043c\u0443 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0443:<\/p>\n<pre><code class=\"cpp\">int main(int argc, char **argv) {   OptionsGetloss options(argc, argv);   Database db(options);   std::cout &lt;&lt; db.get_loss(options.get_address()) &lt;&lt; std::endl;   return EXIT_SUCCESS; }<\/code><\/pre>\n<p>\u0412\u044b\u0432\u043e\u0434\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0440\u0432\u0435\u0440 Zabbix \u0441\u043c\u043e\u0433 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u043e\u0442\u0442\u0443\u0434\u0430. \u041f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0434\u0435\u0441\u044c \u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 &#8212; \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043d\u0451\u043c \u043d\u0435\u0442.<\/p>\n<h4>\u0414\u0435\u043c\u043e\u043d losshd<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0439\u043c\u0451\u043c\u0441\u044f \u0441\u0435\u0440\u0434\u0446\u0435\u043c \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438: \u0434\u0435\u043c\u043e\u043d\u043e\u043c <code>losshd<\/code>. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 <code>Ipv4<\/code> \u0438 <code>Icmp<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432\u0437\u044f\u0442\u044b \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043a Boost.Asio:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Ipv4 \u0438 Icmp<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">class Ipv4 { public:   Ipv4();   char8_t version() const;   uint16_t header_length() const;   char8_t tos() const;   uint32_t time_to_live() const;   boost::asio::ip::address_v4 source_address() const;   uint32_t source_address_uint32() const;   friend std::istream &amp;operator>>(std::istream &amp;is, Ipv4 &amp;header);  private:   char8_t data_[60]; };  class Icmp { public:   enum {     kEchoReply = 0,     kDestinationUnreachable = 3,     kSourceQuench = 4,     kRedirect = 5,     kEchoRequest = 8,     kTimeExceeded = 11,     kParameterProblem = 12,     kTimestampRequest = 13,     kTimestampReply = 14,     kInfoRequest = 15,     kInfoReply = 16,     kAddressRequest = 17,     kAddressReply = 18   };   Icmp();   char8_t type() const;   char8_t code() const;   uint16_t identifier() const;   uint16_t sequence_number() const;   void type(char8_t);   void code(char8_t);   void checksum(uint16_t);   void identifier(uint16_t);   void sequence_number(uint16_t);   void CalculateChecksum(auto body_begin, auto body_end);   friend std::istream&amp; operator>>     (std::istream &amp;inputStream, Icmp &amp;header);   friend std::ostream&amp; operator&lt;&lt;     (std::ostream &amp;outputStream, const Icmp &amp;header);  private:   uint16_t Decode(int32_t a, int32_t b) const;   void Encode(int32_t a, int32_t b, uint16_t n);    char8_t data_[8]; };  Ipv4::Ipv4() {   std::fill (data_, data_ + sizeof(data_), 0); }  char8_t Ipv4::version() const {   return (data_[0] >> 4) &amp; 0xF; }  uint16_t Ipv4::header_length() const {   return (data_[0] &amp; 0xF) &lt;&lt; 2; }  char8_t Ipv4::tos() const {   return data_[1]; }  uint32_t Ipv4::time_to_live() const {   return data_[8]; }  boost::asio::ip::address_v4 Ipv4::source_address() const {   boost::asio::ip::address_v4::bytes_type bytes = {     {data_[12], data_[13], data_[14], data_[15]}   };   return boost::asio::ip::address_v4(bytes); }  uint32_t Ipv4::source_address_uint32() const {   return (data_[12] &lt;&lt; 24) |      (data_[13] &lt;&lt; 16) |      (data_[14] &lt;&lt; 8) |     data_[15]; }  Icmp::Icmp() {   std::fill(data_, data_ + sizeof(data_), 0); }  char8_t Icmp::type() const {   return data_[0]; }  char8_t Icmp::code() const {   return data_[1]; }  uint16_t Icmp::identifier() const {   return Decode(4, 5); }  uint16_t Icmp::sequence_number() const {   return Decode(6, 7); }  void Icmp::type(char8_t n) {   data_[0] = n; }  void Icmp::code(char8_t n) {   data_[1] = n; }  void Icmp::checksum(uint16_t n) {   Encode(2, 3, n); }  void Icmp::identifier(uint16_t n) {   Encode(4, 5, n); }  void Icmp::sequence_number(uint16_t n) {   Encode(6, 7, n); }  void Icmp::CalculateChecksum(auto body_begin, auto body_end) {   uint32_t sum = (type() &lt;&lt; 8) + code() + identifier() + sequence_number();   auto body_iterator = body_begin;   while (body_iterator != body_end) {     sum += (static_cast&lt;char8_t>(*body_iterator++) &lt;&lt; 8);     if (body_iterator != body_end)       sum += static_cast&lt;char8_t>(*body_iterator++);   }    sum = (sum >> 16) + (sum &amp; 0xFFFF);   sum += (sum >> 16);   checksum(static_cast&lt;uint16_t>(~sum)); }  uint16_t Icmp::Decode(const int32_t a, const int32_t b) const {   return (data_[a] &lt;&lt; 8) + data_[b]; }  void Icmp::Encode(const int32_t a, const int32_t b, const uint16_t n) {   data_[a] = static_cast&lt;char8_t>(n >> 8);   data_[b] = static_cast&lt;char8_t>(n &amp; 0xFF); }  std::istream&amp; operator>>(std::istream&amp; input_stream, Icmp &amp;header) {   return input_stream.read(reinterpret_cast&lt;char *>(header.data_), 8); }  std::ostream&amp; operator&lt;<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-412921","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/412921","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=412921"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/412921\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=412921"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=412921"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=412921"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}