LINUX.ORG.RU

RAW socket


0

0

есть код, он через RAW socket должен отправить по указанному DESTINATION_IP заголовок IP, при этом адрес отправителя в заголовке IP заменяется на SOURCE_IP
не работает, tcpdump пишет [21:49:54.033987 IP5 bad-hlen 16]
в чем может быть дело?


static char ip[20];

int main() {
int option = 1;
uint16_t word;
uint32_t dword;
struct sockaddr_in addr = {0};
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock < 0)
return 1;
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &option, sizeof(option)) < 0)
return 2;
#define IP_HEADER_SIZE 5
word = 4 | (IP_HEADER_SIZE << 4) | (IPTOS_THROUGHPUT << 8);
memcpy(ip, &word, 2);
#define IP_SIZE 20
word = htons(IP_SIZE);
memcpy(ip + 2, &word, 2);
dword = 0;
memcpy(ip + 4, &dword, 4);
word = 0xFF | (IPPROTO_IP << 8);
memcpy(ip + 8, &word, 2);
word = 0;
memcpy(ip + 10, &word, 2);
#define SOURCE_IP "87.252.226.1"
if (inet_aton(SOURCE_IP, &addr.sin_addr) < 0)
return 5;
memcpy(ip + 12, &addr.sin_addr.s_addr, 4);
#define DESTINATION_IP "216.239.59.104"
if (inet_aton(DESTINATION_IP, &addr.sin_addr) < 0)
return 3;
if (sendto(sock, ip, 20, 0, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror(NULL);
return 6;
}
close(sock);
return 0;
}


User-Agent: lynx + jed (x86_64-pc-asus-linux-glibc-perl-debian)

> есть код,

больше кода, красивого и разного!

> он через RAW socket должен

код должен как земля колхозу, программист при этом должен сидеть на
печке и подгонять его?

> отправить по указанному DESTINATION_IP заголовок IP, при этом адрес
> отправителя в заголовке IP заменяется на SOURCE_IP не работает,

описание зОдачи плавно превращается, превращается плавно, превращается
в решение; извите у нас техническая заминка.

> tcpdump пишет [21:49:54.033987 IP5 bad-hlen 16] в чем может быть дело?

для начала я бы порекомендовал выкинуть код и сформулировать задачу.

А `tcpdump` использовать с ключём "-v", тестируя идеи и ртфмные знания в
нескольких python'овских строчках.

