Browse Source

sockaddr: properly decode sockaddr_hci addresses without hci_channel

Before Linux commit v2.6.38-rc1~476^2~14^2~3^2~43^2~9,
struct sockaddr_hci did not contain hci_channel field.

* configure.ac (AC_CHECK_HEADERS([bluetooth/bluetooth.h])): Add check
for struct sockaddr_hci.hci_channel.
* sockaddr.c (print_sockaddr_data_bt): Decode struct sockaddr_hci
without hci_channel field.
* tests/net-sockaddr.c (check_hci): Add check for struct sockaddr_hci
decoding without hci_channel field; guard hci_channel with #ifdef
HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL.
(check_raw): Remove "len++", as 4-byte AF_BLUETOOTH socket addresses are
interpreted as struct sockaddr_hci without hci_channel field.
Eugene Syromyatnikov 2 months ago
parent
commit
c108f0b48b
3 changed files with 30 additions and 7 deletions
  1. 3
    0
      configure.ac
  2. 13
    3
      sockaddr.c
  3. 14
    4
      tests/net-sockaddr.c

+ 3
- 0
configure.ac View File

@@ -479,6 +479,9 @@ AC_CHECK_HEADERS([linux/bpf.h], [
479 479
 ])
480 480
 
481 481
 AC_CHECK_HEADERS([bluetooth/bluetooth.h], [
482
+	AC_CHECK_MEMBERS([struct sockaddr_hci.hci_channel],,,
483
+			 [#include <bluetooth/bluetooth.h>
484
+			 #include <bluetooth/hci.h>])
482 485
 	AC_CHECK_MEMBERS([struct sockaddr_l2.l2_bdaddr_type],,,
483 486
 			 [#include <bluetooth/bluetooth.h>
484 487
 			 #include <bluetooth/l2cap.h>])

+ 13
- 3
sockaddr.c View File

@@ -599,11 +599,21 @@ print_sockaddr_data_bt(const void *const buf, const int addrlen)
599 599
 	};
600 600
 
601 601
 	switch (addrlen) {
602
+	case offsetofend(struct sockaddr_hci, hci_dev):
602 603
 	case sizeof(struct sockaddr_hci): {
603 604
 		const struct sockaddr_hci *const hci = buf;
604
-		tprintf("hci_dev=htobs(%hu), hci_channel=",
605
-			btohs(hci->hci_dev));
606
-		printxval(hci_channels, hci->hci_channel, "HCI_CHANNEL_???");
605
+		tprintf("hci_dev=htobs(%hu)", btohs(hci->hci_dev));
606
+
607
+		/*
608
+		 * hci_channel field has been introduced
609
+		 * Linux commit in v2.6.38-rc1~476^2~14^2~3^2~43^2~9.
610
+		 */
611
+		if (addrlen == sizeof(struct sockaddr_hci)) {
612
+			tprints(", hci_channel=");
613
+			printxval(hci_channels, hci->hci_channel,
614
+				  "HCI_CHANNEL_???");
615
+		}
616
+
607 617
 		break;
608 618
 	}
609 619
 	case sizeof(struct sockaddr_sco): {

+ 14
- 4
tests/net-sockaddr.c View File

@@ -543,11 +543,22 @@ check_hci(void)
543 543
 	TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_hci, hci);
544 544
 	hci->hci_family = AF_BLUETOOTH;
545 545
 	hci->hci_dev = htobs(h_port);
546
+# ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
546 547
 	hci->hci_channel = HCI_CHANNEL_RAW;
548
+# endif
547 549
 	unsigned int len = sizeof(*hci);
548
-	int ret = connect(-1, (void *) hci, len);
550
+
551
+	int ret = connect(-1, (void *) hci, 4);
552
+	printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
553
+	       "}, 4) = %d EBADF (%m)\n",
554
+	       h_port, ret);
555
+
556
+	ret = connect(-1, (void *) hci, len);
549 557
 	printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
550
-	       ", hci_channel=HCI_CHANNEL_RAW}, %u) = %d EBADF (%m)\n",
558
+# ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
559
+	       ", hci_channel=HCI_CHANNEL_RAW"
560
+# endif
561
+	       "}, %u) = %d EBADF (%m)\n",
551 562
 	       h_port, len, ret);
552 563
 }
553 564
 
@@ -700,9 +711,8 @@ check_raw(void)
700 711
 	       " = %d EBADF (%m)\n", len, ret);
701 712
 
702 713
 	u.sa->sa_family = AF_BLUETOOTH;
703
-	++len;
704 714
 	ret = connect(-1, (void *) u.st, len);
705
-	printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"00\"}, %u)"
715
+	printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"0\"}, %u)"
706 716
 	       " = %d EBADF (%m)\n", len, ret);
707 717
 }
708 718
 

Loading…
Cancel
Save