Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / include / eth.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: eth.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23/*
24 * "eth.h"
25 *
26 * structs & functions to access ethernet packet fields...
27 *
28 * Note, for when ip.verlen = 0x45, ie standard 5-word (20-uchar) ip-header,
29 * and when tcp.?? = ??, ie standard 20-uchar tcp header:
30 *
31 * min eth-pkt = 64 uchars
32 * -14 (eth-header)
33 * -4 (eth-tailer CRC) = 46 min eth-data
34 * -20 (ip-header) = 26 min padding for "empty" ip-pkt
35 * -20 (tcp-header) = 6 min padding for "empty" tcp-pkt
36 *
37 * max eth-pkt = 1518 uchars
38 * - 14 (eth-header)
39 * - 4 (eth-trailer CRC) = 1500 max eth-data-MTU
40 * - 20 (ip-header) = 1480 max ip-data-MTU
41 * - 20 (tcp-header) = 1460 max tcp-data-MTU
42 *
43 *
44 * all of the "word" sized fields are UN-aligned, Argh!!!...
45 *
46 * @@@ Danger Will Robinson, Danger:
47 * -1 and -2 seem to be valid ip addresses ???
48 */
49#ifndef _ETH_H
50#define _ETH_H
51
52typedef unsigned char uchar;
53typedef unsigned short ushort;
54typedef unsigned int uword;
55
56
57#define ETH_MAX 1518 /* the whole thing, including header and CRC */
58#define ETH_BUF_MAX 1514 /* without the CRC */
59#define ETH_DATA_MAX 1500 /* without the CRC or the header, aka `MTU' */
60
61#define ETHHDRSZ 14 /* ethernet packet header size */
62
63#define ETH_MIN 64 /* the whole thing, including header and CRC */
64
65#define IP_DATA_MAX 1480 /* eth minus the 20-uchar ip header */
66#define TCP_DATA_MAX 1460 /* ip minus the 20-uchar tcp header */
67
68
69/* Ethernet Types */
70#define ET_IPv4 0x0800
71#define ET_ARP 0x0806
72#define ET_RARP 0x0835
73
74
75/* (some) IP Types */
76#define IP_ICMP 0x01 /* Inet Control Message Prot <--- */
77#define IP_IGMP 0x02 /* Inet Gateway Message Prot <--- */
78#define IP_GGP 0x03 /* Gateway-to-Gateway Prot */
79#define IP_IP 0x04 /* IP-in-IP-encapsulation Prot */
80#define IP_ST 0x05 /* Stream Prot */
81#define IP_TCP 0x06 /* Transmission Control Prot <--- */
82#define IP_EGP 0x08 /* Exterior-Gateway Prot */
83#define IP_IGP 0x09 /* Interior-Gateway Prot */
84#define IP_UDP 0x11 /* User Datagram Prot <--- */
85
86/* (some) ICMP message Types */
87#define ICMP_ECHOREPLY 0
88#define ICMP_UNREACHABLE 3
89#define ICMP_SRCQUENCH 4
90#define ICMP_REDIRECT 5
91#define ICMP_ECHO 8
92#define ICMP_ROUTERREPLY 9
93#define ICMP_ROUTERREQST 10
94#define ICMP_TIMEOUT 11
95#define ICMP_INVARG 12
96#define ICMP_TIMESTAMP 13
97#define ICMP_TSTAMPREPLY 14
98#define ICMP_INFO 15
99#define ICMP_INFOREPLY 16
100#define ICMP_MASK 17
101#define ICMP_MASKREPLY 18
102#define ICMP_DOMNAMREQST 37
103#define ICMP_DOMNAMREPLY 38
104
105
106/* (a few) TCP Types */
107#define TCP_ECHO 7
108#define TCP_FTPDATA 20
109#define TCP_FTP 21
110#define TCP_SSH 22
111#define TCP_TELNET 23
112#define TCP_TIME 37
113#define TCP_DNS 53
114#define TCP_HTTP 80
115#define TCP_HTTPS 443
116#define TCP_SUNRPC 111
117#define TCP_LDAP 389
118#define TCP_REXEC 512
119#define TCP_RLOGIN 513
120#define TCP_RSHELL 514
121
122
123
124
125typedef struct {
126 uchar dstMAC[6]; /* all 1's for a broadcast Request 0*/
127 uchar srcMAC[6]; /* 3*/
128 ushort frametype; /* 0x0800 => ET_IPv4 6*/
129 /* 0x0806 => ARP, 0x0835 => RARP */
130 union {
131
132 char eth_data[ ETH_DATA_MAX ];
133
134 struct arp_s {
135 ushort hardtype; /* 1 => Ethernet 7*/
136 ushort prottype; /* 0x0800 => IP 8*/
137 uchar hardsize; /* 6, mac size 9*/
138 uchar protsize; /* 4, ip size */
139 ushort op; /* 1 => ARP, 2 => reply,
140 3 => RARP, 4 => reply 10*/
141 /* ARP-Request ARP-Reply */
142 uchar srcMAC[6]; /* requestor -----> replyor 11*/
143 uchar srcIP[4]; /* requestor / ----> replyor 14*/
144 uchar dstMAC[6]; /* <empty>----- / 16*/
145 uchar dstIP[4]; /* specified----- 19*/
146 } arp;
147
148 struct ip_s {
149 uchar verlen; /* 0x45 -> IPv4 and std 5-word header */
150 uchar TofS;
151 ushort iplen; /* ipheader + ipdata, NOT incl eth hdr*/
152 ushort ident;
153 ushort flags;
154 uchar time_to_live;
155 uchar protocol; /* 0x06=>TCP, 0x11=>UDP, 0x01=> ICMP */
156 ushort hdrchecksum;
157 uchar srcIP[4]; /* 13*/
158 uchar dstIP[4]; /* 15*/
159
160 union {
161
162 char ip_data [ IP_DATA_MAX ];
163
164 struct icmp_s {
165 char type;
166 char code;
167 ushort chksum;
168 } icmp;
169
170 struct udp_s {
171 ushort srcPORT;
172 ushort dstPORT;
173 ushort udplen;
174 ushort checksum;
175 } udp;
176
177 struct tcp_s {
178 ushort srcPORT; /* 17*/
179 ushort dstPORT; /* 18*/
180 uchar SeqNum[4];
181 uchar AckNum[4];
182 ushort flags;
183 ushort win_size;
184 ushort checksum;
185 ushort UrgentPtr;
186
187 uchar data[6]; /*min padding for "empty" pkt*/
188 } tcp;
189
190 } u;
191
192 } ip;
193
194 } u;
195
196 char CRC[4];
197 char guard[120]; /* protect from buffer overflow... */
198} ethpacket_t;
199
200
201 /* short*/
202typedef struct { /*offset*/
203 uchar dstMAC[6];
204 uchar srcMAC[6];
205 ushort frametype; /* 0x0800 -> ET_IPv4 6*/
206 struct {
207 uchar verlen; /* 0x45 -> std IP hdr 7*/
208 uchar TofS;
209 ushort iplen; /* 20 for empty data packet */
210 ushort ident;
211 ushort flags;
212 uchar time_to_live;
213 uchar protocol; /* 0xff -> netsim connect packet 11*/
214 ushort hdrchecksum;
215 uchar srcIP[4]; /* 13*/
216 uchar dstIP[4]; /* 15*/
217 } ip;
218} netsim_connect_packet;
219
220
221
222
223inline uint16_t eth_short (uchar * x)
224 { return ((unsigned short*)(x))[0]; }
225
226inline uint32_t eth_int (uchar * x)
227 { return (((unsigned short*)(x))[0])<<16
228 | (((unsigned short*)(x))[1]); }
229
230inline uint64_t eth_long (uchar * x)
231 { return ((uint64_t)(((unsigned short*)(x))[0])<<32)
232 | ((uint64_t)(((unsigned short*)(x))[1])<<16)
233 | (uint64_t)(((unsigned short*)(x))[2]); }
234
235
236inline bool eth_isbroadcast(ethpacket_t * x)
237 { return eth_short (&x->dstMAC[0]) == 0xffff
238 && eth_short (&x->dstMAC[2]) == 0xffff
239 && eth_short (&x->dstMAC[4]) == 0xffff; }
240
241
242inline int eth_length (ethpacket_t * x)
243 {
244 if (x->frametype == ET_ARP) return 42;
245 else if (x->frametype == ET_IPv4)
246 return ETHHDRSZ + x->u.ip.iplen;
247 else return 0; /* ??? */
248 }
249
250
251inline unsigned short eth_type (ethpacket_t * x) /* arp, ipv4, ... */
252 { return x->frametype; }
253
254inline unsigned short eth_arpop (ethpacket_t * x) /* reqest, reply, */
255 { return x->u.arp.op; }
256
257inline unsigned char eth_ipproto (ethpacket_t * x) /* tcp, upd, icmp,...*/
258 { return x->u.ip.protocol; }
259
260inline unsigned char eth_ipversion (ethpacket_t * x)
261 { return x->u.ip.verlen >> 4; }
262
263inline unsigned char eth_iphdrlen (ethpacket_t * x)
264 { return 4 * (x->u.ip.verlen & 0xf); }
265
266inline unsigned char eth_ipverlen (ethpacket_t * x)
267 { return x->u.ip.verlen; }
268
269inline unsigned char eth_icmptype (ethpacket_t * x)
270 { return x->u.ip.u.icmp.type; }
271
272inline unsigned char eth_icmpcode (ethpacket_t * x)
273 { return x->u.ip.u.icmp.code; }
274
275/*
276inline unsigned char eth_tcptype (ethpacket_t * x)
277 { return x->u.ip.u.tcp.protocol; }
278 * I think we have to look for "known" tcp port numbers... *
279*/
280
281inline bool eth_tcpzlenack (ethpacket_t * x)
282 { return (x->frametype == ET_IPv4)
283 && (x->u.ip.iplen == 40)
284 && (x->u.ip.protocol == IP_TCP)
285 && (x->u.ip.u.tcp.flags & 0x10); }
286
287
288
289 /* fetch MAC addresses */
290inline uint64_t eth_srcMAC(ethpacket_t * x)
291 { return eth_long (x->srcMAC); }
292inline uint64_t eth_dstMAC(ethpacket_t * x)
293 { return eth_long (x->dstMAC); }
294
295inline void sprint_MACaddr (char * buf, uint64_t mac)
296{
297 sprintf (buf, "%02x:%02x:%02x:%02x:%02x:%02x", /* char buf[18] */
298 (int)(mac>>40)&0xff, (int)(mac>>32)&0xff, (int)(mac>>24)&0xff,
299 (int)(mac>>16)&0xff, (int)(mac>>8)&0xff, (int)(mac>>0)&0xff);
300}
301
302
303
304 /* fetch IP addresses */
305inline uint32_t eth_srcIP(ethpacket_t * x)
306{
307 if (eth_type (x) == ET_ARP) return eth_int (x->u.arp.srcIP);
308 else if (eth_type (x) == ET_IPv4)
309 return eth_int (x->u.ip.srcIP);
310 else return 0;
311}
312inline uint32_t eth_dstIP(ethpacket_t * x)
313{
314 if (eth_type (x) == ET_ARP) return eth_int (x->u.arp.dstIP);
315 else if (eth_type (x) == ET_IPv4)
316 return eth_int (x->u.ip.dstIP);
317 else return 0;
318}
319
320inline void sprint_IPaddr (char * buf, uint32_t ip) /* char buf[16] */
321{
322 sprintf (buf, "%d:%d:%d:%d",
323 (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, (ip>>0)&0xff);
324}
325
326inline uint32_t sscan_IPaddr (char * buf)
327{
328 unsigned int i1,i2,i3,i4;
329 if (sscanf (buf, "%d:%d:%d:%d", &i1, &i2, &i3, &i4) == 4) {
330 return (i1&0xff)<<24 | (i2&0xff)<<16 | (i3&0xff)<<8 | (i4&0xff)<<0;
331 } else
332 return 0xffffffff;
333}
334
335
336 /* fetch TCP addresses */
337inline uint32_t eth_srcPORT(ethpacket_t * x)
338{
339 if (eth_type (x) == ET_IPv4
340 && eth_ipverlen (x) == 0x45
341 && eth_ipproto (x) == IP_TCP)
342 return x->u.ip.u.tcp.srcPORT;
343 else
344 return -1;
345}
346inline uint32_t eth_dstPORT(ethpacket_t * x)
347{
348 if (eth_type (x) == ET_IPv4
349 && eth_ipverlen (x) == 0x45
350 && eth_ipproto (x) == IP_TCP)
351 return x->u.ip.u.tcp.dstPORT;
352 else
353 return -1;
354}
355
356
357#if 1
358
359const char * eth_tcp_string (int tcptype);
360
361const char * eth_icmp_string (int icmptype, int icmpcode);
362
363
364#else /*** see "netsim.cc" ***/
365
366char * eth_tcp_string (int tcptype)
367{
368 static char buf[10];
369
370 switch (tcptype) {
371 case TCP_ECHO: return "echo";
372 case TCP_FTPDATA: return "ftpdata";
373 case TCP_FTP: return "ftp";
374 case TCP_SSH: return "ssh";
375 case TCP_TELNET: return "telnet";
376 case TCP_TIME: return "time";
377 case TCP_DNS: return "dns";
378 case TCP_HTTP: return "http";
379 case TCP_HTTPS: return "https";
380 case TCP_SUNRPC: return "sunrpc";
381 case TCP_LDAP: return "ldap";
382 case TCP_REXEC: return "rexec";
383 case TCP_RLOGIN: return "rlogin";
384 case TCP_RSHELL: return "rshell";
385 default:
386 sprintf(&buf[0], "%d", tcptype);
387 return &buf[0];
388 }
389}
390
391char * eth_icmp_string (int icmptype, int icmpcode)
392{
393 static char buf[10];
394
395 switch (icmptype) {
396 case ICMP_ECHOREPLY: return "echo_reply";
397 case ICMP_UNREACHABLE:
398 switch (icmpcode) {
399 case 0: return "network_unreachable";
400 case 1: return "host_unreachable";
401 case 2: return "protocol_unreachable";
402 case 3: return "port_unreachable";
403 case 4: return "fragment_unreachable";
404 case 5: return "route_unreachable";
405 case 6: return "network_unknown";
406 case 7: return "host_unknown";
407 case 8: return "obsolete_unreachable";
408 case 9: return "network_prohibited";
409 case 10: return "host_prohibited";
410 case 11: return "network_tos_unreachable";
411 case 12: return "host_tos_unreachable";
412 default: return "unreachable_?";
413 }
414 case ICMP_SRCQUENCH: return "source_quench";
415 case ICMP_REDIRECT:
416 switch (icmpcode) {
417 case 0: return "redirect_network";
418 case 1: return "redirect_host";
419 case 2: return "redirect_tos_network";
420 case 3: return "redirect_tos_host";
421 default: return "redirect_?";
422 }
423 case ICMP_ECHO: return "echo_request";
424 case ICMP_ROUTERREPLY: return "router_reply";
425 case ICMP_ROUTERREQST: return "router_request";
426 case ICMP_TIMEOUT: return "time_exceeded";
427 case ICMP_INVARG: return "invalid_parameter";
428 case ICMP_TIMESTAMP: return "timestamp_request";
429 case ICMP_TSTAMPREPLY: return "timestamp_reply";
430 case ICMP_INFO: return "obsolete_request";
431 case ICMP_INFOREPLY: return "obsolete_reply";
432 case ICMP_MASK: return "mask_request";
433 case ICMP_MASKREPLY: return "mask_reply";
434 default:
435 sprintf(&buf[0], "%d", icmptype);
436 return &buf[0];
437 }
438}
439
440#endif
441
442
443#if 0 /*** see "netsim.cc"/netsim_dbgpacket() ***/
444void eth_print ()
445{
446 int et,ipt;
447 et = eth_type(&buffer.packet);
448 fprintf (stderr, "eth{%02x->%02x,%s",
449 eth_srcMAC(&buffer.packet) & 0xff,
450 eth_dstMAC(&buffer.packet) & 0xff,
451 (et == ET_IPv4 : "ip" ?
452 et == ET_ARP : "arp" ?
453 et == ET_RARP : "rarp" ? "?") );
454 switch (et) {
455 case ET_IPv4:
456 ipt = eth_ipproto(&buffer.packet);
457 fprintf (stderr, "{%d.%d->%d.%d,%s",
458 eth_srcIP(&buffer.packet) & 0xff,
459 eth_dstIP(&buffer.packet) & 0xff,
460 ipt);
461 break;
462 case ET_ARP:
463 fprintf (stderr, "{
464 break;
465 case ET_RARP:
466 break;
467 }
468 fprintf (stderr, "}\n");
469
470}
471#endif
472
473
474#endif /*_ETH_H*/