Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2

Хочу сделать программу, контролирующую сетевой трафик моего компьютера. С чего начать?

18.07.2017, 21:54. Показов 1623. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Т.е. необходима программа, которая, будучи запущенной, резидентно отслеживала бы всю сетевую активность на компьютере. И сохраняла бы принятую/полученную информацию в виде лог-файла.
Знаю, что есть масса готовых программ. Но, хочу сделать свою. Подскажите хотя бы направление, куда копать.
Правильно ли я понимаю, что, по сути, это будет сниффер? Или можно реализовать при помощи другой идеологии?

Добавлено через 1 час 2 минуты
(Например, использовать слушающий сокет с константой INADDR_ANY).
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.07.2017, 21:54
Ответы с готовыми решениями:

Хочу сайт сделать, с чего начать?
Хочу сайт сделать, с чего начать?

Хочу сделать сайт. С чего начать?
Я хочу сделать сайт! Но даже не знаю с чего начать, вот уже 2 недели в пустую трачу время в поисках ответа в интернете, подскажите...

Хочу создать программу с GUI, не знаю с чего начать
Хочу написать очень простенькое десктопное приложение с GUI, но не знаю как. Оно должно состоять из инсталлятора, быть с иконкой и...

5
Почетный модератор
 Аватар для Humanoid
11556 / 4351 / 452
Регистрация: 12.06.2008
Сообщений: 12,454
18.07.2017, 22:18
Цитата Сообщение от Htext Посмотреть сообщение
Знаю, что есть масса готовых программ. Но, хочу сделать свою.
Полностью поддерживаю. Свою программу всегда можно гораздо лучше подогнать под свои задачи. Я уже не говорю об опыте, который вы получите в процессе разработки. У меня самого до сих пор на домашнем сервере (который ещё и функцию роутера выполняет) работает такая программа. Я её использую для подсчёта трафика и логов доменных имён, которые когда-либо переводились в IP-адреса.

Цитата Сообщение от Htext Посмотреть сообщение
Подскажите хотя бы направление, куда копать.
Я использовал библиотеку pcap для таких задач.

Цитата Сообщение от Htext Посмотреть сообщение
Правильно ли я понимаю, что, по сути, это будет сниффер?
Да.

Цитата Сообщение от Htext Посмотреть сообщение
Или можно реализовать при помощи другой идеологии?
Можно назвать сетевым анализатором. Но это тоже самое. Сниффер не является чем-то противозаконным, если вы им только свой трафик анализируете. Вот если вы будете делать всякие инъекции (обманывать роутер провайдера, что бы он присылал вам пакеты, которые адресованы другому компьютеру), что бы получить чужой трафик, тогда это будет уже незаконно.

Цитата Сообщение от Htext Посмотреть сообщение
Например, использовать слушающий сокет с константой INADDR_ANY
Если просто слушать TCP сокет, то вы просто будете получать соединения.
Вроде, можно использовать AF_PACKET при создании сокета, что бы получать низкоуровневые пакеты. Но я не пробовал.
1
 Аватар для Skjame
86 / 45 / 11
Регистрация: 20.12.2010
Сообщений: 217
Записей в блоге: 1
20.07.2017, 13:10
Я бы предложил использовать Linux kernel module и там сниферить с помощью netfilter
там можно сделать hook на любое направление пакетов (включая форвардинг).

А с помощью read-write операций сделал бы какой-нибудь протокол для обмена данными между модулем и десктопным приложением. Которое по сути было бы просто ui для отображения и мб для настройки.

Как по мне это более хороший вариант чем это делать из userspace'a
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
20.07.2017, 18:19
Как посоватовал Humanoid, используйте pcap. Или если хочется реализовать самому то SOCKET_RAW. Но это только sniff (т.е. прослушка)
1
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2
21.07.2017, 23:07  [ТС]
Цитата Сообщение от Humanoid Посмотреть сообщение
Вроде, можно использовать AF_PACKET при создании сокета, что бы получать низкоуровневые пакеты
Вот это заинтересовало. Хочу сделать на низком уровне. Нашел вот здесь: https://www.opennet.ru/base/de... e.txt.html
Ну, добавил библиотек, иначе не компилировалось. Вот коды первых 4-х листингов:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
/* Листинг 1. Файл analizator.h */
 
#include <linux/types.h>
 
#define PROMISC_MODE_ON 1 // флаг включения неразборчивый режим
#define PROMISC_MODE_OFF 0 // флаг выключения неразборчивого режима
 
struct ifparam {
    __u32 ip;   // IP адрес
    __u32 mask; // маска подсети
    int mtu;    // размер MTU
    int index;  // индекс интерфейса
} ifp;
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * Листинг 2. Функция определения параметров сетевого интерфейса и
 * переключения режимов (файл getifconf.c)
 */
 
#include <linux/socket.h>
#include <linux/ioctl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/in.h>
#include "analizator.h"
 
