per packet QoS (DSCP)



My application calls for sending different UDP packets with different
QoS priority, using DSCP. To do this I wanted to modify the ToS byte
in the IP header (bits 8-15 of the IPv4 header) on a per packet
basis.

It appears that this is possible using "ancillary data" and sendmsg/
recvmsg() API and the cmsg routines (http://manpages.ubuntu.com/
manpages/intrepid/man3/cmsg.html) to modify the header fields.

I cannot get this to work. Can anyone provide an example that does?
I am using ubuntu 8.10 and I have tried several things. Here is a
current little test client. Looking at wireshark I do not see any
changes to the TOS field (stays zero no matter what). I even tried
changing things like TTL field without any luck either. Any ideas?

#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string>
#include <string.h>


#define BUFLEN 512
#define NPACK 10
#define PORT 9930

void diep(const char *s) {
perror(s);
exit(1);
}


#define SRV_IP "127.0.0.1"
/* diep(), #includes and #defines like in the server */

int main(void) {
sockaddr_in si_other = {0};
msghdr msg = {0};
int s, i;
char buf[BUFLEN];

if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
diep("socket");

si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SRV_IP, &si_other.sin_addr) == 0) {
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}

for (i = 0; i < NPACK; i++) {
printf("Sending packet %d\n", i);
sprintf(buf, "This is packet %d\n", i);
//if (sendto(s, buf, BUFLEN, 0, (sockaddr *)&si_other, slen) == -1)
// diep("sendto()");

// sets the address to send to
msg.msg_name = &si_other;
msg.msg_namelen = sizeof(si_other);

iovec iov[1];
msg.msg_iov = iov ;
msg.msg_iovlen = 1;
int test = 0xEFBEADDE;

iov[0].iov_base = &test;
iov[0].iov_len = sizeof test;


// sets the control ancillary data
cmsghdr * cmsg;
//int tos = 0xBEBAFECA; // set to low delay
int tos = 6; // set to low delay

char buf[CMSG_SPACE(sizeof(tos))];
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);

cmsg = CMSG_FIRSTHDR(&msg); // set to first header
if(cmsg == NULL)
{
fprintf(stderr, "CMSG_FIRSTHDR FAILED");
exit(1);
}
// first header is the TOS header
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_TOS;
cmsg->cmsg_len = CMSG_LEN(sizeof(tos));
*((int *) CMSG_DATA(cmsg)) = tos;
//void * data = CMSG_DATA(cmsg); // set the data
//memcpy(data, (void*) &tos, sizeof(tos));
msg.msg_controllen = cmsg->cmsg_len;

if (sendmsg(s, &msg, 0) < 0)
diep("sendmsg()");
}

close(s);
return 0;
}
.