127 lines
4.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|