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:
signature.asc
Description: PGP signature