#define IP_PROT_UDP 17\r
#define IP_PROT_IGMP 2\r
#define IP_PROT_ICMP 1\r
+#define IP_PROT_ICMPV6 58\r
\r
\r
#include <complib/cl_packon.h>\r
*********/\r
#include <complib/cl_packoff.h>\r
\r
+#include <complib/cl_packon.h>\r
+/****s* IB Network Drivers/ipv6_hdr_t\r
+* NAME\r
+* ipv6_hdr_t\r
+*\r
+* DESCRIPTION\r
+* Defines the IPV6 header for IPV6 packets.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef struct _ipv6_hdr\r
+{\r
+ uint32_t ver_tc_fl;\r
+ uint16_t payload_length;\r
+ uint8_t next_header;\r
+ uint8_t hop_limit;\r
+ uint8_t src_addr[16];\r
+ uint8_t dest_addr[16];\r
+\r
+} PACK_SUFFIX ipv6_hdr_t;\r
+/*\r
+* FIELDS\r
+* ver_tc_fl\r
+* This field contains of 3 subfields:\r
+* 1.Version (4 bits) \r
+* The constant 6 (bit sequence 0110).\r
+* 2.Traffic Class (8 bits) \r
+* The bits of this field hold two values. The 6 most-significant bits are used \r
+* for DSCP, which is used to classify packets. The remaining two bits \r
+* are used for ECN; priority values subdivide into ranges: traffic where \r
+* the source provides congestion control and non-congestion control traffic.\r
+* 3.Flow Label (20 bits) \r
+* Originally created for giving real-time applications special service.\r
+* Flow Label specifications and minimum requirements are described, \r
+* and first uses of this field are emerging.\r
+*\r
+*\r
+* payload_length;\r
+* The size of the payload in octets, including any extension headers. \r
+* The length is set to zero when a Hop-by-Hop extension header carries \r
+* a Jumbo Payload option.\r
+*\r
+* next_header\r
+* Specifies the type of the next header. This field usually specifies the\r
+* transport layer protocol used by a packet's payload. When extension headers\r
+* are present in the packet this field indicates which extension header follows. \r
+* The values are shared with those used for the IPv4 protocol field, \r
+* as both fields have the same function \r
+*\r
+* hop_limit\r
+* Replaces the time to live field of IPv4. This value is decremented by \r
+* one at each intermediate node the packet visits. When the counter reaches \r
+* 0 the packet is discarded\r
+*\r
+* src_addr\r
+* The IPv6 address of the sending node.\r
+*\r
+* dest_addr\r
+* The IPv6 address of the destination node(s).\r
+*\r
+*\r
+* SEE ALSO\r
+* IB Network Drivers, eth_hdr_t, arp_pkt_t, tcp_hdr_t, udp_hdr_t\r
+*********/\r
+#include <complib/cl_packoff.h>\r
+\r
\r
#include <complib/cl_packon.h>\r
/****s* IB Network Drivers/tcp_hdr_t\r
*********/\r
#include <complib/cl_packoff.h>\r
\r
-#define DHCP_PORT_SERVER CL_HTON16(67)\r
-#define DHCP_PORT_CLIENT CL_HTON16(68)\r
+#define DHCP_PORT_SERVER CL_HTON16(67)\r
+#define DHCP_PORT_CLIENT CL_HTON16(68)\r
+#define DHCP_IPV6_PORT_SERVER_OR_AGENT CL_HTON16(547)\r
+#define DHCP_IPV6_PORT_CLIENT CL_HTON16(546)\r
+\r
#define DHCP_PORT_PROXY_SERVER CL_HTON16(4011)\r
\r
#define DHCP_REQUEST 1\r
\r
typedef struct _ip_pkt\r
{\r
- ip_hdr_t hdr;\r
+ union\r
+ {\r
+ ip_hdr_t hdr;\r
+ ipv6_hdr_t hdr_ipv6;\r
+ } PACK_SUFFIX ;\r
union _ip_payload\r
{\r
tcp_hdr_t tcp;\r
#include "Precompile.h"\r
\r
\r
-\r
#if defined(EVENT_TRACING)\r
#ifdef offsetof\r
#undef offsetof\r
#include <complib/cl_init.h>\r
#include <initguid.h>\r
#include <iba/ipoib_ifc.h>\r
-#include "ntstrsafe.h"\r
#include "strsafe.h"\r
#include <offload.h>\r
\r
-\r
-\r
#define MAJOR_DRIVER_VERSION 2\r
#define MINOR_DRIVER_VERSION 1\r
\r
PDRIVER_OBJECT g_p_drv_obj;\r
\r
\r
-\r
-\r
static const NDIS_OID SUPPORTED_OIDS[] =\r
{\r
OID_GEN_SUPPORTED_LIST,\r
\r
}\r
\r
+extern "C" DRIVER_INITIALIZE DriverEntry;\r
\r
extern "C"\r
NTSTATUS\r
DriverEntry(\r
IN PDRIVER_OBJECT p_drv_obj,\r
IN PUNICODE_STRING p_reg_path );\r
+#ifdef _DEBUG_\r
+#pragma NDIS_PAGEABLE_FUNCTION(DriverEntry)\r
+#endif\r
+\r
\r
VOID\r
ipoib_unload(\r
IN PDRIVER_OBJECT p_drv_obj );\r
\r
+#ifdef _DEBUG_\r
+extern "C"\r
+#endif\r
NDIS_STATUS\r
ipoib_initialize_ex(\r
IN NDIS_HANDLE h_adapter,\r
IN NDIS_HANDLE config_context,\r
IN PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters);\r
+#ifdef _DEBUG_\r
+#pragma NDIS_PAGEABLE_FUNCTION(ipoib_initialize_ex)\r
+#endif\r
\r
BOOLEAN\r
ipoib_check_for_hang(\r
(sizeof(eth_hdr_t) + p_adapter->params.cm_payload_mtu);\r
}\r
\r
- p_adapter->params.xfer_block_size = \r
+ p_adapter->params.xfer_block_size = \r
(sizeof(eth_hdr_t) + p_adapter->params.payload_mtu);\r
\r
NdisReadNetworkAddress( &status, (PVOID *) p_mac, p_len, h_config );\r
gat.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;\r
gat.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);\r
\r
- gat.MediaType = NdisMedium802_3; \r
+ gat.MediaType = NdisMedium802_3;\r
gat.MaxXmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
gat.MaxRcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
gat.XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;\r
ipoib_adapter_t *p_adapter,\r
NDIS_HANDLE h_adapter\r
)\r
- {\r
+{\r
NTSTATUS Status;\r
\r
-\r
Status = SetDeviceRegistrationAttributes(p_adapter, h_adapter);\r
if (Status != NDIS_STATUS_SUCCESS)\r
{\r
("ipoib_create_adapter returned status %d.\n", ib_status ) );\r
return NDIS_STATUS_FAILURE;\r
}\r
- p_adapter->ipoib_state = IPOIB_INIT;\r
- IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SHUTTER,\r
- ("ipoib_state changed to IPOIB_INIT\n") );\r
\r
status = SetAttributes(p_adapter, h_adapter);\r
if (status != NDIS_STATUS_SUCCESS) {\r
\r
case OID_PNP_QUERY_POWER:\r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
- ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
+ ("Port %d received query for OID_PNP_QUERY_POWER\n", port_num) );\r
// Status is pre-set in this routine to Success\r
status = NDIS_STATUS_SUCCESS; \r
break;\r
IPOIB_EXIT( IPOIB_DBG_OID );\r
return NDIS_STATUS_PENDING;\r
}\r
- \r
+\r
\r
static NDIS_STATUS\r
ipoib_complete_query(\r
shutter_shut( &p_adapter->recv_shutter );\r
// Notify that shutter was already shut\r
p_adapter->ipoib_state |= IPOIB_RESET_OR_DOWN;\r
- ASSERT( p_adapter->ipoib_state == IPOIB_RUNNING ); \r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SHUTTER,\r
("ipoib_state was IPOIB_RUNNING and IPOIB_RESET_OR_DOWN flag was set\n") );\r
}\r
ipoib_port_t *gp_ipoib_port;\r
#endif\r
\r
+static KDEFERRED_ROUTINE __port_mcast_garbage_dpc;\r
static void __port_mcast_garbage_dpc(KDPC *p_gc_dpc,void *context,void *s_arg1, void *s_arg2);\r
+\r
static void __port_do_mcast_garbage(ipoib_port_t* const p_port );\r
\r
#if 0\r
\r
static NDIS_STATUS\r
__send_mgr_filter_udp(\r
- IN const ip_hdr_t* const p_ip_hdr,\r
+ IN const void* const p_ip_hdr,\r
IN MDL* p_mdl,\r
IN size_t buf_len,\r
+ IN uint8_t prot,\r
IN OUT ipoib_send_NB_SG* const s_buf);\r
\r
static NDIS_STATUS\r
/* function returns pointer to payload that is going after IP header.\r
* asssuming that payload and IP header are in the same buffer\r
*/\r
-static void* GetIpPayloadPtr(const ip_hdr_t* const p_ip_hdr)\r
+static inline void* GetIpPayloadPtr(const ip_hdr_t* const p_ip_hdr)\r
{\r
return (void*)((uint8_t*)p_ip_hdr + IP_HEADER_LENGTH(p_ip_hdr));\r
}\r
\r
+static inline void* GetIpv6PayloadPtr(const ipv6_hdr_t* const p_ipv6_hdr)\r
+{\r
+ return (void*)((uint8_t*)p_ipv6_hdr + p_ipv6_hdr->payload_length);\r
+}\r
+\r
+\r
/******************************************************************************\r
*\r
* Implementation\r
V. NDIS calls to ipoib_restart that calls to shutter_alive. Shutter counter is 0 and we can start working\r
*/\r
\r
- if ( p_adapter->ipoib_state == IPOIB_INIT) {\r
- IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,\r
- ("Shutter shut, state = %d\n", p_adapter->ipoib_state));\r
+ if ( p_adapter->ipoib_state == IPOIB_UNINIT ) \r
+ {\r
+ p_adapter->ipoib_state = IPOIB_INIT;\r
+ IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SHUTTER,\r
+ ("Shutter shut, state = %d\n", p_adapter->ipoib_state));\r
shutter_shut ( &p_adapter->recv_shutter );\r
+ } \r
+ else \r
+ {\r
+ IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SHUTTER,\r
+ ("Shutter wasn't shut, state = %d\n", p_adapter->ipoib_state));\r
}\r
- else {\r
- IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_RECV,\r
- ("*****Shutter wasn't shut, state = %d*****\n", p_adapter->ipoib_state));\r
- }\r
+ \r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
return IB_SUCCESS;\r
}\r
qp_create.rq_sge = 2; /* To support buffers spanning pages. */\r
qp_create.h_rq_cq = p_port->ib_mgr.h_recv_cq;\r
qp_create.sq_depth = p_port->p_adapter->params.sq_depth;\r
-\r
+ \r
+ // p_ca_attrs->max_sges contains the maximum number of SG elements \r
+ // available by HW. 3 of the them are reserved for an internal use\r
+ // Thus, the maximum of SGE for UD QP is limited by (p_ca_attrs->max_sges - 3)\r
#define UD_QP_USED_SGE 3\r
- qp_create.sq_sge = MAX_SEND_SGE < p_port->p_ca_attrs->max_sges ? \r
- MAX_SEND_SGE : ( p_port->p_ca_attrs->max_sges - UD_QP_USED_SGE );\r
+ if ( p_port->p_ca_attrs->max_sges > MAX_SEND_SGE )\r
+ {\r
+ p_port->max_sq_sge_supported = MAX_SEND_SGE - UD_QP_USED_SGE;\r
+ }\r
+ else \r
+ {\r
+ p_port->max_sq_sge_supported = p_port->p_ca_attrs->max_sges - UD_QP_USED_SGE;\r
+ }\r
+ \r
+ p_port->p_ca_attrs->max_sges -= UD_QP_USED_SGE;\r
+ qp_create.sq_sge = p_port->max_sq_sge_supported;\r
+ \r
if ( !p_port->p_ca_attrs->ipoib_csum ) \r
{ \r
/* checksum is not supported by device\r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
return status;\r
}\r
+ \r
+ ASSERT( qp_attr.sq_sge >= qp_create.sq_sge);\r
p_port->ib_mgr.qpn = qp_attr.num;\r
\r
/* Register all of physical memory */\r
IN uint32_t *p_recv_cnt\r
);\r
\r
+static IO_WORKITEM_ROUTINE __iopoib_WorkItem;\r
\r
static void\r
__iopoib_WorkItem(\r
total_recv_cnt += recv_cnt;\r
}\r
\r
- if (WorkToDo) {\r
- IoQueueWorkItem( p_port->pPoWorkItem, __iopoib_WorkItem, DelayedWorkQueue, p_port);\r
- } else {\r
+ if (WorkToDo)\r
+ {\r
+ IoQueueWorkItem( p_port->pPoWorkItem,\r
+ (PIO_WORKITEM_ROUTINE) __iopoib_WorkItem,\r
+ DelayedWorkQueue,\r
+ p_port );\r
+ }\r
+ else\r
+ {\r
// Release the reference count that was incremented when queued the work item.\r
ipoib_port_deref( p_port, ref_recv_cb );\r
}\r
\r
switch( p_ipoib->hdr.type )\r
{\r
+ case ETH_PROT_TYPE_IPV6:\r
+ if( len < (sizeof(ipoib_hdr_t) + sizeof(ipv6_hdr_t)) )\r
+ {\r
+ IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Received IP packet < min size\n") );\r
+ status = IB_INVALID_SETTING;\r
+ break;\r
+ }\r
+ \r
+ if( p_ipoib->type.ip.hdr_ipv6.next_header != IP_PROT_UDP )\r
+ {\r
+ /* Unfiltered. Setup the ethernet header and report. */\r
+ cl_perf_start( RecvTcp );\r
+ status = __recv_gen( p_ipoib, p_eth, p_src, p_dst );\r
+ cl_perf_stop( &p_port->p_adapter->perf, RecvTcp );\r
+ break;\r
+ }\r
+ //ASSERT( p_ipoib->type.ip.hdr_ipv6.payload_length == sizeof(ipv6_hdr_t) );\r
+\r
+ /* First packet of a UDP transfer. */\r
+ if( len <\r
+ (sizeof(ipoib_hdr_t) + sizeof(ipv6_hdr_t) + sizeof(udp_hdr_t)) )\r
+ {\r
+ IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Received UDP packet < min size\n") );\r
+ status = IB_INVALID_SETTING;\r
+ break;\r
+ }\r
+\r
+ /* Check if DHCP conversion is required. */\r
+ if( (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_IPV6_PORT_SERVER_OR_AGENT&&\r
+ p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_IPV6_PORT_CLIENT) ||\r
+ (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_IPV6_PORT_CLIENT &&\r
+ p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_IPV6_PORT_SERVER_OR_AGENT))\r
+ {\r
+ //TODO should be DHCP IPv6\r
+ if( len < (sizeof(ipoib_hdr_t) + sizeof(ipv6_hdr_t) +\r
+ sizeof(udp_hdr_t) /*+ DHCP_MIN_SIZE*/) )\r
+ {\r
+ IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Received DHCP < min size\n") );\r
+ status = IB_INVALID_SETTING;\r
+ break;\r
+ }\r
+ \r
+ /* UDP packet with BOOTP ports in src/dst port numbers. */\r
+ cl_perf_start( RecvDhcp );\r
+ //TODO implement this function\r
+ //status = __recv_dhcp_ipv6( p_port, p_ipoib, p_eth, p_src, p_dst );\r
+ status = IB_INVALID_SETTING;\r
+ cl_perf_stop( &p_port->p_adapter->perf, RecvDhcp );\r
+ }\r
+ else\r
+ {\r
+ /* Unfiltered. Setup the ethernet header and report. */\r
+ cl_perf_start( RecvUdp );\r
+ status = __recv_gen( p_ipoib, p_eth, p_src, p_dst );\r
+ cl_perf_stop( &p_port->p_adapter->perf, RecvUdp );\r
+ }\r
+ break;\r
+ \r
case ETH_PROT_TYPE_IP:\r
if( len < (sizeof(ipoib_hdr_t) + sizeof(ip_hdr_t)) )\r
{\r
\r
switch( p_eth_hdr->type )\r
{\r
+ case ETH_PROT_TYPE_IPV6:\r
+ cl_perf_start( FilterIpV6 );\r
+ status = __send_mgr_filter_ip( p_eth_hdr, p_mdl, buf_len, s_buf );\r
+ cl_perf_stop( &p_port->p_adapter->perf, FilterIpV6 );\r
+ break;\r
case ETH_PROT_TYPE_IP:\r
cl_perf_start( FilterIp );\r
status = __send_mgr_filter_ip( p_eth_hdr, p_mdl, buf_len, s_buf );\r
}\r
\r
/* Remember that one of the DS entries is reserved for the IPoIB header. */\r
- if( num_pages >= MAX_SEND_SGE )\r
+ if( num_pages >= p_port->max_sq_sge_supported )\r
{\r
IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
("Too many buffers to fit in WR ds_array. Copying data.\n") );\r
Copy only N+1-MAX_SEND_SGE, where N is a lenght of SG List\r
Remember that one of the DS entries is reserved for the IPoIB header.\r
*/\r
- if( ( p_sgl->NumberOfElements >= MAX_SEND_SGE ||\r
+ if( ( p_sgl->NumberOfElements >= s_buf->p_port->max_sq_sge_supported ||\r
p_sgl->Elements[0].Length < sizeof(eth_hdr_t)) )\r
{\r
IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_SEND,\r
("Too many buffers %d to fit in WR ds_array[%d] \\r
Or buffer[0] length %d < Eth header. Copying data.\n",\r
- p_sgl->NumberOfElements, MAX_SEND_SGE, p_sgl->Elements[0].Length ) );\r
+ p_sgl->NumberOfElements, s_buf->p_port->max_sq_sge_supported , \r
+ p_sgl->Elements[0].Length ) );\r
\r
if( !s_buf->p_port->p_adapter->params.cm_enabled )\r
{\r
status = __send_copy( s_buf->p_port, s_buf, lso_header_size );\r
cl_perf_stop( &s_buf->p_port->p_adapter->perf, SendCopy );\r
}\r
-\r
- status = NDIS_STATUS_RESOURCES;\r
+ else \r
+ {\r
+ status = NDIS_STATUS_RESOURCES;\r
+ }\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
return status;\r
}\r
IN ipoib_send_NB_SG *s_buf )\r
{\r
NDIS_STATUS status;\r
- ip_hdr_t *p_ip_hdr;\r
+ PVOID p_ip_hdr;\r
uint32_t ip_packet_len;\r
size_t iph_size_in_bytes;\r
size_t iph_options_size;\r
+ uint8_t prot;\r
+ size_t hdr_size;\r
\r
PERF_DECLARE( QueryIp );\r
PERF_DECLARE( SendTcp );\r
}\r
else\r
{\r
- p_ip_hdr = (ip_hdr_t*)(p_eth_hdr + 1);\r
+ p_ip_hdr = (PVOID) (p_eth_hdr + 1);\r
}\r
-\r
- if( buf_len < sizeof(ip_hdr_t) )\r
+ \r
+ if ( p_eth_hdr->type == ETH_PROT_TYPE_IPV6 ) \r
+ {\r
+ prot = ((ipv6_hdr_t *) p_ip_hdr)->next_header;\r
+ hdr_size = sizeof(ipv6_hdr_t);\r
+ }\r
+ else //IPv4\r
+ {\r
+ prot = ((ip_hdr_t *) p_ip_hdr)->prot;\r
+ hdr_size = sizeof(ip_hdr_t);\r
+ }\r
+ if( buf_len < hdr_size )\r
{\r
/* This buffer is done for. Get the next buffer. */\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
return NDIS_STATUS_BUFFER_TOO_SHORT;\r
}\r
\r
- switch( p_ip_hdr->prot )\r
+ switch( prot )\r
{\r
case IP_PROT_UDP:\r
cl_perf_start( FilterUdp );\r
status = __send_mgr_filter_udp( p_ip_hdr, p_mdl,\r
- (buf_len - sizeof(ip_hdr_t)), s_buf );\r
+ (buf_len - hdr_size), prot, s_buf );\r
cl_perf_stop( &p_port->p_adapter->perf, FilterUdp );\r
if( status == NDIS_STATUS_PENDING )\r
{ /* not DHCP packet, keep going */\r
2. ip options\r
So to get the IGMP packet we need to skip the ip options NDIS_BUFFER\r
*/\r
- iph_size_in_bytes = (p_ip_hdr->ver_hl & 0xf) * 4;\r
+ iph_size_in_bytes = (((ip_hdr_t*)p_ip_hdr)->ver_hl & 0xf) * 4;\r
iph_options_size = iph_size_in_bytes - buf_len;\r
buf_len -= sizeof(ip_hdr_t);//without ipheader\r
\r
We anyway pass it to __send_mgr_filter_igmp_v2().\r
*/\r
status = __send_mgr_filter_igmp_v2( s_buf->p_port,\r
- p_ip_hdr,\r
+ (ip_hdr_t*) p_ip_hdr,\r
iph_options_size,\r
p_mdl,\r
buf_len );\r
return status;\r
\r
case IP_PROT_ICMP:\r
+ case IP_PROT_ICMPV6:\r
p_desc->send_dir = SEND_UD_QP;\r
default:\r
break;\r
}\r
if( p_desc->send_dir == SEND_UD_QP )\r
{\r
- ip_packet_len = cl_ntoh16( p_ip_hdr->length );\r
+ ip_packet_len = cl_ntoh16( ((ip_hdr_t*)p_ip_hdr)->length ); //TODO add IPv6 support for CM flow\r
if( ip_packet_len > s_buf->p_port->p_adapter->params.payload_mtu )\r
{\r
//TODO: NDIS60\r
\r
static NDIS_STATUS\r
__send_mgr_filter_udp(\r
- IN const ip_hdr_t* const p_ip_hdr,\r
- IN MDL* p_mdl,\r
- IN size_t buf_len,\r
- IN OUT ipoib_send_NB_SG* s_buf )\r
+ IN const void* const p_ip_hdr,\r
+ IN MDL* p_mdl,\r
+ IN size_t buf_len,\r
+ IN uint8_t prot,\r
+ IN OUT ipoib_send_NB_SG* s_buf )\r
{\r
NDIS_STATUS status;\r
udp_hdr_t *p_udp_hdr;\r
}\r
else\r
{\r
- p_udp_hdr = (udp_hdr_t*)GetIpPayloadPtr(p_ip_hdr);\r
+ if ( prot == ETH_PROT_TYPE_IPV6 ) \r
+ {\r
+ p_udp_hdr = (udp_hdr_t*)GetIpv6PayloadPtr((ipv6_hdr_t*)p_ip_hdr);\r
+ }\r
+ else //IPv4\r
+ {\r
+ p_udp_hdr = (udp_hdr_t*)GetIpPayloadPtr((ip_hdr_t*)p_ip_hdr);\r
+ if (((ip_hdr_t*)p_ip_hdr)->offset > 0) {\r
+ /* This is a fragmented part of UDP packet\r
+ * Only first packet will contain UDP header in such case\r
+ * So, return if offset > 0\r
+ */\r
+ return NDIS_STATUS_PENDING;\r
+ }\r
+ }\r
}\r
/* Get the UDP header and check the destination port numbers. */\r
\r
- if (p_ip_hdr->offset > 0) {\r
- /* This is a fragmented part of UDP packet\r
- * Only first packet will contain UDP header in such case\r
- * So, return if offset > 0\r
- */\r
- return NDIS_STATUS_PENDING;\r
- }\r
+ \r
\r
if( buf_len < sizeof(udp_hdr_t) )\r
{\r
return NDIS_STATUS_BUFFER_TOO_SHORT;\r
}\r
\r
- if( (p_udp_hdr->src_port != DHCP_PORT_CLIENT ||\r
- p_udp_hdr->dst_port != DHCP_PORT_SERVER) &&\r
- (p_udp_hdr->src_port != DHCP_PORT_SERVER ||\r
- p_udp_hdr->dst_port != DHCP_PORT_CLIENT) )\r
+ if ( prot == ETH_PROT_TYPE_IPV6 ) {\r
+ if( (p_udp_hdr->src_port != DHCP_PORT_CLIENT ||\r
+ p_udp_hdr->dst_port != DHCP_PORT_SERVER) &&\r
+ (p_udp_hdr->src_port != DHCP_PORT_SERVER ||\r
+ p_udp_hdr->dst_port != DHCP_PORT_CLIENT) )\r
+ {\r
+ /* Not a DHCP packet. */\r
+ return NDIS_STATUS_PENDING;\r
+ }\r
+ }\r
+ else //IPv4\r
{\r
- /* Not a DHCP packet. */\r
- return NDIS_STATUS_PENDING;\r
+ if( (p_udp_hdr->src_port != DHCP_IPV6_PORT_CLIENT||\r
+ p_udp_hdr->dst_port != DHCP_IPV6_PORT_SERVER_OR_AGENT) &&\r
+ (p_udp_hdr->src_port != DHCP_IPV6_PORT_SERVER_OR_AGENT ||\r
+ p_udp_hdr->dst_port != DHCP_IPV6_PORT_CLIENT) )\r
+ {\r
+ /* Not a DHCP packet. */\r
+ return NDIS_STATUS_PENDING;\r
+ }\r
}\r
\r
buf_len -= sizeof(udp_hdr_t);\r
return NDIS_STATUS_RESOURCES;\r
}\r
/* Copy the IP and UDP headers. */\r
- cl_memcpy( &s_buf->p_send_buf->ip.hdr, p_ip_hdr , sizeof(ip_hdr_t) );\r
+ //TODO: in this case we limited IP size to 20, but it can be bigger, according to GetIpPayloadPtr\r
+ if ( prot == ETH_PROT_TYPE_IPV6 ) \r
+ {\r
+ cl_memcpy( &s_buf->p_send_buf->ip.hdr_ipv6, p_ip_hdr , sizeof(ipv6_hdr_t) );\r
+ }\r
+ else\r
+ {\r
+ cl_memcpy( &s_buf->p_send_buf->ip.hdr, p_ip_hdr , sizeof(ip_hdr_t) );\r
+ }\r
+ \r
cl_memcpy(\r
&s_buf->p_send_buf->ip.prot.udp.hdr, p_udp_hdr, sizeof(udp_hdr_t) );\r
\r