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

It appears that this is possible using "ancillary data" and sendmsg/
recvmsg() API and the cmsg routines (
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) {

#define SRV_IP ""
/* 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)

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");

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");
// 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)

return 0;

Relevant Pages

  • per packet QoS (DSCP)
    ... in the IP header on a per packet ... manpages/intrepid/man3/cmsg.html) to modify the header fields. ... changes to the TOS field. ...
  • Re: [PATCH] 802.1p priority (fixed)
    ... What I mean is that if I can set the 802.1p header then why ... we won't actually touch the packet at all in the 801.1p case and will ... Setting TOS values could be done in place since we have the ... priorities and TOS values work rather differently in that TOS values fit ...
  • Re: modify packet in IM driver
    ... Although this is true of NDIS5 (that you may not modify a packet in the send path) this is no longer true of NDIS6. ... each component specifies it 'header' requirements and the sender is required to allocate NetBufferwith the required 'head-room' for packet header insertion. ...
  • Re: [PATCH] 802.1p priority (fixed)
    ... >> priorities and TOS values work rather differently in that TOS values fit ... >> modifications to the header and adding data between the header and the ... use a vlan tag on the packet. ... sense to modify the TOS bits directly in the firewall, ...
  • RE: Transfer a sending packet to upper TCP/IP protocol layer in IM
    ... If the IPv6 address can be resolved, ... IPv4 header will be larger than the MTU. ... After prepending IPv4 header and UDP header to the original IPv6 packet, ...