(root)/
strace-6.5/
tests-mx32/
net-sockaddr.c
       1  /*
       2   * Check decoding of sockaddr structures
       3   *
       4   * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2022 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include "pidns.h"
      13  #include <stddef.h>
      14  #include <stdio.h>
      15  #include <string.h>
      16  #include <unistd.h>
      17  #include <sys/socket.h>
      18  #include <sys/un.h>
      19  #include <arpa/inet.h>
      20  #include <netinet/in.h>
      21  #include "netlink.h"
      22  #include <linux/ax25.h>
      23  #include <linux/if_arp.h>
      24  #include <linux/if_ether.h>
      25  #include <linux/if_packet.h>
      26  #include <linux/x25.h>
      27  #if defined HAVE_LINUX_IPX_H
      28  # include <linux/ipx.h>
      29  #elif defined HAVE_NETIPX_IPX_H
      30  # include <netipx/ipx.h>
      31  #endif
      32  #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
      33  # include <bluetooth/bluetooth.h>
      34  # include <bluetooth/hci.h>
      35  # include <bluetooth/l2cap.h>
      36  # include <bluetooth/rfcomm.h>
      37  # include <bluetooth/sco.h>
      38  #endif
      39  
      40  static void
      41  check_un(void)
      42  {
      43  	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_un, un);
      44  	un->sun_family = AF_UNIX;
      45  	memset(un->sun_path, '0', sizeof(un->sun_path));
      46  	unsigned int len = sizeof(*un);
      47  	int ret = connect(-1, (void *) un, len);
      48  	pidns_print_leader();
      49  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
      50  	       ", %u) = %d EBADF (%m)\n",
      51  	       (int) sizeof(un->sun_path), 0, len, ret);
      52  
      53  	un->sun_path[1] = 0;
      54  	ret = connect(-1, (void *) un, len);
      55  	pidns_print_leader();
      56  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%u\"}, %u)"
      57  	       " = %d EBADF (%m)\n", 0, len, ret);
      58  
      59  	un->sun_path[0] = 0;
      60  	un->sun_path[2] = 1;
      61  	ret = connect(-1, (void *) un, len);
      62  	pidns_print_leader();
      63  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"\\0\\001%.*u\"}"
      64  	       ", %u) = %d EBADF (%m)\n",
      65  	       (int) sizeof(un->sun_path) - 3, 0, len, ret);
      66  
      67  	un = ((void *) un) - 2;
      68  	un->sun_family = AF_UNIX;
      69  	memset(un->sun_path, '0', sizeof(un->sun_path));
      70  	len = sizeof(*un) + 2;
      71  	ret = connect(-1, (void *) un, len);
      72  	pidns_print_leader();
      73  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
      74  	       ", %u) = %d EBADF (%m)\n",
      75  	       (int) sizeof(un->sun_path), 0, len, ret);
      76  
      77  	un->sun_path[0] = 0;
      78  	ret = connect(-1, (void *) un, len);
      79  	pidns_print_leader();
      80  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
      81  	       ", %u) = %d EBADF (%m)\n",
      82  	       (int) sizeof(un->sun_path) - 1, 0, len, ret);
      83  
      84  	un = ((void *) un) + 4;
      85  	un->sun_family = AF_UNIX;
      86  	len = sizeof(*un) - 2;
      87  	ret = connect(-1, (void *) un, len);
      88  	pidns_print_leader();
      89  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
      90  	       ", %u) = %d EBADF (%m)\n",
      91  	       (int) sizeof(un->sun_path) - 2, 0, len, ret);
      92  
      93  	un->sun_path[0] = 0;
      94  	ret = connect(-1, (void *) un, len);
      95  	pidns_print_leader();
      96  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
      97  	       ", %u) = %d EBADF (%m)\n",
      98  	       (int) sizeof(un->sun_path) - 3, 0, len, ret);
      99  
     100  	len = sizeof(*un);
     101  	ret = connect(-1, (void *) un, len);
     102  	pidns_print_leader();
     103  	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", un, len, ret);
     104  
     105  	un = tail_alloc(sizeof(struct sockaddr_storage));
     106  	un->sun_family = AF_UNIX;
     107  	memset(un->sun_path, '0', sizeof(un->sun_path));
     108  	len = sizeof(struct sockaddr_storage) + 1;
     109  	ret = connect(-1, (void *) un, len);
     110  	pidns_print_leader();
     111  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
     112  	       ", %u) = %d EBADF (%m)\n",
     113  	       (int) sizeof(un->sun_path), 0, len, ret);
     114  
     115  	un->sun_path[0] = 0;
     116  	ret = connect(-1, (void *) un, len);
     117  	pidns_print_leader();
     118  	printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
     119  	       ", %u) = %d EBADF (%m)\n",
     120  	       (int) sizeof(un->sun_path) - 1, 0, len, ret);
     121  }
     122  
     123  static void
     124  check_in(void)
     125  {
     126  	const unsigned short h_port = 12345;
     127  	static const char h_addr[] = "12.34.56.78";
     128  
     129  	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in, in);
     130  	in->sin_family = AF_INET;
     131  	in->sin_port = htons(h_port);
     132  	in->sin_addr.s_addr = inet_addr(h_addr);
     133  	unsigned int len = sizeof(*in);
     134  	int ret = connect(-1, (void *) in, len);
     135  	pidns_print_leader();
     136  	printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
     137  	       ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
     138  	       h_port, h_addr, len, ret);
     139  
     140  	in = ((void *) in) - 4;
     141  	in->sin_family = AF_INET;
     142  	in->sin_port = htons(h_port);
     143  	in->sin_addr.s_addr = inet_addr(h_addr);
     144  	len = sizeof(*in) + 4;
     145  	ret = connect(-1, (void *) in, len);
     146  	pidns_print_leader();
     147  	printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
     148  	       ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
     149  	       h_port, h_addr, len, ret);
     150  
     151  	in = ((void *) in) + 8;
     152  	in->sin_family = AF_INET;
     153  	in->sin_port = 0;
     154  	in->sin_addr.s_addr = 0;
     155  	len = sizeof(*in) - 4;
     156  	ret = connect(-1, (void *) in, len);
     157  	pidns_print_leader();
     158  	printf("connect(-1, {sa_family=AF_INET, sa_data=\"%s\"}, %u)"
     159  	       " = %d EBADF (%m)\n",
     160  	       "\\0\\0\\0\\0\\0\\0\\377\\377\\377\\377",
     161  	       len, ret);
     162  
     163  	len = sizeof(*in);
     164  	ret = connect(-1, (void *) in, len);
     165  	pidns_print_leader();
     166  	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in, len, ret);
     167  }
     168  
     169  static void
     170  check_in6_linklocal(struct sockaddr_in6 *const in6, const char *const h_addr)
     171  {
     172  	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
     173  
     174  	in6->sin6_scope_id = 0xfacefeed;
     175  	unsigned int len = sizeof(*in6);
     176  	int ret = connect(-1, (void *) in6, len);
     177  	pidns_print_leader();
     178  	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
     179  	       ", sin6_flowinfo=htonl(%u)"
     180  	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
     181  	       ", sin6_scope_id=%u}, %u)"
     182  	       " = %d EBADF (%m)\n",
     183  	       ntohs(in6->sin6_port), ntohl(in6->sin6_flowinfo),
     184  	       h_addr, in6->sin6_scope_id, len, ret);
     185  
     186  	in6->sin6_scope_id = ifindex_lo();
     187  	if (in6->sin6_scope_id) {
     188  		ret = connect(-1, (void *) in6, len);
     189  		pidns_print_leader();
     190  	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
     191  		       ", sin6_flowinfo=htonl(%u)"
     192  		       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
     193  		       ", sin6_scope_id=%s}, %u)"
     194  		       " = %d EBADF (%m)\n",
     195  		       ntohs(in6->sin6_port), ntohl(in6->sin6_flowinfo), h_addr,
     196  		       IFINDEX_LO_STR, len, ret);
     197  	}
     198  }
     199  
     200  static void
     201  check_in6(void)
     202  {
     203  	const unsigned short h_port = 12345;
     204  	const unsigned int h_flowinfo = 1234567890;
     205  	static const char h_addr[] = "12:34:56:78:90:ab:cd:ef";
     206  
     207  	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in6, in6);
     208  	in6->sin6_family = AF_INET6;
     209  	in6->sin6_port = htons(h_port);
     210  	in6->sin6_flowinfo = htonl(h_flowinfo);
     211  	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
     212  	in6->sin6_scope_id = 0xfacefeed;
     213  	unsigned int len = sizeof(*in6);
     214  	int ret = connect(-1, (void *) in6, len);
     215  	pidns_print_leader();
     216  	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
     217  	       ", sin6_flowinfo=htonl(%u)"
     218  	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
     219  	       ", sin6_scope_id=%u}, %u)"
     220  	       " = %d EBADF (%m)\n",
     221  	       h_port, h_flowinfo, h_addr, in6->sin6_scope_id, len, ret);
     222  
     223  	check_in6_linklocal(in6, "fe80::");
     224  	check_in6_linklocal(in6, "ff42::");
     225  
     226  	in6 = ((void *) in6) - 4;
     227  	in6->sin6_family = AF_INET6;
     228  	in6->sin6_port = htons(h_port);
     229  	in6->sin6_flowinfo = htonl(h_flowinfo);
     230  	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
     231  	in6->sin6_scope_id = 0xfacefeed;
     232  	len = sizeof(*in6) + 4;
     233  	ret = connect(-1, (void *) in6, len);
     234  	pidns_print_leader();
     235  	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
     236  	       ", sin6_flowinfo=htonl(%u)"
     237  	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
     238  	       ", sin6_scope_id=%u}, %u)"
     239  	       " = %d EBADF (%m)\n",
     240  	       h_port, h_flowinfo, h_addr, in6->sin6_scope_id, len, ret);
     241  
     242  	in6 = ((void *) in6) + 4 + sizeof(in6->sin6_scope_id);
     243  	in6->sin6_family = AF_INET6;
     244  	in6->sin6_port = htons(h_port);
     245  	in6->sin6_flowinfo = htonl(h_flowinfo);
     246  	inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
     247  	len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
     248  	ret = connect(-1, (void *) in6, len);
     249  	pidns_print_leader();
     250  	printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
     251  	       ", sin6_flowinfo=htonl(%u)"
     252  	       ", inet_pton(AF_INET6, \"%s\", &sin6_addr)}, %u)"
     253  	       " = %d EBADF (%m)\n",
     254  	       h_port, h_flowinfo, h_addr, len, ret);
     255  
     256  	in6 = ((void *) in6) + 4;
     257  	in6->sin6_family = AF_INET6;
     258  	in6->sin6_port = 0;
     259  	in6->sin6_flowinfo = 0;
     260  	memset(&in6->sin6_addr, '0', sizeof(in6->sin6_addr) - 4);
     261  	len = sizeof(*in6) - sizeof(in6->sin6_scope_id) - 4;
     262  	ret = connect(-1, (void *) in6, len);
     263  	pidns_print_leader();
     264  	printf("connect(-1, {sa_family=AF_INET6"
     265  	       ", sa_data=\"\\0\\0\\0\\0\\0\\000%.*u\"}, %u)"
     266  	       " = %d EBADF (%m)\n",
     267  	       (int) (len - offsetof(struct sockaddr_in6, sin6_addr)), 0,
     268  	       len, ret);
     269  
     270  	len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
     271  	ret = connect(-1, (void *) in6, len);
     272  	pidns_print_leader();
     273  	printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in6, len, ret);
     274  }
     275  
     276  #if defined HAVE_LINUX_IPX_H || defined HAVE_NETIPX_IPX_H
     277  static void
     278  check_ipx(void)
     279  {
     280  	const unsigned short h_port = 12345;
     281  	const unsigned int h_network = 0xfacefeed;
     282  	struct sockaddr_ipx c_ipx = {
     283  		.sipx_family = AF_IPX,
     284  		.sipx_port = htons(h_port),
     285  		.sipx_network = htonl(h_network),
     286  		.sipx_node = "ABCDEF",
     287  		.sipx_type = -1
     288  	};
     289  	struct sockaddr_ipx *ipx = tail_memdup(&c_ipx, sizeof(c_ipx));
     290  	unsigned int len = sizeof(c_ipx);
     291  
     292  	for (size_t i = 0; i < 2; i++) {
     293  		ipx->sipx_zero = i ? 0x42 : 0;
     294  		int ret = connect(-1, (void *) ipx, len);
     295  		pidns_print_leader();
     296  		printf("connect(-1, {sa_family=AF_IPX, sipx_port=htons(%u)"
     297  		       ", sipx_network=htonl(%#x)"
     298  		       ", sipx_node=[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
     299  		       ", sipx_type=%#02x%s}, %u) = %d EBADF (%m)\n",
     300  		       h_port, h_network,
     301  		       c_ipx.sipx_node[0], c_ipx.sipx_node[1],
     302  		       c_ipx.sipx_node[2], c_ipx.sipx_node[3],
     303  		       c_ipx.sipx_node[4], c_ipx.sipx_node[5],
     304  		       c_ipx.sipx_type, i ? ", sipx_zero=0x42" : "",
     305  		       len, ret);
     306  	}
     307  }
     308  #endif /* HAVE_LINUX_IPX_H || defined HAVE_NETIPX_IPX_H */
     309  
     310  /* for a bit more compact AX.25 address definitions */
     311  #define AX25_ADDR(c_, s_) \
     312  	{ { (c_)[0] << 1, (c_)[1] << 1, (c_)[2] << 1, \
     313  	    (c_)[3] << 1, (c_)[4] << 1, (c_)[5] << 1, (s_) << 1 } } \
     314  	/* End of AX25_ADDR definition */
     315  
     316  static void
     317  check_ax25(void)
     318  {
     319  	const struct full_sockaddr_ax25 ax25 = {
     320  		.fsa_ax25 = {
     321  			.sax25_family = AF_AX25,
     322  			.sax25_call = AX25_ADDR("VALID ", 13),
     323  			.sax25_ndigis = 8,
     324  		},
     325  		.fsa_digipeater = {
     326  			AX25_ADDR("SPA CE", 0),
     327  			AX25_ADDR("SSID  ", 16),
     328  			AX25_ADDR("      ", 0),
     329  			AX25_ADDR("NULL\0", 3),
     330  			AX25_ADDR("A-B-C", 4),
     331  			AX25_ADDR(",}]\"\\'", 5),
     332  			AX25_ADDR("DASH-0", 6),
     333  			AX25_ADDR("\n\tABCD", 7),
     334  		},
     335  	};
     336  	const ax25_address aux_addrs[] = {
     337  		AX25_ADDR("VALID2", 7),
     338  		AX25_ADDR("OK    ", 15),
     339  		AX25_ADDR("FINE  ", 2),
     340  		AX25_ADDR("smalls", 9),
     341  	};
     342  
     343  	enum { AX25_ALIGN = ALIGNOF(struct full_sockaddr_ax25), };
     344  	size_t size = sizeof(ax25);
     345  	size_t surplus = ROUNDUP(sizeof(ax25_address), AX25_ALIGN);
     346  	void *sax_void = midtail_alloc(size, surplus);
     347  	struct full_sockaddr_ax25 *sax = sax_void;
     348  	long rc;
     349  
     350  	fill_memory(sax, size);
     351  	sax->fsa_ax25.sax25_family = AF_AX25;
     352  	rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25) - 1);
     353  	pidns_print_leader();
     354  	printf("connect(-1, {sa_family=AF_AX25, sa_data=\"\\202\\203\\204\\205"
     355  	       "\\206\\207\\210\\211\\212\\213\\214\\215\\216\"}, %zu) = %s\n",
     356  	       sizeof(struct sockaddr_ax25) - 1, sprintrc(rc));
     357  
     358  	memcpy(sax, &ax25, sizeof(ax25));
     359  	rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25));
     360  	pidns_print_leader();
     361  	printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
     362  	       ", sax25_ndigis=8}, fsa_digipeater=[...]}, %zu) = %s\n",
     363  	       sizeof(struct sockaddr_ax25), sprintrc(rc));
     364  
     365  	sax->fsa_ax25.sax25_ndigis = 0;
     366  	rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25));
     367  	pidns_print_leader();
     368  	printf("connect(-1, {sa_family=AF_AX25, sax25_call=VALID-13"
     369  	       ", sax25_ndigis=0}, %zu) = %s\n",
     370  	       sizeof(struct sockaddr_ax25), sprintrc(rc));
     371  
     372  	sax->fsa_ax25.sax25_ndigis = 8;
     373  	size = sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 3 + 1;
     374  	rc = connect(-1, sax_void, size);
     375  	pidns_print_leader();
     376  	printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
     377  	       ", sax25_ndigis=8}, fsa_digipeater"
     378  	       "=[{ax25_call=\"\\xa6\\xa0\\x82\\x40\\x86\\x8a\\x00\""
     379  		   "} /* SPA CE-0 */"
     380  	       ", {ax25_call=\"\\xa6\\xa6\\x92\\x88\\x40\\x40\\x20\""
     381  	           "} /* SSID-0 */"
     382  	       ", *"
     383  	       ", ...], ...}, %zu) = %s\n",
     384  	       size, sprintrc(rc));
     385  
     386  	sax->fsa_digipeater[2].ax25_call[6] = 0x4;
     387  	size = sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 4;
     388  	rc = connect(-1, sax_void, size);
     389  	pidns_print_leader();
     390  	printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
     391  	       ", sax25_ndigis=8}, fsa_digipeater"
     392  	       "=[{ax25_call=\"\\xa6\\xa0\\x82\\x40\\x86\\x8a\\x00\""
     393  		   "} /* SPA CE-0 */"
     394  	       ", {ax25_call=\"\\xa6\\xa6\\x92\\x88\\x40\\x40\\x20\""
     395  	           "} /* SSID-0 */"
     396  	       ", {ax25_call=\"\\x40\\x40\\x40\\x40\\x40\\x40\\x04\"} /* -2 */"
     397  	       ", {ax25_call=\"\\x9c\\xaa\\x98\\x98\\x00\\x00\\x06\"}"
     398  	       ", ...]}, %zu) = %s\n",
     399  	       size, sprintrc(rc));
     400  
     401  	memcpy(sax->fsa_digipeater, aux_addrs, sizeof(aux_addrs));
     402  	sax->fsa_digipeater[2].ax25_call[6] = 0xa5;
     403  	sax->fsa_digipeater[4].ax25_call[5] = 0x40;
     404  	for (size_t i = 0; i < 3; i++) {
     405  		size = sizeof(ax25) + sizeof(ax25_address) * (i / 2);
     406  		rc = connect(-1, sax_void, size);
     407  		pidns_print_leader();
     408  		printf("connect(-1, {sa_family=AF_AX25"
     409  		       ", fsa_ax25={sax25_call=VALID-13, sax25_ndigis=%d}"
     410  		       ", fsa_digipeater=[VALID2-7, OK-15, %s /* FINE-2 */"
     411  		       ", {ax25_call=\"\\xe6\\xda\\xc2\\xd8\\xd8\\xe6\\x12\""
     412  		           "} /* smalls-9 */"
     413  		       ", {ax25_call=\"\\x%s\\x%s\\x84\\x5a\\x86\\x40\\x08\""
     414  		           "} /* %sB-C-4 */"
     415  		       ", {ax25_call=\"\\x58\\xfa\\xba\\x44\\x%s\\x%s\\x0a\""
     416  		           "}%s"
     417  		       ", {ax25_call=\"\\x88\\x82\\xa6\\x90\\x5a\\x%s\\x0c\""
     418  		           "}%s"
     419  		       "%s]%s}, %zu) = %s\n"
     420  		       , sax->fsa_ax25.sax25_ndigis
     421  		       , i
     422  		       ? "{ax25_call=\"\\x8c\\x92\\x9c\\x8a\\x40\\x41\\x04\"}"
     423  		       : "{ax25_call=\"\\x8c\\x92\\x9c\\x8a\\x40\\x40\\xa5\"}"
     424  		       , i ? "40" : "82"
     425  		       , i ? "40" : "5a"
     426  		       , i ? "  " : "A-"
     427  		       , i ? "54" : "b8"
     428  		       , i ? "5e" : "4e"
     429  		       , i ? "" : " /* ,}]\"\\'-5 */"
     430  		       , i ? "fe" : "60"
     431  		       , i ? "" : " /* DASH-0-6 */"
     432  		       , i == 1
     433  		       ? ""
     434  		       : ", {ax25_call=\"\\x14\\x12\\x82\\x84\\x86\\x88\\x0e\"}"
     435  		       , i > 1 ? ", ..." : ""
     436  		       , size, sprintrc(rc));
     437  
     438  		if (i == 1) {
     439  			sax_void = (char *) sax_void - surplus;
     440  			memmove(sax_void, sax, sizeof(ax25));
     441  			sax = sax_void;
     442  		}
     443  
     444  		sax->fsa_ax25.sax25_ndigis = 7 + 2 * i;
     445  
     446  		sax->fsa_digipeater[2].ax25_call[5] = 0x41;
     447  		sax->fsa_digipeater[2].ax25_call[6] = 0x4;
     448  
     449  		sax->fsa_digipeater[4].ax25_call[0] = 0x40;
     450  		sax->fsa_digipeater[4].ax25_call[1] = 0x40;
     451  
     452  		sax->fsa_digipeater[5].ax25_call[4] = '*' << 1;
     453  		sax->fsa_digipeater[5].ax25_call[5] = '/' << 1;
     454  
     455  		sax->fsa_digipeater[6].ax25_call[5] = 0xfe;
     456  	}
     457  }
     458  
     459  static void
     460  check_x25(void)
     461  {
     462  	static const struct sockaddr_x25 c_x25 = {
     463  		.sx25_family = AF_X25,
     464  		.sx25_addr = { "0123456789abcdef" },
     465  	};
     466  	void *const x25_void = tail_memdup(&c_x25, sizeof(c_x25) + 1);
     467  	long rc;
     468  
     469  	rc = connect(-1, x25_void, sizeof(c_x25) - 1);
     470  	pidns_print_leader();
     471  	printf("connect(-1, {sa_family=AF_X25"
     472  	       ", sa_data=\"0123456789abcde\"}, %zu) = %s\n",
     473  	       sizeof(c_x25) - 1, sprintrc(rc));
     474  
     475  	for (size_t i = 0; i < 2; i++) {
     476  		rc = connect(-1, x25_void, sizeof(c_x25) + i);
     477  		pidns_print_leader();
     478  		printf("connect(-1, {sa_family=AF_X25"
     479  		       ", sx25_addr={x25_addr=\"0123456789abcde\"...}"
     480  		       "}, %zu) = %s\n",
     481  		       sizeof(c_x25) + i, sprintrc(rc));
     482  	}
     483  
     484  	struct sockaddr_x25 *const x25 = x25_void;
     485  	x25->sx25_addr.x25_addr[10] = '\0';
     486  	rc = connect(-1, x25_void, sizeof(c_x25));
     487  	pidns_print_leader();
     488  	printf("connect(-1, {sa_family=AF_X25"
     489  	       ", sx25_addr={x25_addr=\"0123456789\"}"
     490  	       "}, %zu) = %s\n",
     491  	       sizeof(c_x25), sprintrc(rc));
     492  }
     493  
     494  static void
     495  check_nl(void)
     496  {
     497  	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_nl, nl);
     498  	nl->nl_family = AF_NETLINK;
     499  	nl->nl_pid = 1234567890;
     500  	nl->nl_groups = 0xfacefeed;
     501  	unsigned int len = sizeof(*nl);
     502  
     503  	int ret = connect(-1, (void *) nl, len - 1);
     504  	pidns_print_leader();
     505  	printf("connect(-1, {sa_family=AF_NETLINK, sa_data=\"\\377\\377"
     506  	       BE_LE("I\\226\\2\\322", "\\322\\2\\226I")
     507  	       BE_LE("\\372\\316\\376", "\\355\\376\\316")
     508  	       "\"}, %u) = %d EBADF (%m)\n",
     509  	       len - 1, ret);
     510  
     511  	ret = connect(-1, (void *) nl, len);
     512  	pidns_print_leader();
     513  	printf("connect(-1, {sa_family=AF_NETLINK, nl_pad=%#x, nl_pid=%d"
     514  	       ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
     515  	       nl->nl_pad, nl->nl_pid, nl->nl_groups, len, ret);
     516  
     517  	nl->nl_pad = 0;
     518  	ret = connect(-1, (void *) nl, len);
     519  	pidns_print_leader();
     520  	printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
     521  	       ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
     522  	       nl->nl_pid, nl->nl_groups, len, ret);
     523  
     524  	nl = ((void *) nl) - 4;
     525  	nl->nl_family = AF_NETLINK;
     526  	nl->nl_pad = 0;
     527  	nl->nl_pid = getpid();
     528  	nl->nl_groups = 0xfacefeed;
     529  	len = sizeof(*nl) + 4;
     530  	ret = connect(-1, (void *) nl, len);
     531  	pidns_print_leader();
     532  	printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d%s"
     533  	       ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
     534  	       nl->nl_pid, pidns_pid2str(PT_TGID), nl->nl_groups, len, ret);
     535  }
     536  
     537  static void
     538  check_ll(void)
     539  {
     540  	struct sockaddr_ll c_ll = {
     541  		.sll_family = AF_PACKET,
     542  		.sll_protocol = htons(ETH_P_ALL),
     543  		.sll_ifindex = 0xfacefeed,
     544  		.sll_hatype = ARPHRD_ETHER,
     545  		.sll_pkttype = PACKET_HOST,
     546  		.sll_halen = sizeof(c_ll.sll_addr),
     547  		.sll_addr = "abcdefgh"
     548  	};
     549  	void *ll = tail_memdup(&c_ll, sizeof(c_ll));
     550  	unsigned int len = sizeof(c_ll);
     551  	int ret = connect(-1, ll, len);
     552  	pidns_print_leader();
     553  	printf("connect(-1, {sa_family=AF_PACKET"
     554  	       ", sll_protocol=htons(ETH_P_ALL)"
     555  	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
     556  	       ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
     557  	       "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
     558  	       "}, %u) = %d EBADF (%m)\n",
     559  	       c_ll.sll_ifindex, c_ll.sll_halen,
     560  	       c_ll.sll_addr[0], c_ll.sll_addr[1],
     561  	       c_ll.sll_addr[2], c_ll.sll_addr[3],
     562  	       c_ll.sll_addr[4], c_ll.sll_addr[5],
     563  	       c_ll.sll_addr[6], c_ll.sll_addr[7],
     564  	       len, ret);
     565  
     566  	((struct sockaddr_ll *) ll)->sll_halen++;
     567  	ret = connect(-1, ll, len);
     568  	pidns_print_leader();
     569  	printf("connect(-1, {sa_family=AF_PACKET"
     570  	       ", sll_protocol=htons(ETH_P_ALL)"
     571  	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
     572  	       ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
     573  	       "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, ...]"
     574  	       "}, %u) = %d EBADF (%m)\n",
     575  	       c_ll.sll_ifindex, c_ll.sll_halen + 1,
     576  	       c_ll.sll_addr[0], c_ll.sll_addr[1],
     577  	       c_ll.sll_addr[2], c_ll.sll_addr[3],
     578  	       c_ll.sll_addr[4], c_ll.sll_addr[5],
     579  	       c_ll.sll_addr[6], c_ll.sll_addr[7],
     580  	       len, ret);
     581  
     582  	((struct sockaddr_ll *) ll)->sll_halen = 0;
     583  	ret = connect(-1, ll, len);
     584  	pidns_print_leader();
     585  	printf("connect(-1, {sa_family=AF_PACKET"
     586  	       ", sll_protocol=htons(ETH_P_ALL)"
     587  	       ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
     588  	       ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
     589  	       " = %d EBADF (%m)\n", c_ll.sll_ifindex, len, ret);
     590  
     591  	((struct sockaddr_ll *) ll)->sll_ifindex = ifindex_lo();
     592  	if (((struct sockaddr_ll *) ll)->sll_ifindex) {
     593  		ret = connect(-1, ll, len);
     594  	pidns_print_leader();
     595  		printf("connect(-1, {sa_family=AF_PACKET"
     596  		       ", sll_protocol=htons(ETH_P_ALL)"
     597  		       ", sll_ifindex=%s"
     598  		       ", sll_hatype=ARPHRD_ETHER"
     599  		       ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
     600  		       " = %d EBADF (%m)\n", IFINDEX_LO_STR, len, ret);
     601  	}
     602  }
     603  
     604  #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
     605  static void
     606  check_hci(void)
     607  {
     608  	const unsigned short h_port = 12345;
     609  	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_hci, hci);
     610  	hci->hci_family = AF_BLUETOOTH;
     611  	hci->hci_dev = htobs(h_port);
     612  # ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
     613  	hci->hci_channel = HCI_CHANNEL_RAW;
     614  # endif
     615  	unsigned int len = sizeof(*hci);
     616  
     617  	int ret = connect(-1, (void *) hci, 4);
     618  	pidns_print_leader();
     619  	printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
     620  	       "}, 4) = %d EBADF (%m)\n",
     621  	       h_port, ret);
     622  
     623  	ret = connect(-1, (void *) hci, len);
     624  	pidns_print_leader();
     625  	printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
     626  # ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
     627  	       ", hci_channel=HCI_CHANNEL_RAW"
     628  # endif
     629  	       "}, %u) = %d EBADF (%m)\n",
     630  	       h_port, len, ret);
     631  }
     632  
     633  static void
     634  check_sco(void)
     635  {
     636  	const struct sockaddr_sco c_sco = {
     637  		.sco_family = AF_BLUETOOTH,
     638  		.sco_bdaddr.b = "abcdef"
     639  	};
     640  	void *sco = tail_memdup(&c_sco, sizeof(c_sco));
     641  	unsigned int len = sizeof(c_sco);
     642  	int ret = connect(-1, sco, len);
     643  	pidns_print_leader();
     644  	printf("connect(-1, {sa_family=AF_BLUETOOTH"
     645  	       ", sco_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
     646  	       "}, %u) = %d EBADF (%m)\n",
     647  	       c_sco.sco_bdaddr.b[0], c_sco.sco_bdaddr.b[1],
     648  	       c_sco.sco_bdaddr.b[2], c_sco.sco_bdaddr.b[3],
     649  	       c_sco.sco_bdaddr.b[4], c_sco.sco_bdaddr.b[5],
     650  	       len, ret);
     651  }
     652  
     653  static void
     654  check_rc(void)
     655  {
     656  	const struct sockaddr_rc c_rc = {
     657  		.rc_family = AF_BLUETOOTH,
     658  		.rc_bdaddr.b = "abcdef",
     659  		.rc_channel = 42
     660  	};
     661  	void *rc = tail_memdup(&c_rc, sizeof(c_rc));
     662  	unsigned int len = sizeof(c_rc);
     663  	int ret = connect(-1, rc, len);
     664  	pidns_print_leader();
     665  	printf("connect(-1, {sa_family=AF_BLUETOOTH"
     666  	       ", rc_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
     667  	       ", rc_channel=%u}, %u) = %d EBADF (%m)\n",
     668  	       c_rc.rc_bdaddr.b[0], c_rc.rc_bdaddr.b[1],
     669  	       c_rc.rc_bdaddr.b[2], c_rc.rc_bdaddr.b[3],
     670  	       c_rc.rc_bdaddr.b[4], c_rc.rc_bdaddr.b[5],
     671  	       c_rc.rc_channel, len, ret);
     672  }
     673  
     674  static void
     675  check_l2(void)
     676  {
     677  	const unsigned short h_psm = 12345;
     678  	const unsigned short h_cid = 13579;
     679  	struct sockaddr_l2 c_l2 = {
     680  		.l2_family = AF_BLUETOOTH,
     681  		.l2_psm = htobs(h_psm),
     682  		.l2_bdaddr.b = "abcdef",
     683  		.l2_cid = htobs(h_cid),
     684  # ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
     685  		.l2_bdaddr_type = 0xce,
     686  # endif
     687  	};
     688  	void *l2 = tail_memdup(&c_l2, sizeof(c_l2));
     689  	unsigned int len = sizeof(c_l2);
     690  
     691  	int ret = connect(-1, l2, len);
     692  	pidns_print_leader();
     693  	printf("connect(-1, {sa_family=AF_BLUETOOTH"
     694  	       ", l2_psm=htobs(L2CAP_PSM_DYN_START+%hu)"
     695  	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
     696  	       ", l2_cid=htobs(L2CAP_CID_DYN_START+%hu)"
     697  # ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
     698  	       ", l2_bdaddr_type=0xce /* BDADDR_??? */"
     699  # endif
     700  	       "}, %u) = %d EBADF (%m)\n",
     701  	       (short) (h_psm - 0x1001),
     702  	       c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
     703  	       c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
     704  	       c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
     705  	       (short) (h_cid - 0x40), len, ret);
     706  
     707  	c_l2.l2_psm = htobs(1);
     708  	c_l2.l2_cid = htobs(1);
     709  # ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
     710  	c_l2.l2_bdaddr_type = BDADDR_LE_RANDOM;
     711  # endif
     712  	memcpy(l2, &c_l2, sizeof(c_l2));
     713  	ret = connect(-1, l2, len);
     714  	pidns_print_leader();
     715  	printf("connect(-1, {sa_family=AF_BLUETOOTH"
     716  	       ", l2_psm=htobs(L2CAP_PSM_SDP)"
     717  	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
     718  	       ", l2_cid=htobs(L2CAP_CID_SIGNALING)"
     719  # ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
     720  	       ", l2_bdaddr_type=BDADDR_LE_RANDOM"
     721  # endif
     722  	       "}, %u) = %d EBADF (%m)\n",
     723  	       c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
     724  	       c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
     725  	       c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
     726  	       len, ret);
     727  
     728  	c_l2.l2_psm = htobs(0xbad);
     729  	c_l2.l2_cid = htobs(8);
     730  # ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
     731  	c_l2.l2_bdaddr_type = 3;
     732  # endif
     733  	memcpy(l2, &c_l2, sizeof(c_l2));
     734  	ret = connect(-1, l2, len);
     735  	pidns_print_leader();
     736  	printf("connect(-1, {sa_family=AF_BLUETOOTH"
     737  	       ", l2_psm=htobs(0xbad /* L2CAP_PSM_??? */)"
     738  	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
     739  	       ", l2_cid=htobs(0x8 /* L2CAP_CID_??? */)"
     740  # ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
     741  	       ", l2_bdaddr_type=0x3 /* BDADDR_??? */"
     742  # endif
     743  	       "}, %u) = %d EBADF (%m)\n",
     744  	       c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
     745  	       c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
     746  	       c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
     747  	       len, ret);
     748  
     749  	c_l2.l2_psm = htobs(0x10ff);
     750  	c_l2.l2_cid = htobs(0xffff);
     751  	memcpy(l2, &c_l2, 12);
     752  	ret = connect(-1, l2, 12);
     753  	pidns_print_leader();
     754  	printf("connect(-1, {sa_family=AF_BLUETOOTH"
     755  	       ", l2_psm=htobs(L2CAP_PSM_AUTO_END)"
     756  	       ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
     757  	       ", l2_cid=htobs(L2CAP_CID_DYN_END)"
     758  	       "}, 12) = %d EBADF (%m)\n",
     759  	       c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
     760  	       c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
     761  	       c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
     762  	       ret);
     763  }
     764  #endif
     765  
     766  static void
     767  check_raw(void)
     768  {
     769  	union {
     770  		struct sockaddr *sa;
     771  		struct sockaddr_storage *st;
     772  	} u = { .st = tail_alloc(sizeof(*u.st)) };
     773  	memset(u.st, '0', sizeof(*u.st));
     774  	u.sa->sa_family = 0xff;
     775  	unsigned int len = sizeof(*u.st) + 8;
     776  	int ret = connect(-1, (void *) u.st, len);
     777  	pidns_print_leader();
     778  	printf("connect(-1, {sa_family=%#x /* AF_??? */, sa_data=\"%.*u\"}"
     779  	       ", %u) = %d EBADF (%m)\n", u.sa->sa_family,
     780  	       (int) (sizeof(*u.st) - sizeof(u.sa->sa_family)), 0, len, ret);
     781  
     782  	u.sa->sa_family = 0;
     783  	len = sizeof(u.sa->sa_family) + 1;
     784  	ret = connect(-1, (void *) u.st, len);
     785  	pidns_print_leader();
     786  	printf("connect(-1, {sa_family=AF_UNSPEC, sa_data=\"0\"}, %u)"
     787  	       " = %d EBADF (%m)\n", len, ret);
     788  
     789  	u.sa->sa_family = AF_BLUETOOTH;
     790  	ret = connect(-1, (void *) u.st, len);
     791  	pidns_print_leader();
     792  	printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"0\"}, %u)"
     793  	       " = %d EBADF (%m)\n", len, ret);
     794  }
     795  
     796  int
     797  main(void)
     798  {
     799  	PIDNS_TEST_INIT;
     800  
     801  	check_un();
     802  	check_in();
     803  	check_in6();
     804  #if defined HAVE_LINUX_IPX_H || defined HAVE_NETIPX_IPX_H
     805  	check_ipx();
     806  #endif
     807  	check_ax25();
     808  	check_x25();
     809  	check_nl();
     810  	check_ll();
     811  #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
     812  	check_hci();
     813  	check_sco();
     814  	check_rc();
     815  	check_l2();
     816  #endif
     817  	check_raw();
     818  
     819  	pidns_print_leader();
     820  	puts("+++ exited with 0 +++");
     821  	return 0;
     822  }