196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin/*
296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * Check decoding of sockaddr structures
396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin *
496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
539bac055674d23770b9a724221b728e443196ea7Elliott Hughes * Copyright (c) 2016-2017 The strace developers.
696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * All rights reserved.
796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin *
896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * Redistribution and use in source and binary forms, with or without
996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * modification, are permitted provided that the following conditions
1096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * are met:
1196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * 1. Redistributions of source code must retain the above copyright
1296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin *    notice, this list of conditions and the following disclaimer.
1396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * 2. Redistributions in binary form must reproduce the above copyright
1496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin *    notice, this list of conditions and the following disclaimer in the
1596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin *    documentation and/or other materials provided with the distribution.
1696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * 3. The name of the author may not be used to endorse or promote products
1796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin *    derived from this software without specific prior written permission.
1896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin *
1996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin */
3096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
3196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include "tests.h"
3296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <stddef.h>
3396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <stdio.h>
3496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <string.h>
3596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <unistd.h>
3696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <sys/socket.h>
3796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <sys/un.h>
3896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <arpa/inet.h>
3996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <netinet/in.h>
40dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes#include "netlink.h"
4196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <linux/if_arp.h>
4296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <linux/if_ether.h>
4396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <linux/if_packet.h>
4496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#include <linux/ipx.h>
4596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
4696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin# include <bluetooth/bluetooth.h>
4796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin# include <bluetooth/hci.h>
4896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin# include <bluetooth/l2cap.h>
4996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin# include <bluetooth/rfcomm.h>
5096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin# include <bluetooth/sco.h>
5196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#endif
5296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
5396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#ifdef HAVE_IF_INDEXTONAME
5496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin/* <linux/if.h> used to conflict with <net/if.h> */
5596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinextern unsigned int if_nametoindex(const char *);
5696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#endif
5796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
5896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
5996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_un(void)
6096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
6139bac055674d23770b9a724221b728e443196ea7Elliott Hughes	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_un, un);
6296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_family = AF_UNIX;
6396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	memset(un->sun_path, '0', sizeof(un->sun_path));
6496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(*un);
6596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, (void *) un, len);
6696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
6796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n",
6896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) sizeof(un->sun_path), 0, len, ret);
6996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
7096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_path[1] = 0;
7196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
7296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%u\"}, %u)"
7396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n", 0, len, ret);
7496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
7596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_path[0] = 0;
7696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_path[2] = 1;
7796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
7896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"\\0\\001%.*u\"}"
7996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n",
8096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) sizeof(un->sun_path) - 3, 0, len, ret);
8196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
8296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un = ((void *) un) - 2;
8396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_family = AF_UNIX;
8496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	memset(un->sun_path, '0', sizeof(un->sun_path));
8596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*un) + 2;
8696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
8796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
8896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n",
8996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) sizeof(un->sun_path), 0, len, ret);
9096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
9196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_path[0] = 0;
9296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
9396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
9496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n",
9596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) sizeof(un->sun_path) - 1, 0, len, ret);
9696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
9796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un = ((void *) un) + 4;
9896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_family = AF_UNIX;
9996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*un) - 2;
10096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
10196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
10296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n",
10396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) sizeof(un->sun_path) - 2, 0, len, ret);
10496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
10596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_path[0] = 0;
10696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
10796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
10896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n",
10996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) sizeof(un->sun_path) - 3, 0, len, ret);
11096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
11196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*un);
11296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
11396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", un, len, ret);
11496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
11596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un = tail_alloc(sizeof(struct sockaddr_storage));
11696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_family = AF_UNIX;
11796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	memset(un->sun_path, '0', sizeof(un->sun_path));
11896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(struct sockaddr_storage) + 1;
11996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
12096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
12196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n",
12296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) sizeof(un->sun_path), 0, len, ret);
12396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
12496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	un->sun_path[0] = 0;
12596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) un, len);
12696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
12796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n",
12896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) sizeof(un->sun_path) - 1, 0, len, ret);
12996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
13096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
13196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
13296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_in(void)
13396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
13496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const unsigned short h_port = 12345;
13596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	static const char h_addr[] = "12.34.56.78";
13696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
13739bac055674d23770b9a724221b728e443196ea7Elliott Hughes	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in, in);
13896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_family = AF_INET;
13996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_port = htons(h_port);
14096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_addr.s_addr = inet_addr(h_addr);
14196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(*in);
14296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, (void *) in, len);
14396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
14496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
14596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       h_port, h_addr, len, ret);
14696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
14796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in = ((void *) in) - 4;
14896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_family = AF_INET;
14996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_port = htons(h_port);
15096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_addr.s_addr = inet_addr(h_addr);
15196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*in) + 4;
15296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) in, len);
15396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
15496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
15596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       h_port, h_addr, len, ret);
15696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
15796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in = ((void *) in) + 8;
15896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_family = AF_INET;
15996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_port = 0;
16096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in->sin_addr.s_addr = 0;
16196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*in) - 4;
16296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) in, len);
16396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_INET, sa_data=\"%s\"}, %u)"
16496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n",
16596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       "\\0\\0\\0\\0\\0\\0\\377\\377\\377\\377",
16696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       len, ret);
16796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
16896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*in);
16996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) in, len);
17096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in, len, ret);
17196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
17296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
17396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
17496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_in6_linklocal(struct sockaddr_in6 *const in6, const char *const h_addr)
17596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
17696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
17796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
17896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_scope_id = 0xfacefeed;
17996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(*in6);
18096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, (void *) in6, len);
18196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
18296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
18396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sin6_flowinfo=htonl(%u)"
18496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sin6_scope_id=%u}, %u)"
18596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n",
18696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ntohs(in6->sin6_port), h_addr,
18796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ntohl(in6->sin6_flowinfo), in6->sin6_scope_id, len, ret);
18896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
18996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#ifdef HAVE_IF_INDEXTONAME
19096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_scope_id = if_nametoindex("lo");
19196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	if (in6->sin6_scope_id) {
19296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		ret = connect(-1, (void *) in6, len);
19396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
19496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
19596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ", sin6_flowinfo=htonl(%u)"
19696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ", sin6_scope_id=if_nametoindex(\"lo\")}, %u)"
19796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       " = %d EBADF (%m)\n",
19896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ntohs(in6->sin6_port), h_addr,
19996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ntohl(in6->sin6_flowinfo), len, ret);
20096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	}
20196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#endif
20296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
20396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
20496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
20596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_in6(void)
20696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
20796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const unsigned short h_port = 12345;
20896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const unsigned int h_flowinfo = 1234567890;
20996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	static const char h_addr[] = "12:34:56:78:90:ab:cd:ef";
21096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
21139bac055674d23770b9a724221b728e443196ea7Elliott Hughes	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in6, in6);
21296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_family = AF_INET6;
21396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_port = htons(h_port);
21496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_flowinfo = htonl(h_flowinfo);
21596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
21696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_scope_id = 0xfacefeed;
21796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(*in6);
21896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, (void *) in6, len);
21996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
22096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
22196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sin6_flowinfo=htonl(%u), sin6_scope_id=%u}, %u)"
22296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n",
22396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       h_port, h_addr, h_flowinfo, in6->sin6_scope_id, len, ret);
22496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
22596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_in6_linklocal(in6, "fe80::");
22696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_in6_linklocal(in6, "ff42::");
22796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
22896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6 = ((void *) in6) - 4;
22996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_family = AF_INET6;
23096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_port = htons(h_port);
23196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_flowinfo = htonl(h_flowinfo);
23296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
23396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_scope_id = 0xfacefeed;
23496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*in6) + 4;
23596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) in6, len);
23696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
23796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
23896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sin6_flowinfo=htonl(%u), sin6_scope_id=%u}, %u)"
23996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n",
24096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       h_port, h_addr, h_flowinfo, in6->sin6_scope_id, len, ret);
24196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
24296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6 = ((void *) in6) + 4 + sizeof(in6->sin6_scope_id);
24396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_family = AF_INET6;
24496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_port = htons(h_port);
24596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_flowinfo = htonl(h_flowinfo);
24696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
24796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
24896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) in6, len);
24996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
25096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
25196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sin6_flowinfo=htonl(%u)}, %u)"
25296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n",
25396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       h_port, h_addr, h_flowinfo, len, ret);
25496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
25596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6 = ((void *) in6) + 4;
25696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_family = AF_INET6;
25796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_port = 0;
25896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	in6->sin6_flowinfo = 0;
25996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	memset(&in6->sin6_addr, '0', sizeof(in6->sin6_addr) - 4);
26096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*in6) - sizeof(in6->sin6_scope_id) - 4;
26196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) in6, len);
26296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_INET6"
26396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sa_data=\"\\0\\0\\0\\0\\0\\000%.*u\"}, %u)"
26496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n",
26596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) (len - offsetof(struct sockaddr_in6, sin6_addr)), 0,
26696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       len, ret);
26796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
26896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
26996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) in6, len);
27096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in6, len, ret);
27196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
27296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
27396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
27496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_ipx(void)
27596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
27696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const unsigned short h_port = 12345;
27796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const unsigned int h_network = 0xfacefeed;
27896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	struct sockaddr_ipx c_ipx = {
27996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sipx_family = AF_IPX,
28096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sipx_port = htons(h_port),
28196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sipx_network = htonl(h_network),
28296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sipx_node = "ABCDEF",
28396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sipx_type = -1
28496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	};
28596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	void *ipx = tail_memdup(&c_ipx, sizeof(c_ipx));
28696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(c_ipx);
28796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, ipx, len);
28896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_IPX, sipx_port=htons(%u)"
28996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sipx_network=htonl(%#x)"
29096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sipx_node=[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
29196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sipx_type=%#02x}, %u) = %d EBADF (%m)\n",
29296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       h_port, h_network,
29396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ipx.sipx_node[0], c_ipx.sipx_node[1],
29496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ipx.sipx_node[2], c_ipx.sipx_node[3],
29596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ipx.sipx_node[4], c_ipx.sipx_node[5],
29696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ipx.sipx_type, len, ret);
29796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
29896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
29996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
30096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_nl(void)
30196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
30239bac055674d23770b9a724221b728e443196ea7Elliott Hughes	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_nl, nl);
30396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	nl->nl_family = AF_NETLINK;
30496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	nl->nl_pid = 1234567890;
30596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	nl->nl_groups = 0xfacefeed;
30696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(*nl);
30796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, (void *) nl, len);
30896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
30996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
31096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       nl->nl_pid, nl->nl_groups, len, ret);
31196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
31296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	nl = ((void *) nl) - 4;
31396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	nl->nl_family = AF_NETLINK;
31496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	nl->nl_pid = 1234567890;
31596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	nl->nl_groups = 0xfacefeed;
31696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(*nl) + 4;
31796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) nl, len);
31896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
31996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
32096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       nl->nl_pid, nl->nl_groups, len, ret);
32196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
32296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
32396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
32496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_ll(void)
32596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
32696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	struct sockaddr_ll c_ll = {
32796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sll_family = AF_PACKET,
32896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sll_protocol = htons(ETH_P_ALL),
32996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sll_ifindex = 0xfacefeed,
33096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sll_hatype = ARPHRD_ETHER,
33196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sll_pkttype = PACKET_HOST,
33296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sll_halen = sizeof(c_ll.sll_addr),
33396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sll_addr = "abcdefgh"
33496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	};
33596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	void *ll = tail_memdup(&c_ll, sizeof(c_ll));
33696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(c_ll);
33796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, ll, len);
33896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_PACKET"
33996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_protocol=htons(ETH_P_ALL)"
34096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
34196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
34296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
34396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       "}, %u) = %d EBADF (%m)\n",
34496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_ifindex, c_ll.sll_halen,
34596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_addr[0], c_ll.sll_addr[1],
34696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_addr[2], c_ll.sll_addr[3],
34796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_addr[4], c_ll.sll_addr[5],
34896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_addr[6], c_ll.sll_addr[7],
34996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       len, ret);
35096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
35196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	((struct sockaddr_ll *) ll)->sll_halen++;
35296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, ll, len);
35396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_PACKET"
35496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_protocol=htons(ETH_P_ALL)"
35596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
35696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
35796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, ...]"
35896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       "}, %u) = %d EBADF (%m)\n",
35996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_ifindex, c_ll.sll_halen + 1,
36096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_addr[0], c_ll.sll_addr[1],
36196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_addr[2], c_ll.sll_addr[3],
36296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_addr[4], c_ll.sll_addr[5],
36396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_ll.sll_addr[6], c_ll.sll_addr[7],
36496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       len, ret);
36596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
36696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	((struct sockaddr_ll *) ll)->sll_halen = 0;
36796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, ll, len);
36896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_PACKET"
36996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_protocol=htons(ETH_P_ALL)"
37096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
37196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
37296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n", c_ll.sll_ifindex, len, ret);
37396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
37496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#ifdef HAVE_IF_INDEXTONAME
37596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const int id = if_nametoindex("lo");
37696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	if (id) {
37796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		((struct sockaddr_ll *) ll)->sll_ifindex = id;
37896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		ret = connect(-1, ll, len);
37996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		printf("connect(-1, {sa_family=AF_PACKET"
38096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ", sll_protocol=htons(ETH_P_ALL)"
38196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ", sll_ifindex=if_nametoindex(\"lo\")"
38296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ", sll_hatype=ARPHRD_ETHER"
38396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
38496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		       " = %d EBADF (%m)\n", len, ret);
38596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	}
38696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#endif
38796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
38896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
38996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
39096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
39196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_hci(void)
39296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
39396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const unsigned short h_port = 12345;
39439bac055674d23770b9a724221b728e443196ea7Elliott Hughes	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_hci, hci);
39596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	hci->hci_family = AF_BLUETOOTH;
39696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	hci->hci_dev = htobs(h_port);
39796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	hci->hci_channel = HCI_CHANNEL_RAW;
39896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(*hci);
39996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, (void *) hci, len);
40096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
40196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", hci_channel=HCI_CHANNEL_RAW}, %u) = %d EBADF (%m)\n",
40296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       h_port, len, ret);
40396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
40496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
40596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
40696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_sco(void)
40796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
40896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const struct sockaddr_sco c_sco = {
40996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sco_family = AF_BLUETOOTH,
41096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.sco_bdaddr.b = "abcdef"
41196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	};
41296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	void *sco = tail_memdup(&c_sco, sizeof(c_sco));
41396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(c_sco);
41496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, sco, len);
41596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_BLUETOOTH"
41696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", sco_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
41796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       "}, %u) = %d EBADF (%m)\n",
41896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_sco.sco_bdaddr.b[0], c_sco.sco_bdaddr.b[1],
41996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_sco.sco_bdaddr.b[2], c_sco.sco_bdaddr.b[3],
42096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_sco.sco_bdaddr.b[4], c_sco.sco_bdaddr.b[5],
42196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       len, ret);
42296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
42396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
42496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
42596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_rc(void)
42696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
42796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const struct sockaddr_rc c_rc = {
42896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.rc_family = AF_BLUETOOTH,
42996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.rc_bdaddr.b = "abcdef",
43096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.rc_channel = 42
43196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	};
43296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	void *rc = tail_memdup(&c_rc, sizeof(c_rc));
43396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(c_rc);
43496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, rc, len);
43596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_BLUETOOTH"
43696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", rc_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
43796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", rc_channel=%u}, %u) = %d EBADF (%m)\n",
43896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_rc.rc_bdaddr.b[0], c_rc.rc_bdaddr.b[1],
43996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_rc.rc_bdaddr.b[2], c_rc.rc_bdaddr.b[3],
44096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_rc.rc_bdaddr.b[4], c_rc.rc_bdaddr.b[5],
44196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_rc.rc_channel, len, ret);
44296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
44396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
44496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
44596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_l2(void)
44696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
44796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const unsigned short h_psm = 12345;
44896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const unsigned short h_cid = 13579;
44996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	const struct sockaddr_l2 c_l2 = {
45096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.l2_family = AF_BLUETOOTH,
45196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.l2_psm = htobs(h_psm),
45296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.l2_bdaddr.b = "abcdef",
45396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.l2_cid = htobs(h_cid),
45496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		.l2_bdaddr_type = 42
45596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	};
45696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	void *l2 = tail_memdup(&c_l2, sizeof(c_l2));
45796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(c_l2);
45896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, l2, len);
45996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_BLUETOOTH"
46096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", l2_psm=htobs(%hu)"
46196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
46296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", l2_cid=htobs(%hu), l2_bdaddr_type=%u}"
46396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n", h_psm,
46496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
46596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
46696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
46796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       h_cid, c_l2.l2_bdaddr_type, len, ret);
46896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
46996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#endif
47096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
47196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinstatic void
47296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levincheck_raw(void)
47396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
47496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	union {
47596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		struct sockaddr *sa;
47696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin		struct sockaddr_storage *st;
47796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	} u = { .st = tail_alloc(sizeof(*u.st)) };
47896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	memset(u.st, '0', sizeof(*u.st));
47996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	u.sa->sa_family = 0xff;
48096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	unsigned int len = sizeof(*u.st) + 8;
48196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	int ret = connect(-1, (void *) u.st, len);
48296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=%#x /* AF_??? */, sa_data=\"%.*u\"}"
48396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       ", %u) = %d EBADF (%m)\n", u.sa->sa_family,
48496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       (int) (sizeof(*u.st) - sizeof(u.sa->sa_family)), 0, len, ret);
48596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
48696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	u.sa->sa_family = 0;
48796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	len = sizeof(u.sa->sa_family) + 1;
48896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) u.st, len);
48996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_UNSPEC, sa_data=\"0\"}, %u)"
49096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n", len, ret);
49196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
49296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	u.sa->sa_family = AF_BLUETOOTH;
49396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	++len;
49496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	ret = connect(-1, (void *) u.st, len);
49596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"00\"}, %u)"
49696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	       " = %d EBADF (%m)\n", len, ret);
49796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
49896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
49996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinint
50096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levinmain(void)
50196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin{
50296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_un();
50396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_in();
50496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_in6();
50596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_ipx();
50696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_nl();
50796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_ll();
50896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
50996b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_hci();
51096b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_sco();
51196b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_rc();
51296b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_l2();
51396b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin#endif
51496b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	check_raw();
51596b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin
51696b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	puts("+++ exited with 0 +++");
51796b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin	return 0;
51896b04dc71d3ebaf46e4f03b85152234eb49c0a41Dmitry V. Levin}
519