Update copyright year on all source files.
[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 if (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE)
88 printf_P(PSTR(" + Protocol: 0x%04x\r\n"), SwapEndian_16(FrameHeader->EtherType));
89 else
90 printf_P(PSTR(" + Protocol: UNKNOWN E1\r\n"));
91 #endif
92 }
93
94 /** Decodes an ARP header and prints its contents to through the USART in a human readable format.
95 *
96 * \param[in] InDataStart Pointer to the start of an ARP packet header
97 */
98 void DecodeARPHeader(void* InDataStart)
99 {
100 #if !defined(NO_DECODE_ARP)
101 ARP_Header_t* ARPHeader = (ARP_Header_t*)InDataStart;
102
103 printf_P(PSTR(" \\\r\n ARP\r\n"));
104
105 if (!(IP_COMPARE(&ARPHeader->TPA, &ServerIPAddress)) &&
106 !(MAC_COMPARE(&ARPHeader->THA, &ServerMACAddress)))
107 {
108 printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
109 return;
110 }
111
112 printf_P(PSTR(" + Protocol: %x\r\n"), SwapEndian_16(ARPHeader->ProtocolType));
113 printf_P(PSTR(" + Operation: %u\r\n"), SwapEndian_16(ARPHeader->Operation));
114
115 if (SwapEndian_16(ARPHeader->ProtocolType) == ETHERTYPE_IPV4)
116 {
117 printf_P(PSTR(" + SHA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->SHA.Octets[0],
118 ARPHeader->SHA.Octets[1],
119 ARPHeader->SHA.Octets[2],
120 ARPHeader->SHA.Octets[3],
121 ARPHeader->SHA.Octets[4],
122 ARPHeader->SHA.Octets[5]);
123
124 printf_P(PSTR(" + SPA IP: %u.%u.%u.%u\r\n"), ARPHeader->SPA.Octets[0],
125 ARPHeader->SPA.Octets[1],
126 ARPHeader->SPA.Octets[2],
127 ARPHeader->SPA.Octets[3]);
128
129 printf_P(PSTR(" + THA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->THA.Octets[0],
130 ARPHeader->THA.Octets[1],
131 ARPHeader->THA.Octets[2],
132 ARPHeader->THA.Octets[3],
133 ARPHeader->THA.Octets[4],
134 ARPHeader->THA.Octets[5]);
135
136 printf_P(PSTR(" + TPA IP: %u.%u.%u.%u\r\n"), ARPHeader->TPA.Octets[0],
137 ARPHeader->TPA.Octets[1],
138 ARPHeader->TPA.Octets[2],
139 ARPHeader->TPA.Octets[3]);
140 }
141 #endif
142 }
143
144 /** Decodes an IP header and prints its contents to through the USART in a human readable format.
145 *
146 * \param[in] InDataStart Pointer to the start of an IP packet header
147 */
148 void DecodeIPHeader(void* InDataStart)
149 {
150 #if !defined(NO_DECODE_IP)
151 IP_Header_t* IPHeader = (IP_Header_t*)InDataStart;
152
153 uint16_t HeaderLengthBytes = (IPHeader->HeaderLength * sizeof(uint32_t));
154
155 printf_P(PSTR(" \\\r\n IP\r\n"));
156
157 if (!(IP_COMPARE(&IPHeader->DestinationAddress, &ServerIPAddress)))
158 {
159 printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
160 return;
161 }
162
163 printf_P(PSTR(" + Header Length: %u Bytes\r\n"), HeaderLengthBytes);
164 printf_P(PSTR(" + Packet Version: %u\r\n"), IPHeader->Version);
165 printf_P(PSTR(" + Total Length: %u\r\n"), SwapEndian_16(IPHeader->TotalLength));
166
167 printf_P(PSTR(" + Protocol: %u\r\n"), IPHeader->Protocol);
168 printf_P(PSTR(" + TTL: %u\r\n"), IPHeader->TTL);
169
170 printf_P(PSTR(" + IP Src: %u.%u.%u.%u\r\n"), IPHeader->SourceAddress.Octets[0],
171 IPHeader->SourceAddress.Octets[1],
172 IPHeader->SourceAddress.Octets[2],
173 IPHeader->SourceAddress.Octets[3]);
174
175 printf_P(PSTR(" + IP Dst: %u.%u.%u.%u\r\n"), IPHeader->DestinationAddress.Octets[0],
176 IPHeader->DestinationAddress.Octets[1],
177 IPHeader->DestinationAddress.Octets[2],
178 IPHeader->DestinationAddress.Octets[3]);
179 #endif
180 }
181
182 /** Decodes an ICMP header and prints its contents to through the USART in a human readable format.
183 *
184 * \param[in] InDataStart Pointer to the start of an ICMP packet header
185 */
186 void DecodeICMPHeader(void* InDataStart)
187 {
188 #if !defined(NO_DECODE_ICMP)
189 ICMP_Header_t* ICMPHeader = (ICMP_Header_t*)InDataStart;
190
191 printf_P(PSTR(" \\\r\n ICMP\r\n"));
192
193 printf_P(PSTR(" + Type: %u\r\n"), ICMPHeader->Type);
194 printf_P(PSTR(" + Code: %u\r\n"), ICMPHeader->Code);
195 #endif
196 }
197
198 /** Decodes a TCP header and prints its contents to through the USART in a human readable format.
199 *
200 * \param[in] InDataStart Pointer to the start of a TCP packet header
201 */
202 void DecodeTCPHeader(void* InDataStart)
203 {
204 #if !defined(NO_DECODE_TCP)
205 TCP_Header_t* TCPHeader = (TCP_Header_t*)InDataStart;
206
207 uint16_t HeaderLengthBytes = (TCPHeader->DataOffset * sizeof(uint32_t));
208
209 printf_P(PSTR(" \\\r\n TCP\r\n"));
210
211 printf_P(PSTR(" + Header Length: %u Bytes\r\n"), HeaderLengthBytes);
212
213 printf_P(PSTR(" + Source Port: %u\r\n"), SwapEndian_16(TCPHeader->SourcePort));
214 printf_P(PSTR(" + Destination Port: %u\r\n"), SwapEndian_16(TCPHeader->DestinationPort));
215
216 printf_P(PSTR(" + Sequence Number: %lu\r\n"), SwapEndian_32(TCPHeader->SequenceNumber));
217 printf_P(PSTR(" + Acknowledgment Number: %lu\r\n"), SwapEndian_32(TCPHeader->AcknowledgmentNumber));
218
219 printf_P(PSTR(" + Flags: 0x%02X\r\n"), TCPHeader->Flags);
220
221 if (TCP_GetPortState(TCPHeader->DestinationPort) == TCP_Port_Closed)
222 printf_P(PSTR(" + NOT LISTENING ON DESTINATION PORT\r\n"));
223 #endif
224 }
225
226 /** Decodes an UDP header and prints its contents to through the USART in a human readable format.
227 *
228 * \param[in] InDataStart Pointer to the start of a UDP packet header
229 */
230 void DecodeUDPHeader(void* InDataStart)
231 {
232 #if !defined(NO_DECODE_UDP)
233 UDP_Header_t* UDPHeader = (UDP_Header_t*)InDataStart;
234
235 printf_P(PSTR(" \\\r\n UDP\r\n"));
236
237 printf_P(PSTR(" + Source Port: %u\r\n"), SwapEndian_16(UDPHeader->SourcePort));
238 printf_P(PSTR(" + Destination Port: %u\r\n"), SwapEndian_16(UDPHeader->DestinationPort));
239
240 printf_P(PSTR(" + Data Length: %d\r\n"), SwapEndian_16(UDPHeader->Length));
241 #endif
242 }
243
244 /** Decodes an DHCP header and prints its contents to through the USART in a human readable format.
245 *
246 * \param[in] InDataStart Pointer to the start of a DHCP packet header
247 */
248 void DecodeDHCPHeader(void* InDataStart)
249 {
250 #if !defined(NO_DECODE_DHCP)
251 uint8_t* DHCPOptions = (InDataStart + sizeof(DHCP_Header_t));
252
253 printf_P(PSTR(" \\\r\n DHCP\r\n"));
254
255 while (DHCPOptions[0] != DHCP_OPTION_END)
256 {
257 if (DHCPOptions[0] == DHCP_OPTION_MESSAGETYPE)
258 {
259 switch (DHCPOptions[2])
260 {
261 case DHCP_MESSAGETYPE_DISCOVER:
262 printf_P(PSTR(" + DISCOVER\r\n"));
263 break;
264 case DHCP_MESSAGETYPE_REQUEST:
265 printf_P(PSTR(" + REQUEST\r\n"));
266 break;
267 case DHCP_MESSAGETYPE_RELEASE:
268 printf_P(PSTR(" + RELEASE\r\n"));
269 break;
270 case DHCP_MESSAGETYPE_DECLINE:
271 printf_P(PSTR(" + DECLINE\r\n"));
272 break;
273 }
274 }
275
276 DHCPOptions += ((DHCPOptions[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptions[1] + 2));
277 }
278 #endif
279 }
280