More endianness porting of the LUFA device mode class drivers.
[pub/USBasp.git] / Demos / Device / LowLevel / RNDISEthernet / Lib / ProtocolDecoders.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2011.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7 */
8
9 /*
10 Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 /* Protocol decoders for Ethernet, TCP, IP, ICMP and ARP. Each of these routines
32 accepts a header to the appropriate protocol and prints out pertinent information
33 on the packet through the serial port.
34
35 To disable printing of a specific protocol, define the token NO_DECODE_{Protocol}
36 in the project makefile, and pass it to the compiler using the -D switch.
37 */
38
39 /** \file
40 *
41 * Protocol decoding routines, for the plain-text decoding of Ethernet frames for debugging purposes.
42 * Enabled protocol decoders will print incoming Ethernet frame contents through the USART in a human
43 * readable format.
44 *
45 * Note that the USART is a slow transmission medium, and will slow down packet processing considerably.
46 * Packet decoding routines can be disabled by defining NO_DECODE_{Protocol Name} in the project makefile
47 * and passing it to the compiler via the -D switch.
48 */
49
50 #include "ProtocolDecoders.h"
51
52 /** Decodes an Ethernet frame header and prints its contents to through the USART in a human readable format.
53 *
54 * \param[in] InDataStart Pointer to the start of an Ethernet frame header
55 */
56 void DecodeEthernetFrameHeader(void* InDataStart)
57 {
58 #if !defined(NO_DECODE_ETHERNET)
59 Ethernet_Frame_Header_t* FrameHeader = (Ethernet_Frame_Header_t*)InDataStart;
60
61 printf_P(PSTR("\r\n"));
62
63 printf_P(PSTR(" ETHERNET\r\n"));
64 printf_P(PSTR(" + Frame Size: %u\r\n"), FrameIN.FrameLength);
65
66 if (!(MAC_COMPARE(&FrameHeader->Destination, &ServerMACAddress)) &&
67 !(MAC_COMPARE(&FrameHeader->Destination, &BroadcastMACAddress)))
68 {
69 printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
70 return;
71 }
72
73 printf_P(PSTR(" + MAC Source : %02X:%02X:%02X:%02X:%02X:%02X\r\n"), FrameHeader->Source.Octets[0],
74 FrameHeader->Source.Octets[1],
75 FrameHeader->Source.Octets[2],
76 FrameHeader->Source.Octets[3],
77 FrameHeader->Source.Octets[4],
78 FrameHeader->Source.Octets[5]);
79
80 printf_P(PSTR(" + MAC Dest: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), FrameHeader->Destination.Octets[0],
81 FrameHeader->Destination.Octets[1],
82 FrameHeader->Destination.Octets[2],
83 FrameHeader->Destination.Octets[3],
84 FrameHeader->Destination.Octets[4],
85 FrameHeader->Destination.Octets[5]);
86
87 printf_P(PSTR(" + Protocol: 0x%04x\r\n"), SwapEndian_16(FrameHeader->EtherType));
88 #endif
89 }
90
91 /** Decodes an ARP header and prints its contents to through the USART in a human readable format.
92 *
93 * \param[in] InDataStart Pointer to the start of an ARP packet header
94 */
95 void DecodeARPHeader(void* InDataStart)
96 {
97 #if !defined(NO_DECODE_ARP)
98 ARP_Header_t* ARPHeader = (ARP_Header_t*)InDataStart;
99
100 printf_P(PSTR(" \\\r\n ARP\r\n"));
101
102 if (!(IP_COMPARE(&ARPHeader->TPA, &ServerIPAddress)) &&
103 !(MAC_COMPARE(&ARPHeader->THA, &ServerMACAddress)))
104 {
105 printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
106 return;
107 }
108
109 printf_P(PSTR(" + Protocol: %x\r\n"), SwapEndian_16(ARPHeader->ProtocolType));
110 printf_P(PSTR(" + Operation: %u\r\n"), SwapEndian_16(ARPHeader->Operation));
111
112 if (SwapEndian_16(ARPHeader->ProtocolType) == ETHERTYPE_IPV4)
113 {
114 printf_P(PSTR(" + SHA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->SHA.Octets[0],
115 ARPHeader->SHA.Octets[1],
116 ARPHeader->SHA.Octets[2],
117 ARPHeader->SHA.Octets[3],
118 ARPHeader->SHA.Octets[4],
119 ARPHeader->SHA.Octets[5]);
120
121 printf_P(PSTR(" + SPA IP: %u.%u.%u.%u\r\n"), ARPHeader->SPA.Octets[0],
122 ARPHeader->SPA.Octets[1],
123 ARPHeader->SPA.Octets[2],
124 ARPHeader->SPA.Octets[3]);
125
126 printf_P(PSTR(" + THA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->THA.Octets[0],
127 ARPHeader->THA.Octets[1],
128 ARPHeader->THA.Octets[2],
129 ARPHeader->THA.Octets[3],
130 ARPHeader->THA.Octets[4],
131 ARPHeader->THA.Octets[5]);
132
133 printf_P(PSTR(" + TPA IP: %u.%u.%u.%u\r\n"), ARPHeader->TPA.Octets[0],
134 ARPHeader->TPA.Octets[1],
135 ARPHeader->TPA.Octets[2],
136 ARPHeader->TPA.Octets[3]);
137 }
138 #endif
139 }
140
141 /** Decodes an IP header and prints its contents to through the USART in a human readable format.
142 *
143 * \param[in] InDataStart Pointer to the start of an IP packet header
144 */
145 void DecodeIPHeader(void* InDataStart)
146 {
147 #if !defined(NO_DECODE_IP)
148 IP_Header_t* IPHeader = (IP_Header_t*)InDataStart;
149
150 uint16_t HeaderLengthBytes = (IPHeader->HeaderLength * sizeof(uint32_t));
151
152 printf_P(PSTR(" \\\r\n IP\r\n"));
153
154 if (!(IP_COMPARE(&IPHeader->DestinationAddress, &ServerIPAddress)))
155 {
156 printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
157 return;
158 }
159
160 printf_P(PSTR(" + Header Length: %u Bytes\r\n"), HeaderLengthBytes);
161 printf_P(PSTR(" + Packet Version: %u\r\n"), IPHeader->Version);
162 printf_P(PSTR(" + Total Length: %u\r\n"), SwapEndian_16(IPHeader->TotalLength));
163
164 printf_P(PSTR(" + Protocol: %u\r\n"), IPHeader->Protocol);
165 printf_P(PSTR(" + TTL: %u\r\n"), IPHeader->TTL);
166
167 printf_P(PSTR(" + IP Src: %u.%u.%u.%u\r\n"), IPHeader->SourceAddress.Octets[0],
168 IPHeader->SourceAddress.Octets[1],
169 IPHeader->SourceAddress.Octets[2],
170 IPHeader->SourceAddress.Octets[3]);
171
172 printf_P(PSTR(" + IP Dst: %u.%u.%u.%u\r\n"), IPHeader->DestinationAddress.Octets[0],
173 IPHeader->DestinationAddress.Octets[1],
174 IPHeader->DestinationAddress.Octets[2],
175 IPHeader->DestinationAddress.Octets[3]);
176 #endif
177 }
178
179 /** Decodes an ICMP header and prints its contents to through the USART in a human readable format.
180 *
181 * \param[in] InDataStart Pointer to the start of an ICMP packet header
182 */
183 void DecodeICMPHeader(void* InDataStart)
184 {
185 #if !defined(NO_DECODE_ICMP)
186 ICMP_Header_t* ICMPHeader = (ICMP_Header_t*)InDataStart;
187
188 printf_P(PSTR(" \\\r\n ICMP\r\n"));
189
190 printf_P(PSTR(" + Type: %u\r\n"), ICMPHeader->Type);
191 printf_P(PSTR(" + Code: %u\r\n"), ICMPHeader->Code);
192 #endif
193 }
194
195 /** Decodes a TCP header and prints its contents to through the USART in a human readable format.
196 *
197 * \param[in] InDataStart Pointer to the start of a TCP packet header
198 */
199 void DecodeTCPHeader(void* InDataStart)
200 {
201 #if !defined(NO_DECODE_TCP)
202 TCP_Header_t* TCPHeader = (TCP_Header_t*)InDataStart;
203
204 uint16_t HeaderLengthBytes = (TCPHeader->DataOffset * sizeof(uint32_t));
205
206 printf_P(PSTR(" \\\r\n TCP\r\n"));
207
208 printf_P(PSTR(" + Header Length: %u Bytes\r\n"), HeaderLengthBytes);
209
210 printf_P(PSTR(" + Source Port: %u\r\n"), SwapEndian_16(TCPHeader->SourcePort));
211 printf_P(PSTR(" + Destination Port: %u\r\n"), SwapEndian_16(TCPHeader->DestinationPort));
212
213 printf_P(PSTR(" + Sequence Number: %lu\r\n"), SwapEndian_32(TCPHeader->SequenceNumber));
214 printf_P(PSTR(" + Acknowledgment Number: %lu\r\n"), SwapEndian_32(TCPHeader->AcknowledgmentNumber));
215
216 printf_P(PSTR(" + Flags: 0x%02X\r\n"), TCPHeader->Flags);
217
218 if (TCP_GetPortState(TCPHeader->DestinationPort) == TCP_Port_Closed)
219 printf_P(PSTR(" + NOT LISTENING ON DESTINATION PORT\r\n"));
220 #endif
221 }
222
223 /** Decodes an UDP header and prints its contents to through the USART in a human readable format.
224 *
225 * \param[in] InDataStart Pointer to the start of a UDP packet header
226 */
227 void DecodeUDPHeader(void* InDataStart)
228 {
229 #if !defined(NO_DECODE_UDP)
230 UDP_Header_t* UDPHeader = (UDP_Header_t*)InDataStart;
231
232 printf_P(PSTR(" \\\r\n UDP\r\n"));
233
234 printf_P(PSTR(" + Source Port: %u\r\n"), SwapEndian_16(UDPHeader->SourcePort));
235 printf_P(PSTR(" + Destination Port: %u\r\n"), SwapEndian_16(UDPHeader->DestinationPort));
236
237 printf_P(PSTR(" + Data Length: %d\r\n"), SwapEndian_16(UDPHeader->Length));
238 #endif
239 }
240
241 /** Decodes an DHCP header and prints its contents to through the USART in a human readable format.
242 *
243 * \param[in] InDataStart Pointer to the start of a DHCP packet header
244 */
245 void DecodeDHCPHeader(void* InDataStart)
246 {
247 #if !defined(NO_DECODE_DHCP)
248 uint8_t* DHCPOptions = (InDataStart + sizeof(DHCP_Header_t));
249
250 printf_P(PSTR(" \\\r\n DHCP\r\n"));
251
252 while (DHCPOptions[0] != DHCP_OPTION_END)
253 {
254 if (DHCPOptions[0] == DHCP_OPTION_MESSAGETYPE)
255 {
256 switch (DHCPOptions[2])
257 {
258 case DHCP_MESSAGETYPE_DISCOVER:
259 printf_P(PSTR(" + DISCOVER\r\n"));
260 break;
261 case DHCP_MESSAGETYPE_REQUEST:
262 printf_P(PSTR(" + REQUEST\r\n"));
263 break;
264 case DHCP_MESSAGETYPE_RELEASE:
265 printf_P(PSTR(" + RELEASE\r\n"));
266 break;
267 case DHCP_MESSAGETYPE_DECLINE:
268 printf_P(PSTR(" + DECLINE\r\n"));
269 break;
270 }
271 }
272
273 DHCPOptions += ((DHCPOptions[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptions[1] + 2));
274 }
275 #endif
276 }
277