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.3 2017/02/05 04:05:05 spz Exp $"); 25 #endif 26 27 /* \summary: USB printer */ 28 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 #include <netdissect-stdinc.h> 34 35 #include "netdissect.h" 36 37 38 #if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) 39 #include <pcap/usb.h> 40 41 static const char tstr[] = "[|usb]"; 42 43 /* returns direction: 1=inbound 2=outbound -1=invalid */ 44 static int 45 get_direction(int transfer_type, int event_type) 46 { 47 int direction; 48 49 direction = -1; 50 switch(transfer_type){ 51 case URB_BULK: 52 case URB_CONTROL: 53 case URB_ISOCHRONOUS: 54 switch(event_type) 55 { 56 case URB_SUBMIT: 57 direction = 2; 58 break; 59 case URB_COMPLETE: 60 case URB_ERROR: 61 direction = 1; 62 break; 63 default: 64 direction = -1; 65 } 66 break; 67 case URB_INTERRUPT: 68 switch(event_type) 69 { 70 case URB_SUBMIT: 71 direction = 1; 72 break; 73 case URB_COMPLETE: 74 case URB_ERROR: 75 direction = 2; 76 break; 77 default: 78 direction = -1; 79 } 80 break; 81 default: 82 direction = -1; 83 } 84 85 return direction; 86 } 87 88 static void 89 usb_header_print(netdissect_options *ndo, const pcap_usb_header *uh) 90 { 91 int direction; 92 93 switch(uh->transfer_type) 94 { 95 case URB_ISOCHRONOUS: 96 ND_PRINT((ndo, "ISOCHRONOUS")); 97 break; 98 case URB_INTERRUPT: 99 ND_PRINT((ndo, "INTERRUPT")); 100 break; 101 case URB_CONTROL: 102 ND_PRINT((ndo, "CONTROL")); 103 break; 104 case URB_BULK: 105 ND_PRINT((ndo, "BULK")); 106 break; 107 default: 108 ND_PRINT((ndo, " ?")); 109 } 110 111 switch(uh->event_type) 112 { 113 case URB_SUBMIT: 114 ND_PRINT((ndo, " SUBMIT")); 115 break; 116 case URB_COMPLETE: 117 ND_PRINT((ndo, " COMPLETE")); 118 break; 119 case URB_ERROR: 120 ND_PRINT((ndo, " ERROR")); 121 break; 122 default: 123 ND_PRINT((ndo, " ?")); 124 } 125 126 direction = get_direction(uh->transfer_type, uh->event_type); 127 if(direction == 1) 128 ND_PRINT((ndo, " from")); 129 else if(direction == 2) 130 ND_PRINT((ndo, " to")); 131 ND_PRINT((ndo, " %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f)); 132 } 133 134 /* 135 * This is the top level routine of the printer for captures with a 136 * 48-byte header. 137 * 138 * 'p' points to the header of the packet, 'h->ts' is the timestamp, 139 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 140 * is the number of bytes actually captured. 141 */ 142 u_int 143 usb_linux_48_byte_print(netdissect_options *ndo, const struct pcap_pkthdr *h, 144 register const u_char *p) 145 { 146 if (h->caplen < sizeof(pcap_usb_header)) { 147 ND_PRINT((ndo, "%s", tstr)); 148 return(sizeof(pcap_usb_header)); 149 } 150 151 usb_header_print(ndo, (const pcap_usb_header *) p); 152 153 return(sizeof(pcap_usb_header)); 154 } 155 156 #ifdef DLT_USB_LINUX_MMAPPED 157 /* 158 * This is the top level routine of the printer for captures with a 159 * 64-byte header. 160 * 161 * 'p' points to the header of the packet, 'h->ts' is the timestamp, 162 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 163 * is the number of bytes actually captured. 164 */ 165 u_int 166 usb_linux_64_byte_print(netdissect_options *ndo, const struct pcap_pkthdr *h, 167 register const u_char *p) 168 { 169 if (h->caplen < sizeof(pcap_usb_header_mmapped)) { 170 ND_PRINT((ndo, "%s", tstr)); 171 return(sizeof(pcap_usb_header_mmapped)); 172 } 173 174 usb_header_print(ndo, (const pcap_usb_header *) p); 175 176 return(sizeof(pcap_usb_header_mmapped)); 177 } 178 #endif /* DLT_USB_LINUX_MMAPPED */ 179 180 #endif /* defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) */ 181 182