netlib.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,442 行 · 第 1/3 页

C
1,442
字号
/*++

Copyright (c) 2005 - 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  NetLib.c

Abstract:


--*/

#include "NetLib.h"

//
// All the supported IP4 maskes in host byte order.
//
IP4_ADDR  mIp4AllMasks[IP4_MASK_NUM] = {
  0x00000000,
  0x80000000,
  0xC0000000,
  0xE0000000,
  0xF0000000,
  0xF8000000,
  0xFC000000,
  0xFE000000,

  0xFF000000,
  0xFF800000,
  0xFFC00000,
  0xFFE00000,
  0xFFF00000,
  0xFFF80000,
  0xFFFC0000,
  0xFFFE0000,

  0xFFFF0000,
  0xFFFF8000,
  0xFFFFC000,
  0xFFFFE000,
  0xFFFFF000,
  0xFFFFF800,
  0xFFFFFC00,
  0xFFFFFE00,

  0xFFFFFF00,
  0xFFFFFF80,
  0xFFFFFFC0,
  0xFFFFFFE0,
  0xFFFFFFF0,
  0xFFFFFFF8,
  0xFFFFFFFC,
  0xFFFFFFFE,
  0xFFFFFFFF,
};

INTN
NetGetMaskLength (
  IN IP4_ADDR               NetMask
  )
/*++

Routine Description:

  Return the length of the mask. If the mask is invalid,
  return the invalid length 33, which is IP4_MASK_NUM.
  NetMask is in the host byte order.

Arguments:

  NetMask  - The netmask to get the length from

Returns:

  The length of the netmask, IP4_MASK_NUM if the mask isn't 
  supported.

--*/
{
  INTN                      Index;

  for (Index = 0; Index < IP4_MASK_NUM; Index++) {
    if (NetMask == mIp4AllMasks[Index]) {
      break;
    }
  }

  return Index;
}


INTN
NetGetIpClass (
  IN IP4_ADDR               Addr
  )
/*++

Routine Description:

  Return the class of the address, such as class a, b, c.
  Addr is in host byte order.

Arguments:

  Addr  - The address to get the class from

Returns:

  IP address class, such as IP4_ADDR_CLASSA

--*/
{
  UINT8                     ByteOne;

  ByteOne = (UINT8) (Addr >> 24);

  if ((ByteOne & 0x80) == 0) {
    return IP4_ADDR_CLASSA;

  } else if ((ByteOne & 0xC0) == 0x80) {
    return IP4_ADDR_CLASSB;

  } else if ((ByteOne & 0xE0) == 0xC0) {
    return IP4_ADDR_CLASSC;

  } else if ((ByteOne & 0xF0) == 0xE0) {
    return IP4_ADDR_CLASSD;

  } else {
    return IP4_ADDR_CLASSE;

  }
}

BOOLEAN
Ip4IsUnicast (
  IN IP4_ADDR               Ip,
  IN IP4_ADDR               NetMask
  )
/*++

Routine Description:

  Check whether the IP is a valid unicast address according to
  the netmask. If NetMask is zero, use the IP address's class to 
  get the default mask.

Arguments:

  Ip      - The IP to check againist
  NetMask - The mask of the IP

Returns:

  TRUE if IP is a valid unicast address on the network, otherwise FALSE

--*/
{
  INTN                      Class;

  Class = NetGetIpClass (Ip);

  if ((Ip == 0) || (Class >= IP4_ADDR_CLASSD)) {
    return FALSE;
  }

  if (NetMask == 0) {
    NetMask = mIp4AllMasks[Class << 3];
  }

  if (((Ip &~NetMask) == ~NetMask) || ((Ip &~NetMask) == 0)) {
    return FALSE;
  }

  return TRUE;
}

UINT32
NetRandomInitSeed (
  VOID
  )
/*++

Routine Description:

  Initialize a random seed using current time.

Arguments:

  None

Returns:

  The random seed initialized with current time.

--*/
{
  EFI_TIME                  Time;
  UINT32                    Seed;

  gRT->GetTime (&Time, NULL);
  Seed = (~Time.Hour << 24 | Time.Second << 16 | Time.Minute << 8 | Time.Day);
  Seed ^= Time.Nanosecond;
  Seed ^= Time.Year << 7;

  return Seed;
}

UINT32
NetGetUint32 (
  IN UINT8                  *Buf
  )
/*++

Routine Description:

  Extract a UINT32 from a byte stream, then convert it to host 
  byte order. Use this function to avoid alignment error.

Arguments:

  Buf - The buffer to extract the UINT32.

Returns:

  The UINT32 extracted.

--*/
{
  UINT32                    Value;
  
  NetCopyMem (&Value, Buf, sizeof (UINT32));
  return NTOHL (Value);
}

VOID
NetPutUint32 (
  IN UINT8                  *Buf,
  IN UINT32                 Data
  )
/*++

Routine Description:

  Put a UINT32 to the byte stream. Convert it from host byte order
  to network byte order before putting.

Arguments:

  Buf   - The buffer to put the UINT32
  Data  - The data to put

Returns:

  None

--*/
{
  Data = HTONL (Data);
  NetCopyMem (Buf, &Data, sizeof (UINT32));
}

NET_LIST_ENTRY *
NetListRemoveHead (
  NET_LIST_ENTRY            *Head
  )
/*++

Routine Description:

  Remove the first entry on the list
  
Arguments:

  Head  - The list header

Returns:

  The entry that is removed from the list, NULL if the list is empty.

--*/
{
  NET_LIST_ENTRY            *First;

  ASSERT (Head != NULL);

  if (NetListIsEmpty (Head)) {
    return NULL;
  }

  First                         = Head->ForwardLink;
  Head->ForwardLink             = First->ForwardLink;
  First->ForwardLink->BackLink  = Head;

  DEBUG_CODE (
    First->ForwardLink  = (EFI_LIST_ENTRY *) EFI_BAD_POINTER;
    First->BackLink     = (EFI_LIST_ENTRY *) EFI_BAD_POINTER;
  )

  return First;
}

NET_LIST_ENTRY *
NetListRemoveTail (
  NET_LIST_ENTRY            *Head
  )
/*++

Routine Description:

  Remove the last entry on the list

Arguments:

  Head  - The list head

Returns:

  The entry that is removed from the list, NULL if the list is empty.

--*/
{
  NET_LIST_ENTRY            *Last;

  ASSERT (Head != NULL);

  if (NetListIsEmpty (Head)) {
    return NULL;
  }

  Last                        = Head->BackLink;
  Head->BackLink              = Last->BackLink;
  Last->BackLink->ForwardLink = Head;

  DEBUG_CODE (
    Last->ForwardLink = (EFI_LIST_ENTRY *) EFI_BAD_POINTER;
    Last->BackLink    = (EFI_LIST_ENTRY *) EFI_BAD_POINTER;
  )

  return Last;
}

VOID
NetListInsertAfter (
  IN NET_LIST_ENTRY         *PrevEntry,
  IN NET_LIST_ENTRY         *NewEntry
  )
/*++

Routine Description:

  Insert the NewEntry after the PrevEntry

Arguments:

  PrevEntry - The previous entry to insert after
  NewEntry  - The new entry to insert

Returns:

  None

--*/
{
  NewEntry->BackLink                = PrevEntry;
  NewEntry->ForwardLink             = PrevEntry->ForwardLink;
  PrevEntry->ForwardLink->BackLink  = NewEntry;
  PrevEntry->ForwardLink            = NewEntry;
}

VOID
NetListInsertBefore (
  IN NET_LIST_ENTRY *PostEntry,
  IN NET_LIST_ENTRY *NewEntry
  )
/*++

Routine Description:

  Insert the NewEntry before the PostEntry

Arguments:

  PostEntry - The entry to insert before
  NewEntry  - The new entry to insert

Returns:

  None

--*/
{
  NewEntry->ForwardLink             = PostEntry;
  NewEntry->BackLink                = PostEntry->BackLink;
  PostEntry->BackLink->ForwardLink  = NewEntry;
  PostEntry->BackLink               = NewEntry;
}

VOID
NetMapInit (
  IN NET_MAP                *Map
  )
/*++

Routine Description:

  Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.

Arguments:

  Map - The netmap to initialize

Returns:

  None

--*/
{
  ASSERT (Map != NULL);

  NetListInit (&Map->Used);
  NetListInit (&Map->Recycled);
  Map->Count = 0;
}

VOID
NetMapClean (
  IN NET_MAP                *Map
  )
/*++

Routine Description:

  To clean up the netmap, that is, release allocated memories.

Arguments:

  Map - The netmap to clean up.

Returns:

  None

--*/
{
  NET_MAP_ITEM              *Item;
  NET_LIST_ENTRY            *Entry;
  NET_LIST_ENTRY            *Next;

  ASSERT (Map != NULL);

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Map->Used) {
    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);

    NetListRemoveEntry (&Item->Link);
    Map->Count--;

    NetFreePool (Item);
  }

  ASSERT ((Map->Count == 0) && NetListIsEmpty (&Map->Used));

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Map->Recycled) {
    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);

    NetListRemoveEntry (&Item->Link);
    NetFreePool (Item);
  }

  ASSERT (NetListIsEmpty (&Map->Recycled));
}

BOOLEAN

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?