int getifconf(__u8 *intf, struct ifparam *ifp, int mode)
{
    int fd;
    struct sockaddr_in s;
    struct ifreq ifr; // см. <linux/if.h>
 
    memset((void *)&ifr, 0, sizeof(struct ifreq));
    if((fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) return (-1);
 
    sprintf(ifr.ifr_name,"%s",intf);
 
 
/*
 * Проверяем флаг режима. Если он установлен в 0, неразборчивый режим
 * необходимо отключить, поэтому сразу выполняется переход на метку setmode
 */
    if(!mode) goto setmode;
 
/*
 * Определяем IP адрес сетевого интерфейса
 */
    if(ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
    perror("ioctl SIOCGIFADDR");
    return -1;
    }
    memset((void *)&s, 0, sizeof(struct sockaddr_in));
    memcpy((void *)&s, (void *)&ifr.ifr_addr, sizeof(struct sockaddr));
    memcpy((void *)&ifp->ip, (void *)&s.sin_addr.s_addr, sizeof(__u32));
 
/*
 * Определяем маску подсети
 */
    if(ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) {
    perror("ioctl SIOCGIFNETMASK");
    return -1;
    }
    memset((void *)&s, 0, sizeof(struct sockaddr_in));
    memcpy((void *)&s, (void *)&ifr.ifr_netmask, sizeof(struct sockaddr));
    memcpy((void *)&ifp->mask, (void *)&s.sin_addr.s_addr, sizeof(u_long));
 
/*
 * Определяем размер MTU
 */
    if(ioctl(fd, SIOCGIFMTU, &ifr) < 0) {
    perror("ioctl SIOCGIFMTU");
    return -1;
    }
    ifp->mtu = ifr.ifr_mtu;
 
/*
 * Индекс интерфейса
 */
    if(ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
    perror("ioctl SIOCGIFINDEX");
    return -1;
    }
    ifp->index = ifr.ifr_ifindex;
 
 
/*
 * Устанавливаем заданный режим работы сетевого интерфейса
 */
setmode:
 
/*
 * Получаем значение флагов
 */
    if(ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
    perror("ioctl SIOCGIFFLAGS");
    close(fd);
    return -1;
    }
 
/*
 * В зависимости от значения третьего параметра функции, устанавливаем
 * или снимаем флаг неразборчивого режима
 */
    if(mode) ifr.ifr_flags |= IFF_PROMISC;
    else ifr.ifr_flags &= ~(IFF_PROMISC);
 
/*
 * Устанавливаем новое значение флагов интерфейса
 */
    if(ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
    perror("ioctl SIOCSIFFLAGS");
    close(fd);
    return (-1);
    }
 
    return 0;
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * Листинг 3. Функция создания пакетного сокета (файл getsock_recv.c)
 */
 
#include <net/if.h>
#include <netinet/in.h>
 
#include <linux/socket.h>
#include <linux/types.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
 
int getsock_recv(int index)
{
    int sd; // дескриптор сокета
/*
 * При работе с пакетными сокетами для хранения адресной информации
 * сетевого интерфейса вместо структуры sockaddr_in используется структура
 * sockaddr_ll (см. <linux/if_packet.h>)
 */
    struct sockaddr_ll s_ll;
 
/*
 * Cоздаем пакетный сокет. Т.к. MAC-адреса мы тоже собираемся обрабатывать,
 * параметр type системного вызова socket принимает значение SOCK_RAW
 */
    sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if(sd < 0) return -1;
 
    memset((void *)&s_ll, 0, sizeof(struct sockaddr_ll));
 
/*
 * Заполним поля адресной структуры s_ll
 */
    s_ll.sll_family = PF_PACKET; // тип сокета
    s_ll.sll_protocol = htons(ETH_P_ALL); // тип принимаемого протокола
    s_ll.sll_ifindex = index; // индекс сетевого интерфейса
 
/*
 * Привязываем сокет к сетевому интерфейсу. В принципе, делать это не
 * обязательно, если на хосте активен только один сетевой интерфейс.
 * При наличии двух и более сетевых плат пакеты будут приниматься сразу со всех
 * активных интерфейсов, и если нас интересуют пакеты только из одного сегмента
 * сети, целесообразно выполнить привязку сокета к нужному интерфейсу
 */
    if(bind(sd, (struct sockaddr *)&s_ll, sizeof(struct sockaddr_ll)) < 0) {
    close(sd);
    return -1;
    }
 
    return sd;
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Листинг 4. Главная функция (файл analizator.c)
 */
 
#include <stdio.h>
#include <signal.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include "analizator.h"
 
/*
 * В буфере buff будут сохранятся принятые сетевые пакеты.
 * Значение ETH_FRAME_LEN равно максимальной длине кадра Ethernet (1514)
 * и определено в <linux/if_ether.h>
 */
 __u8 buff[ETH_FRAME_LEN];
 
/*
 * Функция, которая заменит стандартный обработчик сигнала SIGINT.
 * Задача этой функции - по приходу сигнала SIGINT вывести интерфейс из
 * состояния "Promiscuous mode" в обычный режим
 */
void mode_off()
{
    if(getifconf("eth0", &ifp, PROMISC_MODE_OFF) < 0) {
    perror("getifconf");
    exit(-1);
    }
 
    return;
}
 
/*
 * Главная функция
 */
int main()
{
    __u32 num = 0;
    int eth0_if, rec = 0, ihl = 0;
    struct iphdr ip; // структура для хранения IP заголовка пакета
    struct tcphdr tcp; // TCP заголовок
    struct ethhdr eth; // заголовок Ethernet-кадра
    static struct sigaction act;
 
/*
 * Получаем параметры сетевого интерфейса eth0 и переводим его
 * в неразборчивый режим
 */
    if(getifconf("eth0", &ifp, PROMISC_MODE_ON) < 0) {
    perror("getifconf");
    return -1;
    }
 
printf("IP адрес - %s\n",inet_ntoa(&ifp.mask));
 
/*
 * Отобразим полученные параметры сетевого интерфейса
 */
    printf("IP адрес - %s\n",inet_ntoa(ifp.ip));
    printf("Маска подсети - %s\n",inet_ntoa(ifp.mask));
    printf("MTU - %d\n", ifp.mtu);
    printf("Индекс - %d\n", ifp.index);
 
/*
 * Получим дескриптор пакетного сокета
 */
    if((eth0_if = getsock_recv(ifp.index)) < 0) {
    perror("getsock_recv");
    return -1;
    }
 
/*
 * Определим новый обработчик сигнала SIGINT - функцию mode_off
 */
    act.sa_handler = mode_off;
    sigfillset(&(act.sa_mask));
    sigaction(SIGINT, &act, NULL);
 
/*
 * Запускаем бесконечный цикл приема пакетов
 */
    for(;;) {
 
    memset(buff, 0, ETH_FRAME_LEN);
    
    rec = recvfrom(eth0_if, (char *)buff, ifp.mtu + 18, 0, NULL, NULL);
    if(rec < 0 || rec > ETH_FRAME_LEN) {
        perror("recvfrom");
        return -1;
    }
 
    memcpy((void *)&eth, buff, ETH_HLEN);
    memcpy((void *)&ip, buff + ETH_HLEN, sizeof(struct iphdr));
    if((ip.version) != 4) continue;
    memcpy((void *)&tcp, buff + ETH_HLEN + ip.ihl * 4, sizeof(struct tcphdr));
 
/*
 * MAC-адреса отправителя и получателя
 */
    printf("\n%u\n", num++);
    printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\t->\t",
    eth.h_source[0],eth.h_source[1],eth.h_source[2],
    eth.h_source[3],eth.h_source[4],eth.h_source[5]);
 
    printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
    eth.h_dest[0],eth.h_dest[1],eth.h_dest[2],
    eth.h_dest[3],eth.h_dest[4],eth.h_dest[5]);
 
    printf("Длина заголовка - %d, ", (ip.ihl * 4));
    printf("длина пакета - %d\n", ntohs(ip.tot_len));
 
/*
 * Если транспортный протокол - TCP, отобразим IP адреса и порты
 * получателя и отправителя
 */
    if(ip.protocol == IPPROTO_TCP) {
        printf("%s (%d)\t->\t",inet_ntoa(ip.saddr), ntohs(tcp.source));
        printf("%s (%d)\n",inet_ntoa(ip.daddr), ntohs(tcp.dest));
        printf("TCP пакет\n");
    }
    }
 
    return 0;
}
Добавлено через 2 минуты
Скомпилировал. Запускаю (в виртуальной машине Linux) - программа НИЧЕГО не делает, никаких сообщений, попросту прекращает работу и все, возврат в командную строку. Может, кто подскажет, в чем может быть дело?
0
Почетный модератор
Эксперт по компьютерным сетямЭксперт Windows
 Аватар для magirus
28049 / 15785 / 983
Регистрация: 15.09.2009
Сообщений: 67,752
Записей в блоге: 78
24.07.2017, 09:44
создано во фрилансе. здесь закрыто.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.07.2017, 09:44
Помогаю со студенческими работами здесь

Хочу начать изучать Cisco с чего начать?
Вопрос у меня такой! Хочу в будущем изучать cisco но купить маршрутизатор дорого, а найти где-нибудь поэксперементировать, позаниматься...

Как сделать программу, в которой будут новости, обновляемые с моего компьютера?
Здравствуйте,мне нужно сделать программу,в которой будут новости,обновляемые с моего компьютера и чат,скажите как это можно реализовать?

Хочу начать учить C++ с чего начать?
Посоветуйте действительно хорошие книги/видео уроки по этому языку. За спиной у меня нет других языков программирования. Еще хочу задать...

Хочу начать изучать java. С чего посоветуете начать, какие книги или какие-то советы есть?
Хочу начать изучать java. С чего посоветуете начать, какие книги или какие-то советы есть? Спасибо заранее

С чего начать создание моего проекта: литература, статьи, примеры, библиотеки и т.п?
Здравствуйте, уважаемые! Ещё месяц назад решил приступить к реализации проекта и поэтому проходился по основам С++. На практике не создавал...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Закрытая тема Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru