Forum » Programiranje » [c]recvmsg
[c]recvmsg
slovencl ::
Berem dokumentacijo in gledam primere uporabe recvmsg(), ampak enostavno ne štekam, kako sploh prideš do vsebine ethernet paketa?
Za osnovo sem vzel enega od teh primerov. Recvmsg mi sicer vrne število bytov, ki so bili sprejeti. Imam pa raw socket sockfd = socket(PF_PACKET, SOCK_RAW, htons(0x1234)).
Kakšna ideja?
Za osnovo sem vzel enega od teh primerov. Recvmsg mi sicer vrne število bytov, ki so bili sprejeti. Imam pa raw socket sockfd = socket(PF_PACKET, SOCK_RAW, htons(0x1234)).
Kakšna ideja?
- spremenil: slovencl ()
Mavrik ::
Saj mu podaš buffer v kerega bo dal podatke kot parameter a ne?
The truth is rarely pure and never simple.
slovencl ::
tale koda:
mi vrne:
dejansko pa je v paketku:
int read_size = 200; //10 * 1024; const int CMSG_SIZE = 1024; unsigned char cmsg_buf[CMSG_SIZE]; struct iovec recv_iov; struct cmsghdr *cmsg; bool failed = false; struct msghdr hdr; int flags = 0; int r; memset(&hdr, 0, sizeof(hdr)); hdr.msg_iov = &recv_iov; hdr.msg_iovlen = 1; recv_iov.iov_base = malloc(read_size); recv_iov.iov_len = read_size; hdr.msg_control = cmsg_buf; hdr.msg_controllen = sizeof(cmsg_buf); r = recvmsg(rcv, &hdr, flags); if (r < 0) { perror("Failed to recvmsg: "); } if (r != 0) { fprintf(stderr, "rx payload: %d B.\n", r); } if (hdr.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) { perror("Message was truncated.\n"); } for(int i=0; i<r+100; i++) { fprintf(stderr, "%02x:", cmsg_buf[i]); } fprintf(stderr, "\n"); // Get the address of the first 'cmsghdr' in the received ancillary data cmsg = CMSG_FIRSTHDR(&hdr); // Check the validity of the 'cmsghdr' if (cmsg == NULL) { fprintf(stderr, "cmsg null \n"); }
mi vrne:
rx payload: 64 B. c8:94:4e:37:c3:7f:00:00:28:eb:62:35:fc:7f:00:00:e0:4c:4c:37:c3:7f:00:00:70:91:4e:37:c3:7f:00:00:00:00:00:00:00:00:00:00:ef:b1:2c:37:c3:7f:00:00:08:00:00:00:00:00:00:00:e0:4c:4c:37:c3:7f:00:00:01:00:00:00:00:00:00:00:00:6a:17:0d:e8:52:bf:c1:70:ea:62:35:fc:7f:00:00:70:ea:62:35:fc:7f:00:00:2f:00:00:00:00:00:00:00:0d:6a:b2:35:c3:7f:00:00:e8:eb:62:35:fc:7f:00:00:80:87:d2:35:c3:7f:00:00:94:a9:4b:37:c3:7f:00:00:10:89:db:35:c3:7f:00:00:01:80:ad:fb:00:00:00:00:94:a9:4b:37:c3:7f:00:00:94:a9:4b:37: cmsg null
dejansko pa je v paketku:
0010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................ 0020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f !"#$%&'()*+,-./ 0030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?
AndrejO ::
cmsg_buf[i])
To si opazil, da si izpisuješ dodatne podatke iz protokola in ne vsebino paketa? Vsebino paketa boš našel v recv_iov.iov_base.
28.3 čl. Pravil: Argumentirano pritožbo mora uporabnik poslati v oddelek
Slo-Tech, tema Pritožbe. Pritožb poslanih po zasebnih sporočilih,
elektronski pošti ali odprte v obliki tem v drugih oddelkih se ne upošteva.
Slo-Tech, tema Pritožbe. Pritožb poslanih po zasebnih sporočilih,
elektronski pošti ali odprte v obliki tem v drugih oddelkih se ne upošteva.
slovencl ::
Sem poskusil tudi to, da izpiše iov, pa še vedno dobivam neke čudne podatke:
Mi vrne:
paket ki ga sprejme je še vedno isti (posneto z wireshark):
int read_size = 200; //10 * 1024; const int CMSG_SIZE = 1024; unsigned char cmsg_buf[CMSG_SIZE]; struct iovec recv_iov; struct cmsghdr *cmsg; bool failed = false; struct msghdr hdr; int flags = 0; int r; unsigned char imsg_buf[100]; recv_iov.iov_base = imsg_buf; recv_iov.iov_len = 100; memset(&hdr, 0, sizeof(hdr)); hdr.msg_iov = &recv_iov; hdr.msg_iovlen = 1; recv_iov.iov_base = malloc(read_size); recv_iov.iov_len = read_size; hdr.msg_control = cmsg_buf; hdr.msg_controllen = sizeof(cmsg_buf); r = recvmsg(rcv, &hdr, flags); if (r < 0) { perror("Failed to recvmsg: "); } if (r != 0) { fprintf(stderr, "rx payload: %d B.\n", r); } if (hdr.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) { perror("Message was truncated.\n"); } fprintf(stderr, "I MSG "); for(int i=0; i<r; i++) { fprintf(stderr, "%02x:", imsg_buf[i]); } fprintf(stderr, "\n");
Mi vrne:
I MSG 00:00:00:00:00:12:7b:c2:ce:ba:01:16:70:5e:58:59:fd:7f:00:00:d3:94:dc:fd:a8:7f:00:00:d0:5e:58:59:fd:7f:00:00:40:b4:fc:fd:a8:7f:00:00:00:01:00:00:00:00:00:00:50:b5:fc:fd:a8:7f:00:00:14:00:00:00:
paket ki ga sprejme je še vedno isti (posneto z wireshark):
0010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................ 0020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f !"#$%&'()*+,-./ 0030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?
Senitel ::
imsg_buf je garbage, sej nič ne daš notri. Stuff je dejansko v recv_iov.iov_base, ki ga alociraš tukaj recv_iov.iov_base = malloc(read_size);.
Randomness ::
recv_iov.iov_base = imsg_buf; recv_iov.iov_len = 100; // tukaj si povoziš recv_iov recv_iov.iov_base = malloc(read_size); recv_iov.iov_len = read_size;
slovencl ::
Super, najlepša hvala, tole sem pa spregledal... tale del zgoraj mi zdej dela.
Imam pa še vedno problem, da mi cmsg vrača NULL. Koda je enako povzeta od enega od primerov. Mogoče kdo ve zakaj?
Mi vrača
Imam pa še vedno problem, da mi cmsg vrača NULL. Koda je enako povzeta od enega od primerov. Mogoče kdo ve zakaj?
struct cmsghdr *cmsg; union { struct cmsghdr hdr; unsigned char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; struct iovec recv_iov; struct msghdr hdr; int r; unsigned char imsg_bufmemset(&hdr, 0, sizeof(hdr)); hdr.msg_iov = &recv_iov; hdr.msg_iovlen = 1; recv_iov.iov_base = imsg_buf; //recv_iov.iov_base = malloc(read_size); recv_iov.iov_len = 2048; //recv_iov.iov_len = read_size; hdr.msg_control = &cmsgbuf.buf; hdr.msg_controllen = sizeof(cmsgbuf.buf); r = recvmsg(rcv, &hdr, 0); if (r < 0) { perror("Failed to recvmsg: "); } if (r != 0) { fprintf(stderr, "rx payload: %d B.\n", r); } if (hdr.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) { perror("Message was truncated.\n"); } // Get the address of the first 'cmsghdr' in the received ancillary data cmsg = CMSG_FIRSTHDR(&hdr); // Check the validity of the 'cmsghdr' if (cmsg == NULL) { fprintf(stderr, "cmsg null \n"); }
Mi vrača
cmsg null
Zgodovina sprememb…
- spremenil: slovencl ()
slovencl ::
Uporablja se za to, da dobiš podatke o paketu, ki niso sama vsebina paketa, mar ne?
Jaz bi rad prebral timestamp paketa. Sem tudi vključil to funkcijo s setsockopt.
Ampak verjetno "ancillary data" tudi če nič ne vključiš preko setsockopt nikoli niso NULL?
Glede na opis CMSG_FIRSTHDR(): It returns NULL if there isn't enough space for a cmsghdr in the buffer. Koliko pa potrebuje?
Jaz bi rad prebral timestamp paketa. Sem tudi vključil to funkcijo s setsockopt.
Ampak verjetno "ancillary data" tudi če nič ne vključiš preko setsockopt nikoli niso NULL?
Glede na opis CMSG_FIRSTHDR(): It returns NULL if there isn't enough space for a cmsghdr in the buffer. Koliko pa potrebuje?
Zgodovina sprememb…
- spremenil: slovencl ()
Randomness ::
Ni nujno, da vsak paket vsebuje dodatne podatke. Če bi bil buffer premajhen, bi dobil izpis "Message was truncated.", saj preverjaš msg_flags. Ne vem točno, kaj čaraš, ampak koda na tem linku izpisuje timestampe paketov.
Svetujem ti, da si pogledaš libpcap, ki ga uporablja tudi Wireshark.
Svetujem ti, da si pogledaš libpcap, ki ga uporablja tudi Wireshark.
slovencl ::
Aha, najlepša hvala ti za tole... tole tudi meni deluje. Če pa izpustim setsockopt, pa mi cmsg ravno tako vrne NULL.
Očitno imam narobe nastavljen setsockopt, rad bi namreč imel harverski timestamp. Takole imam nastavljeno:
Ali imaš idejo v čem bi lahko bil problem s temi nastavitvami? Če prav razumem wireshark podpira samo softverski timestamp.
Hardver mi timestamping podpira:
Time stamping parameters for enp3s0:
Capabilities:
hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE)
software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)
hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE)
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off (HWTSTAMP_TX_OFF)
on (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
none (HWTSTAMP_FILTER_NONE)
all (HWTSTAMP_FILTER_ALL)
Očitno imam narobe nastavljen setsockopt, rad bi namreč imel harverski timestamp. Takole imam nastavljeno:
int opt= 0; opt |= SOF_TIMESTAMPING_RX_HARDWARE; opt |= SOF_TIMESTAMPING_RAW_HARDWARE; if (setsockopt(sockfd, SOL_SOCKET, SO_TIMESTAMPING, (char *)&opt, sizeof(opt))) { perror("setsockopt timestamping"); close(sockfd); exit(EXIT_FAILURE); }
Ali imaš idejo v čem bi lahko bil problem s temi nastavitvami? Če prav razumem wireshark podpira samo softverski timestamp.
Hardver mi timestamping podpira:
Time stamping parameters for enp3s0:
Capabilities:
hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE)
software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)
hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE)
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off (HWTSTAMP_TX_OFF)
on (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
none (HWTSTAMP_FILTER_NONE)
all (HWTSTAMP_FILTER_ALL)
Zgodovina sprememb…
- spremenil: slovencl ()
Randomness ::
Na interfaceu moraš vklopiti HW timestampanje. Glej ioctl in SIOCSHWTSTAMP.
Ne, Wireshark podpira to, kar podpira libpcap. Poleg nastavljanja HW filtrov tudi HW timestampe.
Če prav razumem wireshark podpira samo softverski timestamp.
Ne, Wireshark podpira to, kar podpira libpcap. Poleg nastavljanja HW filtrov tudi HW timestampe.
Zgodovina sprememb…
- spremenilo: Randomness ()
slovencl ::
@Randomness: Carsko, sem preizkusil in na prvi pogled zgleda da deluje! :) Res najlepša ti hvala za tele nasvete!
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [c] ne sprejme UDP paketaOddelek: Programiranje | 984 (572) | slovencl |
» | [C++] problem z binarnimi datotekamiOddelek: Programiranje | 944 (809) | mallard |
» | SMTP v c -juOddelek: Programiranje | 2119 (1260) | BigWhale |
» | [ C ] floating point not loaded !!?Oddelek: Programiranje | 1558 (1491) | Fizikalko |
» | Delo z omrezjem v linuxuOddelek: Programiranje | 1296 (1142) | CCfly |