// ---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // ---------------------------------------------------------------------------- /// // Microsoft Research, Cambridge // using NetStack.Common; using System; using System.Diagnostics; using System.Net.IP; using Drivers.Net; #if !SINGULARITY using System.Net; using System.Net.Sockets; // for AddressFamily using System.Text.RegularExpressions; using System.Runtime.InteropServices; #endif namespace NetStack.Protocols { // An ethernet frame format public class EthernetFormat { // Ethernet protocol types: public const ushort PROTOCOL_IP = 0x0800; public const ushort PROTOCOL_ARP = 0x0806; public const ushort PROTOCOL_RARP = 0x8035; public const ushort PROTOCOL_IP6 = 0x86dd; public const ushort PROTOCOL_PAUSE = 0x8808; // must be sent to 01-80-C2-00-00-01 public const ushort PROTOCOL_MAP = 0x4934; // unassigned according to http://map-ne.com/Ethernet/type.html public const ushort PROTOCOL_NLB = 0x886f; // Network Load Balancer - type allocated to Microsoft public const ushort PROTOCOL_LOOP = 0x0060; // Ethernet Loopback packet public const int MaxFrameSize = 1514; // YW: wo CRC (which is 4 bytes) public const int MinFrameSize = 60; public const int Size = 14; public class FrameHeader { EthernetAddress origin; EthernetAddress target; ushort protocol; public FrameHeader(EthernetAddress origin, EthernetAddress target, ushort protocol) { this.origin = origin; this.target = target; this.protocol = protocol; } public FrameHeader() { } } // parse "pkt" from "start" bytes in, and return the // "src" and "dst" Ethernet addresses, and the protocol // "type" Returns the byte offset of the next layer's // header. public static int Read(byte []! pkt, int start, out EthernetAddress src, out EthernetAddress dst, out ushort type) { dst = EthernetAddress.ParseBytes(pkt, start); src = EthernetAddress.ParseBytes(pkt, start+6); type = (ushort) ((pkt[start+12] << 8) | (pkt[start+13])); return start + 14; } public static bool Read(IBuffer! buf, out EthernetAddress src, out EthernetAddress dst, out ushort type) { bool b; b = buf.ReadEthernetAddress(out dst); b &= buf.ReadEthernetAddress(out src); b &= buf.ReadNet16(out type); return b; } // Write an Ethernet header to "pkt", starting at position "start". public static int Write(byte[]! pkt, int start, EthernetAddress src, EthernetAddress dst, ushort type) { dst.CopyOut(pkt, start); src.CopyOut(pkt, start + EthernetAddress.Length); pkt[start + 12] = (byte) (type >> 8); pkt[start + 13] = (byte) (type & 0xff); return start + 14; } public static bool IsEthernetProtocol(ushort id) { switch (id) { case PROTOCOL_IP: return true; case PROTOCOL_ARP: return true; case PROTOCOL_RARP: return true; case PROTOCOL_IP6: return true; case PROTOCOL_PAUSE: return true; case PROTOCOL_MAP: return true; case PROTOCOL_NLB: return true; case PROTOCOL_LOOP: return true; } return false; } } }