Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Jun 2012 12:34:43 +0200
From:      Michael Tuexen <Michael.Tuexen@lurchi.franken.de>
To:        Adrian Chadd <adrian@freebsd.org>
Cc:        "freebsd-net@freebsd.org mailing list" <freebsd-net@freebsd.org>
Subject:   Re: IP_RECVTOS
Message-ID:  <5399FCC6-BDC4-47DD-9948-ADD16264EE46@lurchi.franken.de>
In-Reply-To: <CAJ-Vmo=1o72QB%2B0tBcvO8A37xdzMCsS3JAFa5%2B6DM6%2BwqfQWPA@mail.gmail.com>
References:  <1D03F00E-2777-4B0B-8E1C-860EA115B6AF@lurchi.franken.de> <CAJ-Vmona0kHnOKXdmQDYksqGifmd5Fjgg-YniTcrHFZvZBv--Q@mail.gmail.com> <7731AEE8-D1BF-4297-8F75-454149D3E303@lurchi.franken.de> <CAJ-VmomrqRLkyTCFsgfcAsXC1V4KubsZ3AeY2K%2B6X7u-yjBOoQ@mail.gmail.com> <5A4A73CF-95FB-4B33-9652-2E4FD517CF5F@lurchi.franken.de> <CAJ-Vmo=1o72QB%2B0tBcvO8A37xdzMCsS3JAFa5%2B6DM6%2BwqfQWPA@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--Apple-Mail=_5120CC7C-A141-480E-8EE0-114EF60EEAB2
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=iso-8859-1

On Jun 6, 2012, at 10:15 AM, Adrian Chadd wrote:

> Well,
> 
> * Is it usable on a TCP socket?
No. The main application (I see) is to access the ECN bits. In the TCP case,
ECN is handled in the kernel, so there is no need to deal with them in
userland.
On the other hand, TCP is byte stream oriented, so I don't see any packet
boundaries. However, the TOS is per packet. Much like the TTL. This is also
limited to SOCK_DGRAM.
> * Is it usable on an outbound TCP socket (ie, where the receive end
> has set the ToS bits on the received ToS), regardless of what you've
> set for the sending ToS?
You can use the IP_TOS socket option for outgoing traffic.
> * Does the receive TOS change during the lifetime of a TCP connection?
The sender can change it.
> If so, can this fetch it?
No. The IP_RECVTOS is similar to the IPV6_RECVTCLASS socket option.
> * Example code? :)
Attached.

Best regards
Michael


--Apple-Mail=_5120CC7C-A141-480E-8EE0-114EF60EEAB2
Content-Disposition: attachment;
	filename=v4test.c
Content-Type: application/octet-stream; x-mac-type=534D4C34;
	x-mac-creator=534D554C; x-unix-mode=0644; name="v4test.c"
Content-Transfer-Encoding: 7bit

/*-
 * Copyright (c) 2012 Michael Tuexen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

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

#define DATA_BUFFER_SIZE (1<<10)
#define CONTROL_BUFFER_SIZE (1<<10)

int
main(void)
{
	int fd;
	ssize_t n;
	struct sockaddr_in addr;
	struct cmsghdr *cmsg;
	struct msghdr msg;
	struct iovec iov;
	const int on = 1;
	char dbuf[DATA_BUFFER_SIZE];
	char cbuf[CONTROL_BUFFER_SIZE];
	char nbuf[INET_ADDRSTRLEN];
	const char *name;

	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
	}

	if (setsockopt(fd, IPPROTO_IP, IP_RECVTOS, &on, sizeof(on)) < 0) {
		perror("IP_RECVTOS");
	}
	if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &on, sizeof(on)) < 0) {
		perror("IP_RECVTTL");
	}
	if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0) {
		perror("IP_RECVDSTADDR");
	}

	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
	addr.sin_len = sizeof(struct sockaddr_in);
#endif
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(9);
	if (bind(fd, (struct sockaddr*) &addr, sizeof(struct sockaddr_in)) < 0) {
		perror("bind");
	}

	for (;;) {
		iov.iov_base = dbuf;
		iov.iov_len = DATA_BUFFER_SIZE;
		memset(&msg, 0, sizeof(struct msghdr));
		msg.msg_name = &addr;
		msg.msg_namelen = sizeof(struct sockaddr_in6);
		msg.msg_iov = &iov;
		msg.msg_iovlen  = 1;
		msg.msg_control = cbuf;
		msg.msg_controllen = CONTROL_BUFFER_SIZE;
		n = recvmsg(fd, &msg, 0);
		if (n < 0) {
			perror("recvmsg");
			break;
		}
		name = inet_ntop(AF_INET, &addr.sin_addr, nbuf, INET_ADDRSTRLEN);
		printf("Received message of length %ld from %s.\n", n, name);
		for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
			printf("level = %d, type = %d, len = %d.\n",
			       cmsg->cmsg_level, cmsg->cmsg_type, cmsg->cmsg_len);
			if ((cmsg->cmsg_level == IPPROTO_IP) &&
			    (cmsg->cmsg_type == IP_RECVTOS) &&
			    (cmsg->cmsg_len == CMSG_LEN(sizeof(uint8_t)))) {
				uint8_t *tos;

				tos = (uint8_t *)CMSG_DATA(cmsg);
				printf("Received tos = %d\n", *tos);
			}
			if ((cmsg->cmsg_level == IPPROTO_IP) &&
			    (cmsg->cmsg_type == IP_RECVTTL) &&
			    (cmsg->cmsg_len == CMSG_LEN(sizeof(uint8_t)))) {
				uint8_t *ttl;

				ttl = (uint8_t *)CMSG_DATA(cmsg);
				printf("Received TTL = %d\n", *ttl);
			}
			if ((cmsg->cmsg_level == IPPROTO_IP) &&
			    (cmsg->cmsg_type == IP_RECVDSTADDR) &&
			    (cmsg->cmsg_len == CMSG_LEN(sizeof(struct in_addr)))) {
				struct in_addr *dst;

				dst = (struct in_addr *)CMSG_DATA(cmsg);
				name = inet_ntop(AF_INET, dst, nbuf, INET_ADDRSTRLEN);
				printf("Destination address %s.\n", name);
			}
		}
	}
	if (close(fd) < 0) {
		perror("close");
	}
	return (0);
}

--Apple-Mail=_5120CC7C-A141-480E-8EE0-114EF60EEAB2
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=iso-8859-1



> 
> 
> 
> Adrian
> 


--Apple-Mail=_5120CC7C-A141-480E-8EE0-114EF60EEAB2--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5399FCC6-BDC4-47DD-9948-ADD16264EE46>