singrdk/base/Services/NetStack/Protocol/EtherFmt.cs

127 lines
4.4 KiB
C#

///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
/**
* Microsoft Research, Cambridge
* author: Yaron Weinsberg, Richard Black
*/
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;
}
}
}