1214456Srpaulo/* 2214456Srpaulo * Copyright 2009 Bert Vermeulen <bert@biot.com> 3214456Srpaulo * 4214456Srpaulo * Redistribution and use in source and binary forms, with or without 5214456Srpaulo * modification, are permitted provided that: (1) source code distributions 6214456Srpaulo * retain the above copyright notice and this paragraph in its entirety, (2) 7214456Srpaulo * distributions including binary code include the above copyright notice and 8214456Srpaulo * this paragraph in its entirety in the documentation or other materials 9214456Srpaulo * provided with the distribution, and (3) all advertising materials mentioning 10214456Srpaulo * features or use of this software display the following acknowledgement: 11214456Srpaulo * ``This product includes software developed by Paolo Abeni.'' 12214456Srpaulo * The name of author may not be used to endorse or promote products derived 13214456Srpaulo * from this software without specific prior written permission. 14214456Srpaulo * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 15214456Srpaulo * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 16214456Srpaulo * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17214456Srpaulo * 18214456Srpaulo * Support for USB packets 19214456Srpaulo * 20214456Srpaulo */ 21214456Srpaulo 22214456Srpaulo#ifdef HAVE_CONFIG_H 23214456Srpaulo#include "config.h" 24214456Srpaulo#endif 25214456Srpaulo 26214456Srpaulo#include <tcpdump-stdinc.h> 27214456Srpaulo 28214456Srpaulo#include <pcap.h> 29214456Srpaulo#include <stdio.h> 30214456Srpaulo#include <string.h> 31214456Srpaulo 32214456Srpaulo#include "interface.h" 33214456Srpaulo 34214456Srpaulo 35214456Srpaulo#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) 36214456Srpaulo#include <pcap/usb.h> 37214456Srpaulo 38214456Srpaulo/* returns direction: 1=inbound 2=outbound -1=invalid */ 39214456Srpaulostatic int 40214456Srpauloget_direction(int transfer_type, int event_type) 41214456Srpaulo{ 42214456Srpaulo int direction; 43214456Srpaulo 44214456Srpaulo direction = -1; 45214456Srpaulo switch(transfer_type){ 46214456Srpaulo case URB_BULK: 47214456Srpaulo case URB_CONTROL: 48214456Srpaulo case URB_ISOCHRONOUS: 49214456Srpaulo switch(event_type) 50214456Srpaulo { 51214456Srpaulo case URB_SUBMIT: 52214456Srpaulo direction = 2; 53214456Srpaulo break; 54214456Srpaulo case URB_COMPLETE: 55214456Srpaulo case URB_ERROR: 56214456Srpaulo direction = 1; 57214456Srpaulo break; 58214456Srpaulo default: 59214456Srpaulo direction = -1; 60214456Srpaulo } 61214456Srpaulo break; 62214456Srpaulo case URB_INTERRUPT: 63214456Srpaulo switch(event_type) 64214456Srpaulo { 65214456Srpaulo case URB_SUBMIT: 66214456Srpaulo direction = 1; 67214456Srpaulo break; 68214456Srpaulo case URB_COMPLETE: 69214456Srpaulo case URB_ERROR: 70214456Srpaulo direction = 2; 71214456Srpaulo break; 72214456Srpaulo default: 73214456Srpaulo direction = -1; 74214456Srpaulo } 75214456Srpaulo break; 76214456Srpaulo default: 77214456Srpaulo direction = -1; 78214456Srpaulo } 79214456Srpaulo 80214456Srpaulo return direction; 81214456Srpaulo} 82214456Srpaulo 83214456Srpaulostatic void 84214456Srpaulousb_header_print(const pcap_usb_header *uh) 85214456Srpaulo{ 86214456Srpaulo int direction; 87214456Srpaulo 88214456Srpaulo switch(uh->transfer_type) 89214456Srpaulo { 90214456Srpaulo case URB_ISOCHRONOUS: 91214456Srpaulo printf("ISOCHRONOUS"); 92214456Srpaulo break; 93214456Srpaulo case URB_INTERRUPT: 94214456Srpaulo printf("INTERRUPT"); 95214456Srpaulo break; 96214456Srpaulo case URB_CONTROL: 97214456Srpaulo printf("CONTROL"); 98214456Srpaulo break; 99214456Srpaulo case URB_BULK: 100214456Srpaulo printf("BULK"); 101214456Srpaulo break; 102214456Srpaulo default: 103214456Srpaulo printf(" ?"); 104214456Srpaulo } 105214456Srpaulo 106214456Srpaulo switch(uh->event_type) 107214456Srpaulo { 108214456Srpaulo case URB_SUBMIT: 109214456Srpaulo printf(" SUBMIT"); 110214456Srpaulo break; 111214456Srpaulo case URB_COMPLETE: 112214456Srpaulo printf(" COMPLETE"); 113214456Srpaulo break; 114214456Srpaulo case URB_ERROR: 115214456Srpaulo printf(" ERROR"); 116214456Srpaulo break; 117214456Srpaulo default: 118214456Srpaulo printf(" ?"); 119214456Srpaulo } 120214456Srpaulo 121214456Srpaulo direction = get_direction(uh->transfer_type, uh->event_type); 122214456Srpaulo if(direction == 1) 123214456Srpaulo printf(" from"); 124214456Srpaulo else if(direction == 2) 125214456Srpaulo printf(" to"); 126214456Srpaulo printf(" %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f); 127214456Srpaulo} 128214456Srpaulo 129214456Srpaulo/* 130214456Srpaulo * This is the top level routine of the printer for captures with a 131214456Srpaulo * 48-byte header. 132214456Srpaulo * 133214456Srpaulo * 'p' points to the header of the packet, 'h->ts' is the timestamp, 134214456Srpaulo * 'h->len' is the length of the packet off the wire, and 'h->caplen' 135214456Srpaulo * is the number of bytes actually captured. 136214456Srpaulo */ 137214456Srpaulou_int 138214456Srpaulousb_linux_48_byte_print(const struct pcap_pkthdr *h, register const u_char *p) 139214456Srpaulo{ 140214456Srpaulo if (h->caplen < sizeof(pcap_usb_header)) { 141214456Srpaulo printf("[|usb]"); 142214456Srpaulo return(sizeof(pcap_usb_header)); 143214456Srpaulo } 144214456Srpaulo 145214456Srpaulo usb_header_print((const pcap_usb_header *) p); 146214456Srpaulo 147214456Srpaulo return(sizeof(pcap_usb_header)); 148214456Srpaulo} 149214456Srpaulo 150214456Srpaulo#ifdef DLT_USB_LINUX_MMAPPED 151214456Srpaulo/* 152214456Srpaulo * This is the top level routine of the printer for captures with a 153214456Srpaulo * 64-byte header. 154214456Srpaulo * 155214456Srpaulo * 'p' points to the header of the packet, 'h->ts' is the timestamp, 156214456Srpaulo * 'h->len' is the length of the packet off the wire, and 'h->caplen' 157214456Srpaulo * is the number of bytes actually captured. 158214456Srpaulo */ 159214456Srpaulou_int 160214456Srpaulousb_linux_64_byte_print(const struct pcap_pkthdr *h, register const u_char *p) 161214456Srpaulo{ 162214456Srpaulo if (h->caplen < sizeof(pcap_usb_header_mmapped)) { 163214456Srpaulo printf("[|usb]"); 164214456Srpaulo return(sizeof(pcap_usb_header_mmapped)); 165214456Srpaulo } 166214456Srpaulo 167214456Srpaulo usb_header_print((const pcap_usb_header *) p); 168214456Srpaulo 169214456Srpaulo return(sizeof(pcap_usb_header_mmapped)); 170214456Srpaulo} 171214456Srpaulo#endif /* DLT_USB_LINUX_MMAPPED */ 172214456Srpaulo 173214456Srpaulo#endif /* defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) */ 174214456Srpaulo 175