From: Alejandro Colomar <alx@kernel.org>
To: Oliver Crumrine <ozlinuxc@gmail.com>
Cc: linux-man@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] ip.7: Add not supported by SOCK_STREAM to socket options
Date: Wed, 6 Mar 2024 11:50:54 +0100 [thread overview]
Message-ID: <ZehKlHJvUgu7mgQH@debian> (raw)
In-Reply-To: <7ubz52rfdl2i76sotvd3s4thv6jvbfao6zct3sywqus2owlvkx@wpbeqqdvipo4>
[-- Attachment #1: Type: text/plain, Size: 6383 bytes --]
Hi Oliver,
On Tue, Mar 05, 2024 at 02:31:48PM -0500, Oliver Crumrine wrote:
> #include<stdio.h> //printf
> #include<string.h> //memset
> #include<stdlib.h> //exit(0);
> #include<arpa/inet.h>
> #include<sys/socket.h>
> #include<unistd.h>
>
> #define BUFLEN 1500 //Max length of buffer
You could use BUFSIZ, which is in <stdio.h>. It also removes magic
numbers like 1500 (why not 1000?).
> #define PORT 8888 //The port on which to listen for incoming data
>
>
> //Hi Alex,
> //These are the two lines that allow you to switch between the three socket options outlined in my patch
> //The socket options tell the kernel to add a control message (cmsg), allowing the program
> //to recieve the data it is requesting. The three options are: IP_RECVTOS for the type of service byte,
> //IP_RECVORIGDSTADDR for the orignial dst address, and IP_PKTINFO for some random packet info.
> #define SOCKOPT IP_RECVORIGDSTADDR
> //This field is synonymous with the above one. Valid options are: IP_TOS, IP_ORIGDSTADDR, and IP_PKTINFO
> #define RECIVEOPTION IP_ORIGDSTADDR
>
> void die(char *s)
> {
> perror(s);
> exit(1);
> }
>
> int main(void)
> {
> struct sockaddr_in si_me, si_other;
>
> int s, i, slen = sizeof(si_other) , recv_len;
Unused variables 'i' and 'slen' (in both programs).
> char buf[BUFLEN];
Unused variable 'buf' (in both programs).
>
> if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
This is more readable (and safer) in two lines:
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1)
> {
> die("socket");
You could use
err(1, "socket");
which is in <err.h>.
> }
>
> memset((char *) &si_me, 0, sizeof(si_me));
>
> si_me.sin_family = AF_INET;
> si_me.sin_port = htons(PORT);
> si_me.sin_addr.s_addr = htonl(INADDR_ANY);
>
> if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
The use of spaces is quite inconsistent.
> {
> die("bind");
> }
> int yes = 1;
> if(setsockopt(s, IPPROTO_IP, SOCKOPT, &yes, sizeof(yes)) != 0){
!= 0 is inconsistent with other == -1 checks.
Also placement of braces.
Have a lovely day!
Alex
> die("setsockopt");
> }
> while(1)
> {
> struct msghdr mhdr;
> struct iovec iov[1];
> struct cmsghdr *cmhdr;
> char control[1000];
> char databuf[1500];
> unsigned char tos = 0;
>
> mhdr.msg_name = &si_me;
> mhdr.msg_namelen = sizeof(si_me);
> mhdr.msg_iov = iov;
> mhdr.msg_iovlen = 1;
> mhdr.msg_control = &control;
> mhdr.msg_controllen = sizeof(control);
> iov[0].iov_base = databuf;
> iov[0].iov_len = sizeof(databuf);
> memset(databuf, 0, sizeof(databuf));
> fflush(stdout);
>
> //this is blocking
> if ((recv_len = recvmsg(s, &mhdr, 0)) == -1)
> {
> die("recvfrom()");
> }
> cmhdr = CMSG_FIRSTHDR(&mhdr);
> while (cmhdr) {
> printf("cmsg recieved\n");
> if (cmhdr->cmsg_level == IPPROTO_IP && cmhdr->cmsg_type == RECIVEOPTION) {
> //read the byte recieved
> tos = ((unsigned char *)CMSG_DATA(cmhdr))[0];
> }
> cmhdr = CMSG_NXTHDR(&mhdr, cmhdr);
> }
> //print out the data recieved as a hex byte
> printf("data read: %sbyte = %02X\n", databuf, tos);
>
> }
>
> close(s);
> return 0;
> }
> #include<stdio.h> //printf
> #include<string.h> //memset
> #include<stdlib.h> //exit(0);
> #include<arpa/inet.h>
> #include<sys/socket.h>
> #include<unistd.h>
>
> #define BUFLEN 1500 //Max length of buffer
> #define PORT 8888 //The port on which to listen for incoming data
>
> //Hi Alex,
> //These are the two lines that allow you to switch between the three socket options outlined in my patch
> //The socket options tell the kernel to add a control message (cmsg), allowing the program
> //to recieve the data it is requesting. The three options are: IP_RECVTOS for the type of service byte,
> //IP_RECVORIGDSTADDR for the orignial dst address, and IP_PKTINFO for some random packet info.
> #define SOCKOPT IP_RECVORIGDSTADDR
> //This field is synonymous with the above one. Valid options are: IP_TOS, IP_ORIGDSTADDR, and IP_PKTINFO
> #define RECIVEOPTION IP_ORIGDSTADDR
>
> void die(char *s)
> {
> perror(s);
> exit(1);
> }
>
> int main(void)
> {
> struct sockaddr_in si_me, si_other;
>
> int s, i, slen = sizeof(si_other) , recv_len;
> char buf[BUFLEN];
>
> if ((s=socket(AF_INET, SOCK_STREAM, 0)) == -1)
> {
> die("socket");
> }
>
> memset((char *) &si_me, 0, sizeof(si_me));
>
> si_me.sin_family = AF_INET;
> si_me.sin_port = htons(PORT);
> si_me.sin_addr.s_addr = htonl(INADDR_ANY);
>
> if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
> {
> die("bind");
> }
> listen(s, 10);
> while(1)
> {
> int connectedfd = accept(s, (struct sockaddr*)NULL, NULL);
> int yes = 1;
> if(setsockopt(connectedfd, IPPROTO_IP, SOCKOPT, &yes, sizeof(yes)) != 0){
> die("setsockopt");
> }
>
>
>
> struct msghdr mhdr;
> struct iovec iov[1];
> struct cmsghdr *cmhdr;
> char control[1000];
> char databuf[1500];
> unsigned char tos = 0;
>
> mhdr.msg_name = &si_me;
> mhdr.msg_namelen = sizeof(si_me);
> mhdr.msg_iov = iov;
> mhdr.msg_iovlen = 1;
> mhdr.msg_control = &control;
> mhdr.msg_controllen = sizeof(control);
> iov[0].iov_base = databuf;
> iov[0].iov_len = sizeof(databuf);
> memset(databuf, 0, sizeof(databuf));
> fflush(stdout);
>
> //this is blocking
> if ((recv_len = recvmsg(connectedfd, &mhdr, 0)) == -1)
> {
> die("recvfrom()");
> }
> cmhdr = CMSG_FIRSTHDR(&mhdr);
> while (cmhdr) {
> printf("cmsg recieved \n");
> if (cmhdr->cmsg_level == IPPROTO_IP && cmhdr->cmsg_type == RECIVEOPTION) {
> //read the byte recieved
> tos = ((unsigned char *)CMSG_DATA(cmhdr))[0];
> }
> cmhdr = CMSG_NXTHDR(&mhdr, cmhdr);
> }
> //print out the data recieved as a hex byte
> printf("data read: %sbyte = %02X\n", databuf, tos);
> close(connectedfd);
> }
>
> close(s);
> return 0;
> }
--
<https://www.alejandro-colomar.es/>
Looking for a remote C programming job at the moment.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2024-03-06 10:51 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-02 18:19 [PATCH] ip.7: Add not supported by SOCK_STREAM to socket options Oliver Crumrine
2024-03-04 16:15 ` Alejandro Colomar
2024-03-05 19:31 ` Oliver Crumrine
2024-03-06 10:50 ` Alejandro Colomar [this message]
2024-03-06 10:58 ` Alejandro Colomar
2024-03-06 13:02 ` Oliver Crumrine
2024-03-06 13:12 ` Alejandro Colomar
[not found] ` <CAK1VsR3MsyphK+=rA7XcEigiSd6J_-QsVW+8hH1fU9xmRY3nGQ@mail.gmail.com>
2024-03-13 18:27 ` Oliver Crumrine
2024-03-13 22:35 ` Alejandro Colomar
2024-03-16 19:33 ` Alejandro Colomar
2024-03-16 18:41 ` Oliver Crumrine
2024-03-17 2:02 ` Alejandro Colomar
2024-03-17 9:02 ` Oliver Crumrine
2024-03-17 13:55 ` Alejandro Colomar
[not found] ` <hxkixsi6uymkjmt4ughda2xmh6guzcaccrjbvsuasndyuvq5rz@36oqfaepfiql>
2024-03-17 15:17 ` Alejandro Colomar
2024-03-17 11:31 ` Peter Seiderer
2024-03-17 18:27 ` Alejandro Colomar
-- strict thread matches above, loose matches on Subject: below --
2024-03-17 13:55 Oliver Crumrine
2024-03-17 18:28 ` Alejandro Colomar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZehKlHJvUgu7mgQH@debian \
--to=alx@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-man@vger.kernel.org \
--cc=ozlinuxc@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox