src/SeeDll/Packet32.c
/*! 
  \brief Sends a buffer of packets to the network.
  \param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter that will 
   send the packets.
  \param PacketBuff Pointer to buffer with the packets to send.
  \param Size Size of the buffer pointed by the PacketBuff argument.
  \param Sync if TRUE, the packets are sent respecting the timestamps. If FALSE, the packets are sent as
         fast as possible
  \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an
          error occurred during the send. The error can be caused by a driver/adapter problem or by an
		  inconsistent/bogus packet buffer.

  This function is used to send a buffer of raw packets to the network. The buffer can contain an arbitrary
  number of raw packets, each of which preceded by a dump_bpf_hdr structure. The dump_bpf_hdr is the same used
  by WinPcap and libpcap to store the packets in a file, therefore sending a capture file is straightforward.
  'Raw packets' means that the sending application will have to include the protocol headers, since every packet 
  is sent to the network 'as is'. The CRC of the packets needs not to be calculated, because it will be 
  transparently added by the network interface.

  \note Using this function if more efficient than issuing a series of PacketSendPacket(), because the packets are
  buffered in the kernel driver, so the number of context switches is reduced.

  \note When Sync is set to TRUE, the packets are synchronized in the kerenl with a high precision timestamp.
  This requires a remarkable amount of CPU, but allows to send the packets with a precision of some microseconds
  (depending on the precision of the performance counter of the machine). Such a precision cannot be reached 
  sending the packets separately with PacketSendPacket().
*/
\brief Sends a buffer of packets to the network.
\param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter that will
send the packets.
\param PacketBuff Pointer to buffer with the packets to send.
\param Size Size of the buffer pointed by the PacketBuff argument.
\param Sync if TRUE, the packets are sent respecting the timestamps. If FALSE, the packets are sent as
fast as possible
\return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an
error occurred during the send. The error can be caused by a driver/adapter problem or by an
inconsistent/bogus packet buffer.

This function is used to send a buffer of raw packets to the network. The buffer can contain an arbitrary
number of raw packets, each of which preceded by a dump_bpf_hdr structure. The dump_bpf_hdr is the same used
by WinPcap and libpcap to store the packets in a file, therefore sending a capture file is straightforward.
'Raw packets' means that the sending application will have to include the protocol headers, since every packet
is sent to the network 'as is'. The CRC of the packets needs not to be calculated, because it will be
transparently added by the network interface.

\note Using this function if more efficient than issuing a series of PacketSendPacket(), because the packets are
buffered in the kernel driver, so the number of context switches is reduced.

\note When Sync is set to TRUE, the packets are synchronized in the kerenl with a high precision timestamp.
This requires a remarkable amount of CPU, but allows to send the packets with a precision of some microseconds
(depending on the precision of the performance counter of the machine). Such a precision cannot be reached
sending the packets separately with PacketSendPacket().
\ brief Sends a buffer of packets to the network . \ param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter that will send the packets . \ param PacketBuff Pointer to buffer with the packets to send . \ param Size Size of the buffer pointed by the PacketBuff argument . \ param Sync if TRUE the packets are sent respecting the timestamps . If FALSE the packets are sent as fast as possible \ return The amount of bytes actually sent . If the return value is smaller than the Size parameter an error occurred during the send . The error can be caused by a driver / adapter problem or by an inconsistent / bogus packet buffer . This function is used to send a buffer of raw packets to the network . The buffer can contain an arbitrary number of raw packets each of which preceded by a dump_bpf_hdr structure . The dump_bpf_hdr is the same used by WinPcap and libpcap to store the packets in a file therefore sending a capture file is straightforward . ' Raw packets ' means that the sending application will have to include the protocol headers since every packet is sent to the network ' as is ' . The CRC of the packets needs not to be calculated because it will be transparently added by the network interface . \ note Using this function if more efficient than issuing a series of PacketSendPacket () because the packets are buffered in the kernel driver so the number of context switches is reduced . \ note When Sync is set to TRUE the packets are synchronized in the kerenl with a high precision timestamp . This requires a remarkable amount of CPU but allows to send the packets with a precision of some microseconds ( depending on the precision of the performance counter of the machine ) . Such a precision cannot be reached sending the packets separately with PacketSendPacket () .
INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
{
    BOOLEAN			Res;
    DWORD			BytesTransfered, TotBytesTransfered=0;
	DWORD last_total = 0;
	struct timeval	BufStartTime;
	UINT num_count = 0;
	ODS("PacketSendPackets");
#ifndef _WINNT4
	if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
	{
		ODS("PacketSendPackets: packet sending not allowed on wan adapters\n");
		return FALSE;
	}
#endif 
	BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec;
	BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
	do{
		Res = DeviceIoControl(AdapterObject->hFile,
			(Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC,
			(PCHAR)PacketBuff + TotBytesTransfered,
			Size - TotBytesTransfered,
			NULL,
			0,
			&BytesTransfered,
			NULL);
		TotBytesTransfered += BytesTransfered;
		if(TotBytesTransfered >= Size || Res != TRUE)
			break;
		if (last_total != TotBytesTransfered)
		{
			num_count = 0;
			last_total = TotBytesTransfered;
		}
		num_count++;
		if (num_count >= 100000)
		{
			return 0x7FFFFFFF;
		}
	}
	while(TRUE);
	return TotBytesTransfered;
}
INT PacketSendPackets ( LPADAPTER AdapterObject , PVOID PacketBuff , ULONG Size , BOOLEAN Sync ) { BOOLEAN Res ; DWORD BytesTransfered , TotBytesTransfered = 0 ; DWORD last_total = 0 ; struct timeval BufStartTime ; UINT num_count = 0 ; ODS ( " " ) ; #ifndef _WINNT4 if ( AdapterObject -> Flags != INFO_FLAG_NDIS_ADAPTER ) { ODS ( " \n " ) ; return FALSE ; } #endif BufStartTime . tv_sec = ( ( struct timeval * ) ( PacketBuff ) ) -> tv_sec ; BufStartTime . tv_usec = ( ( struct timeval * ) ( PacketBuff ) ) -> tv_usec ; do { Res = DeviceIoControl ( AdapterObject -> hFile , ( Sync ) ? pBIOCSENDPACKETSSYNC : pBIOCSENDPACKETSNOSYNC , ( PCHAR ) PacketBuff + TotBytesTransfered , Size - TotBytesTransfered , NULL , 0 , & BytesTransfered , NULL ) ; TotBytesTransfered += BytesTransfered ; if ( TotBytesTransfered >= Size || Res != TRUE ) break ; if ( last_total != TotBytesTransfered ) { num_count = 0 ; last_total = TotBytesTransfered ; } num_count ++ ; if ( num_count >= 100000 ) { return 0x7FFFFFFF ; } } while ( TRUE ) ; return TotBytesTransfered ; }
\brief Sends a buffer of packets to the network.
\ brief Sends a buffer of packets to the network .
//LARGE_INTEGER	StartTicks, CurTicks, TargetTicks, TimeFreq;
 // _WINNT4
 // Obtain starting timestamp of the buffer
 // Retrieve the reference time counters
 //	QueryPerformanceCounter(&StartTicks);
 //	QueryPerformanceFrequency(&TimeFreq);
 //	CurTicks.QuadPart = StartTicks.QuadPart;
 // Send the data to the driver
 // Exit from the loop on termination or error
 // Fatal Error: Infinite Loop
 // calculate the time interval to wait before sending the next packet
 /*TargetTicks.QuadPart = StartTicks.QuadPart +
		(LONGLONG)
		((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 +
		(((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *
		(TimeFreq.QuadPart) / 1000000;
		
		// Wait until the time interval has elapsed
		while( CurTicks.QuadPart <= TargetTicks.QuadPart )
			QueryPerformanceCounter(&CurTicks);*/