Skip to content
This repository was archived by the owner on Sep 9, 2021. It is now read-only.

Conversation

rsvechnikov
Copy link

Инструкция по использованию

Все Linux-only. Тестировалось на Ubuntu 18.04.

DHCP-клиент

В аргуменах указываем наш MAC-адрес, в командную строку выводится полученный IP и время аренды. Так как протокол подразумевает конкретный порт, его выбор не предусмортрен. Может потребоваться отключить на время имеющийся DHCP-клиент.

DNS-сервер

Можно просто запустить, можно передать в качестве параметра ip адрес, к которому будет привязан сервер (по умолчанию - 127.0.0.53). Так как протокол подразумевает конкретный порт, его выбор не предусмортрен. Может потребоваться отключить на время имеющийся резолвер.

Инструкция по сборке/установке

Сборка как сервера, так и клиента, осуществляется с помощью cmake.

cmake --build <build path> --target lab2_dhcp_client

cmake --build <build path> --target lab2_dns_server

Описание

DHCP-клиент

Реализована базовая последовательность получения адреса: DISCOVERY -> OFFER -> REQUEST -> ACK.
Все остальные пакеты не поддерживаются.
ВАЖНО! Адрес отправителя не будет равным 0.0.0.0, если у хоста уже есть адрес. В коде использован IN_ADDR_ANY, подразумевающий выбор IP самой ОС.
После довольно продолжительных поисков выяснилось, что стандартными средствами сокетов нельзя явно установить адрес 0.0.0.0, если IP адрес уже имеется. Единственный выход - вручную формировать udp-пакет и помещать его в ethernet-кадр. Тем не менее, сервер на моём роутере все равно посылает OFFER в ответ на DISCOVERY с ненулевого IP (хотя, возможно, здесь уже от реализации сервера зависит).

Работа была протестирована в wireshark, вот pcap-файл.

DNS-сервер

Была реализована обработка запросов типа A, AAAA, MX и TXT. На все записи выдается фиксированный ответ в зависимости от типа запроса.
На все остальные запросы отправляется ответ со значением RCODE = Not Implemented.

Работа сервера была протестирована с помощью утилиты nslookup, сервер корректно распознавал запросы и выдавал корректные (с т.ч. протокола) ответы.

@wrbbz
Copy link
Contributor

wrbbz commented Jan 18, 2021

DNS сервер не собирается:

➜ cmake --build . --target lab2_dns_server
Scanning dependencies of target lab2_dns_server
[ 16%] Building CXX object CMakeFiles/lab2_dns_server.dir/src/dns/main.cpp.o
[ 33%] Building CXX object CMakeFiles/lab2_dns_server.dir/src/dns/protocol/Message.cpp.o
[ 50%] Building CXX object CMakeFiles/lab2_dns_server.dir/src/dns/protocol/QueryMessage.cpp.o
In file included from /tmp/2020H2/src/dns/protocol/Message.h:10,
                 from /tmp/2020H2/src/dns/protocol/QueryMessage.h:8,
                 from /tmp/2020H2/src/dns/protocol/QueryMessage.cpp:5:
/tmp/2020H2/src/dns/protocol/QueryMessage.cpp: In member function ‘int QueryMessage::decodeQuery(const char*)’:
/tmp/2020H2/src/dns/protocol/QueryMessage.cpp:45:63: error: cannot convert ‘QType’ to ‘__uint16_t’ {aka ‘short unsigned int’}
   45 |     query.type = static_cast<QType>((uint16_t) bswap_16(query.type));
      |                                                         ~~~~~~^~~~
      |                                                               |
      |                                                               QType
In file included from /usr/include/endian.h:35,
                 from /usr/include/sys/types.h:176,
                 from /usr/include/stdlib.h:394,
                 from /usr/include/c++/10.2.0/cstdlib:75,
                 from /usr/include/c++/10.2.0/ext/string_conversions.h:41,
                 from /usr/include/c++/10.2.0/bits/basic_string.h:6535,
                 from /usr/include/c++/10.2.0/string:55,
                 from /tmp/2020H2/src/dns/protocol/Message.h:9,
                 from /tmp/2020H2/src/dns/protocol/QueryMessage.h:8,
                 from /tmp/2020H2/src/dns/protocol/QueryMessage.cpp:5:
/usr/include/bits/byteswap.h:34:24: note:   initializing argument 1 of ‘__uint16_t __bswap_16(__uint16_t)’
   34 | __bswap_16 (__uint16_t __bsx)
      |             ~~~~~~~~~~~^~~~~
In file included from /tmp/2020H2/src/dns/protocol/Message.h:10,
                 from /tmp/2020H2/src/dns/protocol/QueryMessage.h:8,
                 from /tmp/2020H2/src/dns/protocol/QueryMessage.cpp:5:
/tmp/2020H2/src/dns/protocol/QueryMessage.cpp:47:66: error: cannot convert ‘QClass’ to ‘__uint16_t’ {aka ‘short unsigned int’}
   47 |     query.qClass = static_cast<QClass>((uint16_t) bswap_16(query.qClass));
      |                                                            ~~~~~~^~~~~~
      |                                                                  |
      |                                                                  QClass
In file included from /usr/include/endian.h:35,
                 from /usr/include/sys/types.h:176,
                 from /usr/include/stdlib.h:394,
                 from /usr/include/c++/10.2.0/cstdlib:75,
                 from /usr/include/c++/10.2.0/ext/string_conversions.h:41,
                 from /usr/include/c++/10.2.0/bits/basic_string.h:6535,
                 from /usr/include/c++/10.2.0/string:55,
                 from /tmp/2020H2/src/dns/protocol/Message.h:9,
                 from /tmp/2020H2/src/dns/protocol/QueryMessage.h:8,
                 from /tmp/2020H2/src/dns/protocol/QueryMessage.cpp:5:
/usr/include/bits/byteswap.h:34:24: note:   initializing argument 1 of ‘__uint16_t __bswap_16(__uint16_t)’
   34 | __bswap_16 (__uint16_t __bsx)
      |             ~~~~~~~~~~~^~~~~
make[3]: *** [CMakeFiles/lab2_dns_server.dir/build.make:108: CMakeFiles/lab2_dns_server.dir/src/dns/protocol/QueryMessage.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:124: CMakeFiles/lab2_dns_server.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:131: CMakeFiles/lab2_dns_server.dir/rule] Error 2
make: *** [Makefile:150: lab2_dns_server] Error 2

Что касается DHCP клиента - зачтено.

@rsvechnikov
Copy link
Author

Добавил явное преобразование к нужному типу, теоретически, должно собраться.
На всякий случай сделал pcap-файл с тестом сервера.

@wrbbz
Copy link
Contributor

wrbbz commented Jan 19, 2021

Адреса не соответствуют действительности:

Клиент:

drill spbpu.com @46.101.166.161
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 22632
;; flags: qr rd ra ; QUERY: 0, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;;
;; ANSWER SECTION:
spbpu.com.	0	IN	A	192.168.1.4

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 37 msec
;; SERVER: 46.101.166.161
;; WHEN: Tue Jan 19 19:47:01 2021
;; MSG SIZE  rcvd: 37

Сервер:

Query message received.
	ID: 22632, QR: 0, RD: 1, rcode: 0, QDCOUNT: 1.
	QUERY: spbpu.com., TYPE: 1, CLASS: 1
This query is supported. A predefined answer has been sent.

@rsvechnikov
Copy link
Author

Прошу прощения, видимо не правильно понял формулировку задания.

Серверу достаточно отвечать только запросы к одному доменному имени и заранее заложенными значениями, т.е. нет необходимости реализовывать полноценный процесс разрешения имени.

Я думал, что важен сам факт ответа (построения корректного сообщения в соответсвии с rfc), и что сам адрес не важен.
Имелось в виду, что нужно было или отдавать правильный адрес или не отвечать вообще?

@wrbbz
Copy link
Contributor

wrbbz commented Jan 19, 2021

Так. Моя ошибка. Да. Все верно, в таком случае. Сервер общается с клиентами. И отвечает валидно

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Вторая лабораторная Реальные UDP протоколы Зачтено
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants