win-pvdrivers

changeset 246:402fb735ce45

oops. forgot to add xennet_common.c
author James Harper <james.harper@bendigoit.com.au>
date Sat Apr 05 14:34:28 2008 +1100 (2008-04-05)
parents 1b1f26917b6f
children 565483912dc0
files xennet/xennet_common.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xennet/xennet_common.c	Sat Apr 05 14:34:28 2008 +1100
     1.3 @@ -0,0 +1,136 @@
     1.4 +/*
     1.5 +PV Net Driver for Windows Xen HVM Domains
     1.6 +Copyright (C) 2007 James Harper
     1.7 +Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     1.8 +
     1.9 +This program is free software; you can redistribute it and/or
    1.10 +modify it under the terms of the GNU General Public License
    1.11 +as published by the Free Software Foundation; either version 2
    1.12 +of the License, or (at your option) any later version.
    1.13 +
    1.14 +This program is distributed in the hope that it will be useful,
    1.15 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.17 +GNU General Public License for more details.
    1.18 +
    1.19 +You should have received a copy of the GNU General Public License
    1.20 +along with this program; if not, write to the Free Software
    1.21 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    1.22 +*/
    1.23 +
    1.24 +#include "xennet.h"
    1.25 +
    1.26 +ULONG
    1.27 +XenNet_ParsePacketHeader(
    1.28 +  packet_info_t *pi
    1.29 +)
    1.30 +{
    1.31 +  UINT header_length;
    1.32 +
    1.33 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    1.34 +
    1.35 +  ASSERT(pi->mdls[0]);
    1.36 +  
    1.37 +  NdisQueryBufferSafe(pi->mdls[0], &pi->header, &header_length, NormalPagePriority);
    1.38 +
    1.39 +  if (header_length < XN_HDR_SIZE + 20 + 20) // minimum size of first buffer is ETH + IP + TCP header
    1.40 +  {
    1.41 +    return PARSE_TOO_SMALL;
    1.42 +  }
    1.43 +  
    1.44 +  switch (GET_NET_USHORT(pi->header[12])) // L2 protocol field
    1.45 +  {
    1.46 +  case 0x0800:
    1.47 +    pi->ip_version = (pi->header[XN_HDR_SIZE + 0] & 0xF0) >> 4;
    1.48 +    if (pi->ip_version != 4)
    1.49 +    {
    1.50 +      KdPrint((__DRIVER_NAME "     ip_version = %d\n", pi->ip_version));
    1.51 +      return PARSE_UNKNOWN_TYPE;
    1.52 +    }
    1.53 +    pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
    1.54 +    if (header_length < (ULONG)(pi->ip4_header_length + 20))
    1.55 +    {
    1.56 +      KdPrint((__DRIVER_NAME "     first packet is only %d long, must be >= %d\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)));
    1.57 +      // we need to do something conclusive here...
    1.58 +      return PARSE_TOO_SMALL;
    1.59 +    }
    1.60 +    break;
    1.61 +  default:
    1.62 +//    KdPrint((__DRIVER_NAME "     Not IP\n"));
    1.63 +    return PARSE_UNKNOWN_TYPE;
    1.64 +  }
    1.65 +  pi->ip_proto = pi->header[XN_HDR_SIZE + 9];
    1.66 +  switch (pi->ip_proto)
    1.67 +  {
    1.68 +  case 6:  // TCP
    1.69 +  case 17: // UDP
    1.70 +    break;
    1.71 +  default:
    1.72 +    return PARSE_UNKNOWN_TYPE;
    1.73 +  }
    1.74 +  pi->ip4_length = GET_NET_USHORT(pi->header[XN_HDR_SIZE + 2]);
    1.75 +  pi->tcp_header_length = (pi->header[XN_HDR_SIZE + pi->ip4_header_length + 12] & 0xf0) >> 2;
    1.76 +  pi->tcp_length = pi->ip4_length - pi->ip4_header_length - pi->tcp_header_length;
    1.77 +  pi->tcp_remaining = pi->tcp_length;
    1.78 +  pi->tcp_seq = GET_NET_ULONG(pi->header[XN_HDR_SIZE + pi->ip4_header_length + 4]);
    1.79 +  if (pi->mss > 0 && pi->tcp_length > pi->mss)
    1.80 +    pi->split_required = TRUE;
    1.81 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.82 +  return PARSE_OK;
    1.83 +}
    1.84 +
    1.85 +VOID
    1.86 +XenNet_SumIpHeader(
    1.87 +  packet_info_t *pi,  
    1.88 +  PNDIS_PACKET packet
    1.89 +)
    1.90 +{
    1.91 +  PMDL mdl;
    1.92 +  UINT total_length;
    1.93 +  UINT buffer_length;
    1.94 +  PUCHAR buffer;
    1.95 +  ULONG csum = 0;
    1.96 +  USHORT i;
    1.97 +
    1.98 +  NdisGetFirstBufferFromPacketSafe(packet, &mdl, &buffer, &buffer_length, &total_length, NormalPagePriority);
    1.99 +  ASSERT(mdl);
   1.100 +
   1.101 +  buffer[XN_HDR_SIZE + 10] = 0;
   1.102 +  buffer[XN_HDR_SIZE + 11] = 0;
   1.103 +  for (i = 0; i < pi->ip4_header_length; i += 2)
   1.104 +  {
   1.105 +    csum += GET_NET_USHORT(buffer[XN_HDR_SIZE + i]);
   1.106 +  }
   1.107 +  while (csum & 0xFFFF0000)
   1.108 +    csum = (csum & 0xFFFF) + (csum >> 16);
   1.109 +  csum = ~csum;
   1.110 +  SET_NET_USHORT(buffer[XN_HDR_SIZE + 10], csum);
   1.111 +}
   1.112 +
   1.113 +PUCHAR
   1.114 +XenNet_GetData(
   1.115 +  packet_info_t *pi,
   1.116 +  USHORT req_length,
   1.117 +  PUSHORT length
   1.118 +)
   1.119 +{
   1.120 +  PNDIS_BUFFER mdl = pi->mdls[pi->curr_mdl];
   1.121 +  PUCHAR buffer = (PUCHAR)MmGetMdlVirtualAddress(mdl) + pi->curr_mdl_offset;
   1.122 +
   1.123 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.124 +
   1.125 +  *length = (USHORT)min(req_length, MmGetMdlByteCount(mdl) - pi->curr_mdl_offset);
   1.126 +
   1.127 +//  KdPrint((__DRIVER_NAME "     req_length = %d, length = %d\n", req_length, *length));
   1.128 +
   1.129 +  pi->curr_mdl_offset = pi->curr_mdl_offset + *length;
   1.130 +  if (pi->curr_mdl_offset == MmGetMdlByteCount(mdl))
   1.131 +  {
   1.132 +    pi->curr_mdl++;
   1.133 +    pi->curr_mdl_offset = 0;
   1.134 +  }
   1.135 +
   1.136 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.137 +
   1.138 +  return buffer;
   1.139 +}