--
-o--=O`C
 #oo'L O
<___=E M

olecom
()
Ответ на: комментарий от olecom

examples (Re: RAW socket)

User-Agent: lynx + jed (x86_64-pc-asus-linux-glibc-perl-debian)

] capture(shell): `tcpdump -w /tmp/dump -e -n -vvv -xx -XX -i eth0`
] reading(shell): `tcpdump -r /tmp/dump -e -n -vvv -xx -XX | pager`

] input(python):

== IP RAW socket under 254 (SOMETHING/IP) PROTO ==

>>> s=socket(AF_INET,SOCK_RAW,254)
>>> s.sendto("OLECOM", ("1.1.1.1",0))
6
>>> s.sendto("OLECOZ", ("1.1.1.1",0))
6
=
TIME, 00:17:31:8e:4f:3a > 00:01:30:fb:4e:30, ethertype IPv4 (0x0800),
length 40: (tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: unknown (254),
length: 26) 158.194.64.22 > 1.1.1.1:  ip-proto-254 6
        0x0000:  0001 30fb 4e30 0017 318e 4f3a 0800 4500  ..0.N0..1.O:..E.
        0x0010:  001a 0000 4000 40fe 590c 9ec2 4016 0101  ....@.@.Y...@...
        0x0020:  0101 4f4c 4543 4f4d                      ..OLECOM

TIME, 00:17:31:8e:4f:3a > 00:01:30:fb:4e:30, ethertype IPv4 (0x0800),
length 40: (tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: unknown (254),
length: 26) 158.194.64.22 > 1.1.1.1:  ip-proto-254 6
        0x0000:  0001 30fb 4e30 0017 318e 4f3a 0800 4500  ..0.N0..1.O:..E.
        0x0010:  001a 0000 4000 40fe 590c 9ec2 4016 0101  ....@.@.Y...@...
        0x0020:  0101 4f4c 4543 4f5a                      ..OLECOZ
____

== IP RAW socket under 1 (ICMP/IP) PROTO ==

>>> s=socket(AF_INET,SOCK_RAW,1)
>>> s.sendto("OLECOM-ICM", ("1.1.1.1",0))
10
>>> s.sendto("OLECOM-ICMP", ("1.1.1.1",0))
11
=
TIME, 00:17:31:8e:4f:3a > 00:01:30:fb:4e:30, ethertype IPv4 (0x0800),
length 44: (tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: ICMP (1),
length: 30) 158.194.64.22 > 1.1.1.1: ICMP type-#79,
length 10 (wrong icmp cksum 4543 (->f0cf)!)
        [|ip]
        0x0000:  0001 30fb 4e30 0017 318e 4f3a 0800 4500  ..0.N0..1.O:..E.
        0x0010:  001e 0000 4000 4001 5a05 9ec2 4016 0101  ....@.@.Z...@...
        0x0020:  0101 4f4c 4543 4f4d 2d49 434d            ..OLECOM-ICM

TIME, 00:17:31:8e:4f:3a > 00:01:30:fb:4e:30, ethertype IPv4 (0x0800),
length 45: (tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: ICMP (1),
length: 31) 158.194.64.22 > 1.1.1.1: ICMP type-#79,
length 11 (wrong icmp cksum 4543 (->a0cf)!)
        [|ip]
        0x0000:  0001 30fb 4e30 0017 318e 4f3a 0800 4500  ..0.N0..1.O:..E.
        0x0010:  001f 0000 4000 4001 5a04 9ec2 4016 0101  ....@.@.Z...@...
        0x0020:  0101 4f4c 4543 4f4d 2d49 434d 50         ..OLECOM-ICMP
____

== IP RAW socket under 255 (RAW/IP) PROTO ==

>>> s=socket(AF_INET,SOCK_RAW,255)
>>> s.sendto("OLECOM-255", ("1.1.1.1",0))
10
>>> s.sendto("", ("1.1.1.1",0))
0
=
TIME, 00:17:31:8e:4f:3a > 00:01:30:fb:4e:30, ethertype IPv4 (0x0800),
length 24: [|ip]
        0x0000:  0001 30fb 4e30 0017 318e 4f3a 0800 4f4c ..0.N0..1.O:..OL
        0x0010:  4543 4f4d 2d32 3535                     ECOM-255

TIME, 00:17:31:8e:4f:3a > 00:01:30:fb:4e:30, ethertype IPv4 (0x0800),
length 14: [|ip]
        0x0000:  0001 30fb 4e30 0017 318e 4f3a 0800      ..0.N0..1.O:..
____

== ETHERNET RAW socket (under in fact NOTHING) ==

>>> sr=socket(AF_PACKET,SOCK_RAW,0)
>>> sr.sendto("123456789000zzolecom", ("eth0",0))
20
=
TIME, 37:38:39:30:30:30 > 31:32:33:34:35:36, ethertype Unknown (0x7a7a),
length 20:
        0x0000:  3132 3334 3536 3738 3930 3030 7a7a 6f6c  123456789000zzol
        0x0010:  6563 6f6d                                ecom
____
>>> sr.sendto("", ("eth0",0))
0
>>> sr.sendto("", ("eth0",0))
0
=
TIME, [|ether]
TIME, [|ether]
____

olecom
()
Ответ на: комментарий от olecom

> код должен как земля колхозу, программист при этом должен сидеть на
> печке и подгонять его?
совсем не в тему
> для начала я бы порекомендовал выкинуть код и сформулировать задачу.
вручную сформировать пакет IP, состоящий только из заголовка, и отправить его по указанному адресу, заменив адрес отправителя на указанный

rei3er
() автор топика

Советую вам использовать структуру для формирования ip-заголовка пакета. Вроде раньше она определялась в файле <netinet/ip.h>, если её там нет, то скопировать её описание из исходников ядра. Текст программы станет более наглядный, а то многочисленные memcpy(ip + 10,... выглядят неудобоваримо...

Далее, вы забыли скопировать DESTINATION_IP... А строчку, формирующую первые два байта пакета нужно писать так (во всяком случае на i386)

word = IP_HEADER_SIZE | (4 << 4) | (IPTOS_THROUGHPUT << 8);

mky ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.