1 /* 2 * Copyright 2009 Bert Vermeulen <bert@biot.com> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that: (1) source code distributions 6 * retain the above copyright notice and this paragraph in its entirety, (2) 7 * distributions including binary code include the above copyright notice and 8 * this paragraph in its entirety in the documentation or other materials 9 * provided with the distribution, and (3) all advertising materials mentioning 10 * features or use of this software display the following acknowledgement: 11 * ``This product includes software developed by Paolo Abeni.'' 12 * The name of author may not be used to endorse or promote products derived 13 * from this software without specific prior written permission. 14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 15 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 * 18 * Support for USB packets 19 * 20 */ 21 22 #include <sys/cdefs.h> 23 #ifndef lint 24 __RCSID("$NetBSD: print-usb.c,v 1.2 2017/01/24 23:29:14 christos Exp $"); 25 #endif 26 27 #ifdef HAVE_CONFIG_H 28 #include "config.h" 29 #endif 30 31 #include <netdissect-stdinc.h> 32 33 #include "netdissect.h" 34 35 36 #if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) 37 #include <pcap/usb.h> 38 39 static const char tstr[] = "[|usb]"; 40 41 /* returns direction: 1=inbound 2=outbound -1=invalid */ 42 static int 43 get_direction(int transfer_type, int event_type) 44 { 45 int direction; 46 47 direction = -1; 48 switch(transfer_type){ 49 case URB_BULK: 50 case URB_CONTROL: 51 case URB_ISOCHRONOUS: 52 switch(event_type) 53 { 54 case URB_SUBMIT: 55 direction = 2; 56 break; 57 case URB_COMPLETE: 58 case URB_ERROR: 59 direction = 1; 60 break; 61 default: 62 direction = -1; 63 } 64 break; 65 case URB_INTERRUPT: 66 switch(event_type) 67 { 68 case URB_SUBMIT: 69 direction = 1; 70 break; 71 case URB_COMPLETE: 72 case URB_ERROR: 73 direction = 2; 74 break; 75 default: 76 direction = -1; 77 } 78 break; 79 default: 80 direction = -1; 81 } 82 83 return direction; 84 } 85 86 static void 87 usb_header_print(netdissect_options *ndo, const pcap_usb_header *uh) 88 { 89 int direction; 90 91 switch(uh->transfer_type) 92 { 93 case URB_ISOCHRONOUS: 94 ND_PRINT((ndo, "ISOCHRONOUS")); 95 break; 96 case URB_INTERRUPT: 97 ND_PRINT((ndo, "INTERRUPT")); 98 break; 99 case URB_CONTROL: 100 ND_PRINT((ndo, "CONTROL")); 101 break; 102 case URB_BULK: 103 ND_PRINT((ndo, "BULK")); 104 break; 105 default: 106 ND_PRINT((ndo, " ?")); 107 } 108 109 switch(uh->event_type) 110 { 111 case URB_SUBMIT: 112 ND_PRINT((ndo, " SUBMIT")); 113 break; 114 case URB_COMPLETE: 115 ND_PRINT((ndo, " COMPLETE")); 116 break; 117 case URB_ERROR: 118 ND_PRINT((ndo, " ERROR")); 119 break; 120 default: 121 ND_PRINT((ndo, " ?")); 122 } 123 124 direction = get_direction(uh->transfer_type, uh->event_type); 125 if(direction == 1) 126 ND_PRINT((ndo, " from")); 127 else if(direction == 2) 128 ND_PRINT((ndo, " to")); 129 ND_PRINT((ndo, " %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f)); 130 } 131 132 /* 133 * This is the top level routine of the printer for captures with a 134 * 48-byte header. 135 * 136 * 'p' points to the header of the packet, 'h->ts' is the timestamp, 137 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 138 * is the number of bytes actually captured. 139 */ 140 u_int 141 usb_linux_48_byte_print(netdissect_options *ndo, const struct pcap_pkthdr *h, 142 register const u_char *p) 143 { 144 if (h->caplen < sizeof(pcap_usb_header)) { 145 ND_PRINT((ndo, "%s", tstr)); 146 return(sizeof(pcap_usb_header)); 147 } 148 149 usb_header_print(ndo, (const pcap_usb_header *) p); 150 151 return(sizeof(pcap_usb_header)); 152 } 153 154 #ifdef DLT_USB_LINUX_MMAPPED 155 /* 156 * This is the top level routine of the printer for captures with a 157 * 64-byte header. 158 * 159 * 'p' points to the header of the packet, 'h->ts' is the timestamp, 160 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 161 * is the number of bytes actually captured. 162 */ 163 u_int 164 usb_linux_64_byte_print(netdissect_options *ndo, const struct pcap_pkthdr *h, 165 register const u_char *p) 166 { 167 if (h->caplen < sizeof(pcap_usb_header_mmapped)) { 168 ND_PRINT((ndo, "%s", tstr)); 169 return(sizeof(pcap_usb_header_mmapped)); 170 } 171 172 usb_header_print(ndo, (const pcap_usb_header *) p); 173 174 return(sizeof(pcap_usb_header_mmapped)); 175 } 176 #endif /* DLT_USB_LINUX_MMAPPED */ 177 178 #endif /* defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) */ 179 180