Chapter 13. Analyzing Network Packets

Introduction

Network programming is very much concerned with moving data from client to server, but when you need to look at what is moving between the client and server, you encounter a problem.

In most cases, there is no need for a program to know what data is being received by other applications. Furthermore, it is a security risk to have one program that could scan third-party applications, such as FTP software, and retrieve the username and password for your Web site; however, if you are building a value-added package to a third-party application, such as a content filter for a proprietary or legacy application, tapping into what is being sent between client and server is a good start.

Packet capture isn’t something new. It has been around for many years. But very few applications actually leverage the technology to provide tools that can be used in conjunction with other software to provide virus or computer-misuse detection. What is available, though, are extensive tools that can tell you what each byte in every packet means, down to even the computer manufacturer that sent the packet. Figure 13.1 shows the demo version of TracePlus from www.sstinc.com.

TracePlus utility.

Figure 13.1. TracePlus utility.

Note

In order to determine the manufacturer of a particular piece of equipment from its MAC address, access the listing at http://standards.ieee.org/regauth/oui/oui.txt, which contains most, if not all, network equipment manufacturers with their allocated MAC address space.

Software that can leverage packet-level data can be useful for businesses. We have all heard of the scenario where a few employees decide to download their favorite band’s latest album on Mp3 the day of a big presentation, causing a total misallocation of bandwidth within a company. This is where traffic-detection software comes into its own, providing an early warning system for bandwidth misuse.

Traffic-detection software can be used to detect packets on a network that could uncover viruses, use of unauthorized software, and email forgery. Let’s look briefly at how the applications mentioned above could be implemented using packet-level monitoring.

You can use traffic detection to discover the presence of viruses and attacks in progress, but unfortunately not to prevent them. It could, however, be used to provide companywide detection of infected computers and denial-of-service attacks. The telltale signs of virus propagation could be rapid sequential accesses to computers within the subnet on port 80 (scanning for servers to infect) or heartbeat signals coming from a nonstandard port to an external server (firewall tunneling).

Denial-of-service attacks could be detected from the presence of a large number of corrupted packets sent to a particular server. A fragmented ping request would indicate a ping-of-death attack. Large numbers of incomplete TCP connections would indicate a SYN flood attack, in which the first packet of a TCP handshake is sent repetitively and rapidly. The victim attempts to establish TCP sessions for each of the packets by sending ACK (acknowledge) packets to the attacker, which are not responded to. The victim eventually becomes overwhelmed with pending TCP sessions and denies all network traffic.

Detection of unauthorized software usage could be useful in a company where employees may be partial to spending time playing computer games during work hours. Multiplayer computer games generally operate on a high port over TCP/IP or IPX. Games produce a lot of network traffic and, thus, can be spotted easily in a TCP/IP trace. The IP addresses of the offending employee’s computers could be logged, and the employee could be suitably warned.

Email traffic could also be monitored remotely using these techniques. This could be used to detect company secrets being sent to a competitor. Furthermore, a system to prevent email spoofing and forgery could be implemented if SMTP traffic were monitored. An application could keep a record of each employee’s computer’s IP address and email address. In the event of a mismatch between the IP and email address, an alarm could be raised, possibly sending an email to the recipient warning of the possibility of email forgery.

This chapter begins with information about how to read and interpret IP-level traffic on your network. It then progresses to more complex examples about how to drill down further into the network stack and extract lower-level data at the frame level. The chapter concludes with information about how to use new classes introduced in .NET 2.0 Whidbey to gather systemwide network information.

IP-level network tapping

Network tapping anything that runs at the IP level includes TCP/IP and UDP and everything above that, such as DNS, HTTP, FTP, and so forth. At this level, you don’t need to use any special software. Everything can be done natively in .NET.

To implement a layer 3 network tap in .NET, open a new project in Visual Studio .NET and add a list box named lbPackets and two buttons, btnStart and btnStop. It may be worthwhile to set the font for the list box to Courier for easier reading.

After designing the user interface, you should add the following public variable, a reference to the main listener thread:

C#

public Thread Listener;

VB.NET

Public Listener as Thread

Click on the Start button and enter the following code:

C#

private void btnStart_Click(object sender, System.EventArgs
e)
{
  btnStart.Enabled = false;
  btnStop.Enabled = true;
  Listener = new Thread(new ThreadStart(Run));
  Listener.Start();
}

VB.NET

Private Sub btnStart_Click(ByVal sender As Object, _
        ByVal e As System.EventArgs)
  btnStart.Enabled = False
  btnStop.Enabled = True
  Listener = New Thread(New ThreadStart(AddressOf Run))
  Listener.Start()
End Sub

The Run method is where the network tap takes place. It is a processor-intensive task, so it is executed in its own thread, as can be seen from the code. Click on the Stop button and enter the following code:

C#

private void btnStop_Click(object sender, System.EventArgs e)
{
   btnStart.Enabled = true;
   btnStop.Enabled = false;
   if(Listener != null)
 {
   Listener.Abort();
   Listener.Join();
   Listener = null;
 }
}

VB.NET

Private Sub btnStop_Click(ByVal sender As Object, _
        ByVal e As System.EventArgs)
  btnStart.Enabled = True
  btnStop.Enabled = False
  If Not Listener Is Nothing Then
    Listener.Abort()
    Listener.Join()
    Listener = Nothing
  End If
End Sub

This code simply kills the thread containing the network tap, which effectively stops reporting the arrival of new packets.

C#

public void Run()
{
  int len_receive_buf = 4096;
  int len_send_buf = 4096;
  byte[] receive_buf = new byte[len_receive_buf];
  byte[] send_buf = new byte[len_send_buf];
  int cout_receive_bytes;
  Socket socket = new Socket(AddressFamily.InterNetwork,
  SocketType.Raw, ProtocolType.IP);
  socket.Blocking = false;
  IPHostEntry IPHost = Dns.GetHostByName(Dns.GetHostName());
  socket.Bind(new
  IPEndPoint(IPAddress.Parse
  (IPHost.AddressList[0].ToString()), 0));
  socket.SetSocketOption(SocketOptionLevel.IP,
     SocketOptionName.HeaderIncluded, 1);
  byte []IN = new byte[4]{1, 0, 0, 0};
  byte []OUT = new byte[4];
  int SIO_RCVALL = unchecked((int)0x98000001);
  int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
  while(true)
  {
    IAsyncResult ar = socket.BeginReceive(receive_buf, 0,
    len_receive_buf, SocketFlags.None, null, this);
    cout_receive_bytes = socket.EndReceive(ar);
    Receive(receive_buf, cout_receive_bytes);
  }
}

VB.NET

Public Sub Run()
 Dim len_receive_buf As Integer = 4096
 Dim len_send_buf As Integer = 4096
 Dim receive_buf() As Byte = New Byte(len_receive_buf) {}
 Dim send_buf() As Byte = New Byte(len_send_buf) {}
 Dim cout_receive_bytes As Integer
 Dim socket As Socket = New _
   Socket(AddressFamily.InterNetwork, _
   SocketType.Raw, ProtocolType.IP)
 socket.Blocking = False
 Dim IPHost As IPHostEnTry = _
 Dns.GetHostByName(Dns.GetHostName())
 socket.Bind(New _
   IPEndPoint(IPAddress.Parse _
  (IPHost.AddressList(0).ToString()), 0))
 socket.SetSocketOption(SocketOptionLevel.IP, _
   SocketOptionName.HeaderIncluded, 1)
 Dim bIN As Byte() = New Byte() {1, 0, 0, 0}
 Dim bOUT As Byte() = New Byte() {0, 0, 0, 0}
 Dim SIO_RCVALL As Integer = &H98000001
 Dim ret_code As Integer = socket.IOControl _
       (SIO_RCVALL, bIN, bOUT)
 Do
   Dim ar As IAsyncResult = socket.BeginReceive _
     (receive_buf, 0, _
     len_receive_buf, SocketFlags.None, Nothing, Me)
    cout_receive_bytes = socket.EndReceive(ar)
    Receive(receive_buf, cout_receive_bytes)
 Loop
End Sub

The Run method is the core thread of the application. It creates a raw socket bound to the local machine on the default adapter. The socket’s normal operating parameters are then modified using the IOControl method, which accesses the underlying socket API function WSAIoctl. This function is passed a parameter SIO_RCVALL (98000001 Hex). Use of this parameter enables a socket to receive all IP packets on the network. The socket must be in RAW mode, using the IP protocol, and bound to a specific local adapter. This feature requires administrator privilege on the local machine. The packet parsing and display has been separated from the tapping thread to make the program more legible. This method is called Receive and should be implemented thus:

C#

public void Receive(byte []buf, int len)
{
 if (buf[9]==6)
 {
   lbPackets.Items.Add
   (Encoding.ASCII.GetString(buf).Replace(""," "));
 }
}

VB.NET

Public Sub Receive(ByVal buf as byte(), ByVal len As Integer)
 If buf(9)=6 then
  lbPackets.Items.Add(Encoding.ASCII.GetString _
    (buf).Replace(chr(0)," "))
 end if
End Sub

In this example, traffic is filtered so that only TCP/IP packets are shown. This means that the screen is not cluttered with DNS queries, pings, and UDP data. TCP/IP packets will always have the ninth byte in the header set to 6. All null (ASCII code 0) characters are displayed as spaces so that the list box does not crop the string at the first null character.

Finally, you need to add some standard namespaces to the code:

C#

using System;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;

VB.NET

Imports System
Imports System.Windows.Forms
Imports System.Net.Sockets
Imports System.Net
Imports System.Threading
Imports System.Text

To test the application, run it from Visual Studio .NET, and visit a Web site using your browser. You should see the raw TCP data flowing between your browser and the Web server appear in the list box, as shown in Figure 13.2.

IP-layer packet sniffer application.

Figure 13.2. IP-layer packet sniffer application.

Interpreting raw network data

Capturing and interpreting raw network data are totally separate things. Being able to recognize anomalies in the network data is the key to providing a useful tool that could be of real benefit to network managers and administrators.

Raw network data can appear totally unordered, with HTTP packets mixed in with NETBIOS (Microsoft file sharing) and ARP, each performing different tasks, but working simultaneously. Some of these packets can be recognized immediately: familiar snippets of HTML generally indicate HTTP (although it could be a rich-text email or a Web page being uploaded). Most networks will primarily ferry IP traffic, but will also carry non-IP traffic such as NETBIOS and ARP.

Every packet carries a header that is in a strictly defined binary format. To define the standards involved most concisely, the tables in this chapter list the name and starting point of each field in the relevant header. Every field runs contiguously with the next; thus, the length of any field can be calculated by subtracting its starting point from the following field’s starting point.

Because fields do not need to start at a byte boundary, the bit number is also provided in the second column. Where a field is commonly known as being part of a collective field, it is separated in the description column from the parent field by a colon.

The frame header (Table 13.1) is the only part that the hardware within the network card will actually read or process. It is 14 bytes long, containing the hardware address of the source and destination computers. In the case where the hardware address of the destination computer is unknown, this address is set to FF-FF-FF-FF-FF-FF (hex). Over PPP connections, the source and destination MAC address may be omitted and replaced by SRC and DEST.

Table 13.1. Ethernet frame header.

Byte Offset

Bit Offset

Description

1

1

Destination MAC address

6

1

Source MAC address

12

1

Ethernet type code (2 bytes)

The Ethernet type code is a two-digit hex number that specifies the packet protocol (Table 13.2). A fairly comprehensive list of Ethernet type codes can be seen at www.cavebear.com/CaveBear/Ethernet.

Table 13.2. Ethernet type codes.

Type Code (Hex)

Meaning

0800

IP version 4

0805

X.25

0806

ARP

8035

RARP

8037

IPX

809B

AppleTalk

80F3

AppleTalk ARP

814C

SNMP

86DD

IP version 6

IP packets in detail

In IP packets, the IP header (Table 13.3) immediately follows the frame header at byte 14. IP is definitively described in RFC 791.

Table 13.3. IP header.

Byte Offset

Bit Offset

Description

1

1

Version

1

5

Header length

2

1

Type of service: Precedence

2

4

Type of service: Delay

2

5

Type of service: Throughput

2

6

Type of service: Reliability

2

7

Type of service: (Reserved)

3

1

Data length

5

1

Identification

7

1

Flags

7

4

Fragment offset

9

1

TTL

10

1

Protocol

11

1

Header checksum

13

1

Source address

17

1

Destination address

21

1

Option: code: Flag

21

2

Option: code: Class

21

4

Option: code: Number

22

1

Option: Length

23

1

Option: Data (variable length)

  

Data (variable length)

  • Version: Set to 0100 for IPv4 and 0110 for IPv6.

  • Header length: The length of the header divided by 4. Max length is 60.

  • Type of service: May be used to increase quality of service on some networks.

  • Data length: The combined length of the header and data.

  • Identification: A random number used to identify duplicate packets.

  • Flags: Indicates the fragmentation status of the packet. Bit 2 is set to 1 when the datagram cannot be fragmented (0 when it can). Bit 3 is set to 1 when there are more fragments in the datagram, and 0 when this packet is the last fragment.

  • Fragment offset: Indicates the position a packet should occupy within a fragmented datagram.

  • TTL: Indicates the number of nodes through which the datagram can pass before being discarded. Used to avoid infinite routing loops.

  • Protocol: Set to 6 for TCP, 17 for UDP, 1 for ICMP, and 2 for IGMP.

  • Checksum: A checksum of the IP header calculated using a 16-bit ones complement sum.

  • Source: The IP address of the sending computer.

  • Destination: The IP address of the receiving computer.

  • Option: An optional field that may contain security options, routing records, timestamps, and so forth.

ICMP packets in detail

In ICMP (ping) packets immediately following the IP header make up a 4-byte header (Table 13.4) followed by a body of variable length. A definitive description of ICMP can be found in RFC 792.

Table 13.4. ICMP header.

Byte Offset

Bit Offset

Description

1

1

Type

2

1

Code

3

1

Checksum

Type: Defines the purpose or function of the packet. See Table 13.5.

Table 13.5. ICMP type codes.

Type Code

Meaning

0

Echo reply

3

Destination unreachable

4

Source quench

5

Redirect

8

Echo request

11

Timeout

12

Parameter unintelligible

13

Timestamp request

14

Timestamp reply

15

Info request

16

Info reply

17

Address request

18

Address reply

Code: A type code–specific identifier that more accurately describes the function of the packet. In a destination unreachable (3) packet, 0 indicates the subnet is down, whereas 1 indicates that only the host is down.

Checksum: The checksum is the 16-bit ones complement of the ones complement sum of the ICMP message starting with the ICMP type.

TCP/IP packets in detail

In TCP/IP packets, immediately following the IP header is a 24-byte TCP header (Table 13.6). A definitive description of TCP can be found in RFC 793.

Table 13.6. TCP header.

Byte Offset

Bit Offset

Description

1

1

Source port

3

1

Destination port

5

1

Sequence number

9

1

Acknowledgment number

13

1

Data offset

13

4

Reserved

14

3

Urgent (URG)

14

4

Acknowledge (ACK)

14

5

Push (PSH)

14

6

Reset (RST)

14

7

Synchronize (SYN)

14

8

Finish (FIN)

15

1

Window

17

1

Checksum

19

1

Urgent pointer

21

1

Options

24

1

Padding

  • Source port: The port the TCP connection is made from, usually a high port.

  • Destination port: The destination port, 80 for HTTP and 25 for SMTP, etc.

  • Sequence number: The sequence number of the first data octet in this segment (except when SYN is present). If SYN is present, the sequence number is the initial sequence number (ISN), and the first data octet is ISN + 1.

  • Acknowledgment number: If the ACK control bit is set, this field contains the value of the next sequence number the segment sender is expecting to receive. Once a connection is established, this is always sent.

  • Data offset: The number of 32-bit words in the TCP header. This indicates where the data begins. The TCP header (even one including options) is an integral number 32 bits long.

  • Urgent (URG): When set to 1, the urgent pointer field is significant.

  • Acknowledge (ACK): When set to 1, the acknowledgment field is significant.

  • Push (PSH): Implements a push function.

  • Reset (RST): When set to 1, it will reset the connection.

  • Synchronize (SYN): Synchronizes sequence numbers.

  • Finish (FIN): Indicates that there is no more data from the sender.

  • Window: The number of data octets indicated in the acknowledgment field that the sender of this segment is willing to accept.

  • Checksum: The checksum field is the 16-bit ones complement of the ones complement sum of all 16-bit words in the header and text, if segments are zero-padded to form a multiple of 16-bit words for checksum purposes. The pad is not transmitted as part of the segment. While computing the checksum, the checksum field is replaced with zeros. The checksum also covers a pseudoheader that is prefixed to the TCP header while computing the checksum only. This pseudoheader contains the source address, the destination address, the protocol, and TCP length.

  • Urgent pointer: Indicates the current value of the urgent pointer as an offset from the sequence number in this segment. The urgent pointer points to the sequence number of the byte following the urgent data. This field is only to be interpreted in segments with the URG control bit set.

  • Options: This contains vendor-specific IP options that may not be implemented on all systems. It is guaranteed to end on a 32-bit boundary with zero padding.

TCP is a connection-oriented protocol with built-in protection from duplicated, dropped, and out-of order packets. This is done by explicitly opening a connection between client and server and assigning each packet a sequence number. The client will reply to the server with an acknowledgment for every packet sent; if sequence numbers go missing, appear twice, or appear out of order to the client, the acknowledgment will not be sent, and the server can take appropriate action.

A TCP connection is established with a three-way handshake. Initially, the client sends a SYN request to the server, and the server replies with an ACK response, to which the client replies with an ACK reply. Similarly, a TCP connection is closed with a two-way handshake, where one party sends a FIN request to the other, which then replies with an ACK response.

UDP packets in detail

In UDP packets, immediately following the IP header is an 8-byte UDP header (Table 13.7). A definitive description of UDP can be found in RFC 768.

Table 13.7. UDP header.

Byte Offset

Bit Offset

Description

1

1

Source port

3

1

Destination port

5

1

Length

7

1

Checksum

UDP is the most basic data-carrying protocol that is valid for the Internet. It contains no protection against lost or duplicated packets, and therefore is not applicable to media that require high integrity. It is acceptable for live streaming audio and video formats.

  • Source port: The port the UDP connection is made from, usually a high port.

  • Destination port: The destination port, 161 for SNMP and 53 for DNS, etc.

  • Length: The number of bytes following the header, plus the header itself.

  • Checksum: Computed as the 16-bit ones complement of the ones complement sum of a pseudoheader of information from the IP header, the UDP header, and the data, padded as needed with zero bytes at the end to make a multiple of 2 bytes. If the checksum is set to 0, then check summing is disabled. If the computed checksum is 0, then this field must be set to 0xFFFF.

DNS packets in detail

In DNS packets, immediately following the UDP header (port 53) is a 12-byte DNS header (Table 13.8). A definitive description of DNS can be found in RFC 1035.

Table 13.8. DNS header.

Byte Offset

Bit Offset

Description

1

1

ID

3

1

Query or response

3

2

Query

3

6

Authoritative answer

3

7

Truncation

3

8

Recursive

3

1

Availability

4

2

Set to 0 for future use

4

5

Result code

5

1

Question count

7

1

Answer count

9

1

Authority count

11

1

Additional count

  • ID: Used to correlate queries and responses.

  • Query or response: Identifies the message as a query or response.

  • Query: Field that describes the type of message: 0 for standard query (name to address), 1 for inverse query (address to name), and 2 for server status request.

  • Authoritative answer: Identifies the response as one made by an authoritative name server when set to 1.

  • Truncation: Indicates the message has been truncated when set to 1.

  • Recursive: Set to 1 to request the name server to perform recursive searches.

  • Availability: Indicates if the name server can provide recursive service.

  • Result code (RCODE): Used to indicate errors in processing the DNS query.

  • Question count: Indicates the number of entries in the question section.

  • Answer count: Indicates the number of resource records in the answer section.

  • Authority count: Indicates the number of name server resource records in the authority section.

  • Additional count: Indicates the number of resource records in the additional records section.

DNS is used primarily to resolve IP addresses from domain names; however, it can also be used to locate mail exchanges and so forth.

Layer 2 network tapping

When you tap into (sniff) network traffic at level 2, you receive not only data from other applications on your computer, but also from other applications on different computers that are on the same network. Furthermore, you get more than just IP traffic: you start to see ARP requests, NETBIOS packets, and many other weird and wonderful inhabitants of the network, and they all come complete with frame headers.

WinPCap is, in essence, a driver that enables you to read packets directly from a network adapter. It was developed by the Politecnico di Torino (Italy) and can be distributed in binary format with the addition of a copyright notice and disclaimer to your application. WinPCap can be downloaded from http://winpcap.mirror.ethereal.com.

The WinPCap DLL is designed for use with Visual C++ and is difficult to use directly from C# or VB.NET. A wrapper of some description is required to import this library into your .NET application. One of the well-known wrappers is an ActiveX control named PacketX, which is available from www.beesync.com. This software is shareware and, therefore, may not be applicable for inclusion in freeware packages.

Alternatively, I have prepared a wrapper (a C++ DLL) named rvpacket.dll that is available for download at http://network.programming-in.net/downloads/rvPacket.zip. This DLL is open source and can be redistributed as required. The DLL is only a basic implementation of WinPCap, but the source code is available for those who are savvy in C++ to extend the functionality.

Developers should be aware of the following known limitations to WinPCap:

  • It will not operate correctly on Windows NT, 2000, or XP dial-up connections.

  • It may reset dial-up connections on Windows 95.

  • Wireless network cards are not fully supported.

  • Some implementations of VPN are not supported.

Using rvPacket and WinPCap

This first example uses WinPCap with the rvPacket wrapper to display all network traffic on a textbox. It is normal for network data to pass through the adapter faster than it can appear on-screen, so there may be some time lag between data passing through the network and what is displayed on-screen. The first step in developing this application is to download and install WinPCap from http://winpcap.mirror.ethereal.com, then to download rvPacket from http://network.programming-in.net/downloads/rvPacket.zip, and copy the DLL into your Windows system folder.

Create a new project in Visual Studio .NET, and draw a textbox named tbPackets with multiline set to true. Two buttons named btnStart and btnStop are required. VB.NET developers will need to add a reference to Microsoft.VisualBasic.Compatibility using Project→ Add References.

Click on the Start button and add the following code:

C#

private void btnStart_Click(object sender, System.EventArgs
e)
{
  short Qid;
  string packetBuffer;
  short openSuccess;
  short packetQueue;
  short packetLen;
  string rawAdapterDetails = "";
  int posDefaultAdapter;
  getAdapterNames(rawAdapterDetails);
  Adapter="\"; // default adapter
  openSuccess = openAdapter("\");
  if (openSuccess != ERR_SUCCESS)
  {
    MessageBox.Show(
    "Unable to start. Check WinPCap is installed");
    return;
  }
  while(true)
  {
    packetQueue = checkPacketQueue(Adapter);
    for (Qid = 1; Qid<packetQueue;Qid++)
    {
       packetBuffer = new
       StringBuilder().Append
       (' ',MAX_PACKET_SIZE).ToString();
       packetLen = getQueuedPacket(packetBuffer);
     packetBuffer = packetBuffer.Substring(0, packetLen);
     tbPackets.Text = tbPackets.Text +
             packetBuffer.Replace(""," ");
     tbPackets.SelectionStart = tbPackets.Text.Length;
     Application.DoEvents();
   }
   Application.DoEvents();
 }
}

VB.NET

Private Sub cmdStart_Click(ByVal eventSender As _
    System.Object, ByVal eventArgs As _
    System.EventArgs) Handles cmdStart.Click
Dim Qid As Short
Dim packetBuffer As String
Dim adapters() As String
Dim openSuccess As Short
Dim packetQueue As Short
Dim packetLen As Short
Dim rawAdapterDetails As String
Dim posDefaultAdapter As Short
rawAdapterDetails = Space(MAX_ADAPTER_LEN)
getAdapterNames(rawAdapterDetails)
posDefaultAdapter = _
rawAdapterDetails.IndexOf(ADAPTER_DELIMITER)
Adapter = rawAdapterDetails.Substring(0, posDefaultAdapter)
openSuccess = openAdapter(Adapter)
If openSuccess <> ERR_SUCCESS Then
 MsgBox("Unable to start. Check WinPCap is installed")
 Exit Sub
End If
Do
 packetQueue = checkPacketQueue(Adapter)
 For Qid = 1 To packetQueue
  packetBuffer = Space(MAX_PACKET_SIZE)
  packetLen = getQueuedPacket(packetBuffer)
  packetBuffer = packetBuffer.Substring(0, packetLen)
  tbPackets.Text = tbPackets.Text & Replace _
        (packetBuffer, Chr(0), " ")
  tbPackets.SelectionStart = Len(tbPackets.Text)
   System.Windows.Forms.Application.DoEvents()
  Next
  System.Windows.Forms.Application.DoEvents()
 Loop
End Sub

The code listed above performs two functions; first, detects all of the network adapters on the system, bearing in mind that computers can have more than one means of connecting to a network, either by modem, Ethernet, or some other system. The getAdapterNames returns a list of adapter names separated by a pipe character (“|”). Here the first default adapter is used.

Network traffic regularly arrives faster than it can be read and handled by an application; thus, the data is buffered internally in a linked-list structure. The rvPacket library has two functions for reading this buffer, checkPacketQueue and getQueuedPacket. As the names suggest, the former is a nonblocking function that retrieves the number of packets in the queue, and the latter will then read each packet in the queue sequentially. The queue is guaranteed not to grow in size between calls to checkPacketQueue, and no data on this buffer will be altered.

The threading model is primitive, using nothing more than a DoEvents call to maintain responsiveness for the user interface. This has the side effect of pushing CPU usage to 100%, which looks unprofessional in a consumer product. In a more polished version, proper threading should be used.

Note

All bytes of value 0 are replaced with a space character in the code above to help display the text on-screen; this serves no other purpose.

Although not strictly necessary, the adapter should be closed after use. If it is not closed before the application is destroyed, then a memory leak will result. More importantly, if two separate processes open the adapter at once, Windows will crash.

Click on the Stop button, and enter the following code:

C#

private void btnStop_Click(object sender, System.EventArgs e)
{
    closeAdapter(Adapter);
}

VB.NET

Private Sub btnStop_Click(ByVal sender As _
     System.Object, ByVal e As System.EventArgs) _
     Handles btnStop.Click
       closeAdapter(Adapter)
End Sub

Several API declarations have to be made to make the rvPacket library accessible. Insert this code directly after the form constructor:

C#

[DllImport("rvPacket.dll")]
public static extern short getAdapterNames (string s);

[DllImport("rvPacket.dll")]
public static extern short openAdapter (string Adapter);

[DllImport("rvPacket.dll")] public static extern short
checkPacketQueue(string Adapter);

[DllImport("rvPacket.dll")] public static extern short
getQueuedPacket(string s);

[DllImport("rvPacket.dll")] public static extern void
closeAdapter(string Adapter);

const short SIMULTANEOUS_READS = 10;
const short MAX_ADAPTER_LEN = 512;
const string ADAPTER_DELIMITER = "|";
const short MAX_PACKET_SIZE = 10000;
const short ERR_SUCCESS = 1;
const short ERR_ADAPTER_ID= 2;
const short ERR_INVALID_HANDLE= 3;
const short ERR_INVALID_ADAPTER= 4;
const short ERR_ALLOCATE_PACKET= 5;
string Adapter = "";

VB.NET

Private Declare Function getAdapterNames Lib _
        "rvPacket.dll" (ByVal s As String) As Short
Private Declare Function openAdapter Lib _
        "rvPacket.dll" (ByVal Adapter As String) As Short
 Private Declare Function checkPacketQueue Lib _
        "rvPacket.dll" (ByVal Adapter As String) As Short
 Private Declare Function getQueuedPacket Lib _
        "rvPacket.dll" (ByVal s As String) As Short
 Private Declare Sub closeAdapter Lib _
        "rvPacket.dll" (ByVal Adapter As String)

 Private Const SIMULTANEOUS_READS As Short = 10
 Private Const MAX_ADAPTER_LEN As Short = 512
 Private Const ADAPTER_DELIMITER As String = "|"
 Private Const MAX_PACKET_SIZE As Short = 10000
 Private Const ERR_SUCCESS As Short = 1
 Private Const ERR_ADAPTER_ID As Short = 2
 Private Const ERR_INVALID_HANDLE As Short = 3
 Private Const ERR_INVALID_ADAPTER As Short = 4
 Private Const ERR_ALLOCATE_PACKET As Short = 5
 Public Adapter As String

The rvPacket library is developed in unmanaged C++; therefore, these rather cryptic function declarations must be used, in the same way as they were required to access the Windows API. The calling conventions for each of the functions are identical: they all accept a string and return a number.

GetAdapterNames is used to retrieve a list of network adapters present on the system. One of these adapter names would be passed to openAdapter, which effectively begins the sniffing process on that network adapter.

CheckPacketQueue returns the number of packets that are currently held in the network card buffer. The GetQueued packet can then retrieve each of these packets one at a time.

CloseAdapter stops the sniffing process and frees up the adapter for any other process to use it. Immediately following the declarations are several constants that can be used within the code to better explain errors to users, and so forth.

Finally, C# programmers require the following namespaces:

C#

using System.Text;
using System.Runtime.InteropServices;

To test the application, make sure you are connected to an active network and that WinPCap and rvPacket have been installed. Run the program from Visual Studio .NET and press Start. If you open a browser and start using the Web, you will see the HTTP sent and received in the textbox (Figure 13.3).

Frame-layer packet sniffer with rvPacket.

Figure 13.3. Frame-layer packet sniffer with rvPacket.

Note

Data sent to the loop-back address 127.0.0.1 (localhost) does not actually register with WinPCap because it never actually moves through the network card.

Using PacketX and WinPCap

The following example uses BeeSync’s packetX control (www.beesync.com) to illustrate the concept. There would be no problem in using rvPacket for this example, but packetX is a useful alternative to know how to use. The object of the example is to log packets that match a certain criterion. In this case, only TCP/IP traffic will be logged.

TCP/IP traffic can be isolated from raw network traffic by checking two bytes in the packet. In an IP packet, the IP header follows the frame header and, thus, will appear at the 14th byte in the packet. The first byte in the IP header will always be 69 when IPv4 is used with standard priority. The second byte to check is the protocol byte, the 10th byte in the IP header. This byte will always be 6 when TCP/IP is used.

You will need to have downloaded and installed both WinPCap and PacketX before starting to code this program. Start a new project in Visual Studio .NET, right-click on the toolbox on the left, and click Customize Toolbox (or Add/Remove Items in Visual Studio .NET 2003), click the COM tab, check PacketXCtrl Class, and press OK. Drag the new icon onto the form. Draw a List View control named lvPackets onto the form as well as a Start button named btnStart.

To start with, add a few column headers into the list view so that the results it displays will be evenly tabulated. Add the following lines of code to the load event:

C#

private void Form1_Load(object sender, System.EventArgs e)
{
  lvPackets.Columns.Add("From", lvPackets.Width / 3,
                          HorizontalAlignment.Left);
  lvPackets.Columns.Add("To", lvPackets.Width / 3,
                          HorizontalAlignment.Left);
  lvPackets.Columns.Add("Size", lvPackets.Width / 3,
                          HorizontalAlignment.Left);
  lvPackets.View = View.Details;
}

VB.NET

Private Sub Form1_Load(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles MyBase.Load
 With lvPackets
  .Columns.Add("From", .Width / 3, HorizontalAlignment.Left)
  .Columns.Add("To", .Width / 3, HorizontalAlignment.Left)
  .Columns.Add("Size", .Width / 3, HorizontalAlignment.Left)
  .View = View.Details
 End With
End Sub

The PacketX control will not start detecting packets until the Start method is called. This is to facilitate choosing nondefault adapters:

C#

private void btnStart_Click(object sender, System.EventArgs
e)
{
 axPacketXCtrl1.Start();
}

VB.NET

Private Sub btnStart_Click(ByVal eventSender As _
    System.Object, ByVal eventArgs As System.EventArgs) _
    Handles Command1.Click
  axPacketXCtrl1.Start()
End Sub

Unlike the polling mechanism of the rvPacket library, PacketX uses an event to notify the host application of the arrival of packets. The event delivers an object that effectively derives from System.EventArgs, yet contains a PacketClass object that contains information on the packet contents and the exact time (with microsecond accuracy) the packet was received.

The packet contents are stored in a byte array named Data. This byte array appears to .NET as a generic object; thus, to handle it without causing type cast errors, Option Strict Off must be added as the first line of the VB.NET code:

C#

private void axPacketXCtrl1_OnPacket(object sender,
AxPACKETXLib._IPktXPacketXCtrlEvents_OnPacketEvent e)
{
  short I;
  string thisPacket;
  string SourceIP;
  string DestIP;
  ListViewItem item = new ListViewItem();
    thisPacket = "";
  byte[] packetData = (byte[])e.pPacket.Data;
  for (I = 0;I<e.pPacket.DataSize - 1;I++)
  {
    thisPacket = thisPacket + Convert.ToChar(packetData[I]);
  }
  if (packetData[14] == 69 && packetData[23] == 6)
  {
    SourceIP = packetData[26] + "." +
      packetData[27] + "." +
      packetData[28] + "." +
      packetData[29];

    DestIP = packetData[30] + "." +
      packetData[31] + "." +
      packetData[32] + "." +
      packetData[33] + ".";

   item.SubItems[0].Text = SourceIP;
   item.SubItems.Add(DestIP);
   item.SubItems.Add(e.pPacket.DataSize.ToString());
   lvPackets.Items.Add(item);
  }
}

VB.NET

Private Sub axPacketXCtrl1_OnPacket(ByVal eventSender _
     As System.Object, ByVal e As _
     AxPACKETXLib.IPktXPacketXCtrlEvents_OnPacketEvent) _
    Handles axPacketXCtrl1.OnPacket
 Dim I As Short
 Dim thisPacket As String
 Dim SourceIP As String
 Dim DestIP As String
 Dim item As New ListViewItem()

 thisPacket = ""
 For I = 0 To e.pPacket.DataSize - 1
   thisPacket = thisPacket & Chr(eventArgs.pPacket.Data(I))
 Next
 If e.pPacket.Data(14) = 69 And e.pPacket.Data(23) = 6 Then
  SourceIP = e.pPacket.Data(26) & "." & _
             e.pPacket.Data(27) & "." & + _
             e.pPacket.Data(28) & "." & + _
             e.pPacket.Data(29)
  DestIP = e.pPacket.Data(30) & "." & _
           e.pPacket.Data(31) & "." & + _
           e.pPacket.Data(32) & "." & + _
           e.pPacket.Data(33)
   item.SubItems(0).Text = SourceIP
   item.SubItems.Add(DestIP)
   item.SubItems.Add(e.pPacket.DataSize)
   lvPackets.Items.Add(item)
  End If
End Sub

The actual network packet that is passed within the eventArgs or e parameter of the event takes the form of an object stored in e.pPacket.Data, which can be cast to a byte array (implicitly so, in the case of VB.NET). This array is examined for key bytes, first to filter out non-TCP/IP data and then to extract the Local and Remote IP addresses from the header. The extracted data is displayed on-screen in a list box.

To test this application, run it from Visual Studio .NET and wait for a TCP/IP connection to take place on the network. Alternately, simply opening a browser should generate a TCP/IP connection to the server hosting your browser’s home page.

The example shown in Figure 13.4 is one single HTTP request between two computers on a LAN. Note that it does not involve simply one packet for the request and one for the response, but a fair amount of handshaking takes place between client and server, before a connection is made. This may be worth knowing if, for instance, you were using a TCP trace to build up statistics on user browsing habits. You cannot equate the number of packets to the amount of Web pages or emails sent. It might be better to count occurrences of the string HTTP/1.1 or HELLO in outgoing packets on ports 80 and 25, respectively, in this instance.

Frame-layer packet sniffer with PacketX.

Figure 13.4. Frame-layer packet sniffer with PacketX.

A busy network may produce an overwhelming number of packets, and it is likely that .NET will not be able to process 10 Mb of packets per second, as is commonplace on LANs. In this case, we can use hardware filters that are built into network cards to cope with high-volume traffic.

To detect only packets destined for the local machine, we can apply the directed packet hardware filter to the WinPCap driver by setting a parameter in the PacketX object with:

PacketXCtrl1.Adapter.HWFilter = 1

The default hardware filter is promiscuous mode, which will pass up every packet seen by the network adapter. The rvPacket library only operates in promiscuous mode. Wireless network cards cannot operate in promiscuous mode; therefore, a nonpromiscuous hardware filter (Table 13.9) must be applied for wireless devices.

Table 13.9. WinPCap hardware filters.

Filter ID

Purpose

1

Directed packets that contain a destination address equal to the station address of the NIC

2

Multicast address packets sent to addresses in the multicast address list

4

All multicast address packets, not just the ones enumerated in the multicast address list

8

Broadcast packets

16

All source routing packets

32

Default, promiscuous mode; specifies all packets

64

SMT packets that an FDDI NIC receives

128

All packets sent by installed protocols

4096

Packets sent to the current group address

8192

All functional address packets, not just the ones in the current functional address

16384

Functional address packets sent to addresses included in the current functional address

32768

NIC driver frames that a Token Ring NIC receives

WinPCap also has the capability to send and receive packets. This functionality can be accessed through Adapter.SendPacket, which could be useful for generating non-IP-based packets, such as ARP requests or raw server message block (SMB) data. These packets would not be routable over the Internet, but they may have applications within company networks.

Physical network tapping

Although there would be no conceivable reason for software to read data at this low level, it might be important to know whether the phone line is connected to the computer or not.

A program might also want to determine the type of connection the computer has to the Internet. To cite an example, when developing a peer-to-peer network, clients that have a fast connection via a LAN should be given higher weighting in the index server(s) than 56K dial-up connections. This would ensure that new clients do not waste time attempting to connect to dial-up connections, which would be more than likely disconnected, but instead run queries against more reliable, faster connections.

The Adapter.LinkType and Adapter.LinkSpeed properties of PacketX provide information on the network type (Table 13.10) and link speed in bits per second, respectively.

Table 13.10. Link types.

Link Type Code

Meaning

0

None

1

Ethernet (802.3)

2

Token Ring (802.5)

3

FDDI (Fiber Distributed Data Interface)

4

WAN (Wide Area Network)

5

LocalTalk

6

DIX (DEC- Intel - Xerox)

7

ARCNET (raw)

8

ARCNET (878.2)

9

ATM (Asynchronous Transfer Mode)

10

Wireless

Using WinPCap and PacketX may seem like overkill to determine whether a computer is connected to the Internet, but you could, of course, always ping a well-known Web site address or use the getInternetConnectedState API function call.

In .NET version 2 (Whidbey), the NetworkInformation class provides a simple mechanism to determine whether a computer is connected to the network as follows:

C#

NetworkInformation netInfo = new NetworkInformation();
If (netInfo.GetIsConnected() == true)
{
 // connected to network
}

VB.NET

Dim netInfo as new NetworkInformation()
If (netInfo.GetIsConnected()= True)
 ' connected to network
end if

The NetworkInformation class (Table 13.11) inherits from System.Net.NetworkInformation. It contains a host of useful properties, which describe low-level network activities. The last five methods listed in table 13.11 may be alternatively retrieved from the GetNetworkParams Windows API function.

Table 13.11. Significant members of the NetworkInformation class.

Method or Property

Purpose

AddressChanged

Sets AddressChangedEventHandler (Object, EventArgs) delegate.

GetActiveUdpListeners

Lists all active UDP ports. Returns ActiveUdpListener[].

GetIcmpV4Statistics

Retrieves statistics of ping (ICMP) activity. Returns IcmpV4Statistics.

GetIPStatistics

Retrieves statistics of IP activity. Returns IPStatistics.

GetIsConnected

Determines if the computer is connected to the network. Returns Boolean.

GetNetworkInterfaces

Retrieves information about connected network hardware. Returns NetworkInterface[].

GetTcpConnections

Retrieves statistics of TCP/IP activity. Returns TcpStatistics.

GetUdpStatistics

Retrieves statistics of UDP/IP activity. Returns UdpStatistics.

DhcpScopeName

Gets the DHCP scope name. Returns String.

DomainName

Gets the locally registered domain name. Returns String.

HostName

Gets the host name for the local computer. Returns String.

IsWinsProxy

Specifies if the computer is acting as a WINS proxy. Returns Boolean.

NodeType

Gets the NetBIOS node type of the computer. Returns NodeType (e.g., broadcast, P2P, mixed, hybrid).

The ActiveUdpListener class, as returned by GetActiveUdpListeners, is descried in Table 13.12. This is equivalent to calling the GetUdpTable Windows API, or running NETSTAT -p udp -a from the command line.

Table 13.12. Significant members of the ActiveUdpListener class.

Method or Property

Purpose

LocalEndPoint

The logical location of the port holding the active UDP connection. Returns IPEndPoint

The IcmpV4Statistics class, as returned by GetIcmpV4Statistics, is described in Table 13.13 (all properties return int64 unless otherwise specified). This class is equivalent to the GetIcmpStatistics Windows IP Helper API.

Table 13.13. Significant members of the IcmpV4Statistics class.

Method or Property

Purpose

AddressMaskRepliesReceived

Gets the number of address mask replies received

AddressMaskRepliesSent

Gets the number of address mask replies sent

AddressMaskRequestsReceived

Gets the number of address mask requests received

AddressMaskRequestsSent

Gets the number of address mask requests sent

DestinationUnreachableMessagesReceived

Gets the number of destination unreachable messages received

DestinationUnreachableMessagesSent

Gets the number of destination unreachable messages sent

EchoRepliesReceived

Gets the number of echo replies received

EchoRepliesSent

Gets the number of echo replies sent

EchoRequestsReceived

Gets the number of echo requests received

EchoRequestsSent

Gets the number of echo requests sent

ErrorsReceived

Gets the number of errors received

ErrorsSent

Gets the number of errors sent

MessagesReceived

Gets the number of messages received

MessagesSent

Gets the number of messages sent

ParameterProblemsReceived

Gets the number of parameter problems received

ParameterProblemsSent

Gets the number of parameter problems sent

RedirectsReceived

Gets the number of redirects received

RedirectsSent

Gets the number of redirects sent

SourceQuenchesReceived

Gets the number of source quenches received

SourceQuenchesSent

Gets the number of source quenches sent

TimeExceededMessagesReceived

Gets the number of time exceeded messages received

TimeExceededMessagesSent

Gets the number of time exceeded messages sent

TimestampRepliesReceived

Gets the number of timestamp replies received

TimestampRepliesSent

Gets the number of timestamp replies sent

TimestampRequestsReceived

Gets the number of timestamp requests received

TimestampRequestsSent

Gets the number of timestamp requests sent

The IPStatistics class, as returned by GetIPStatistics, is described in Table 13.14 (all properties return int64 unless otherwise specified). This is equivalent to calling the GetIpStatistics Windows IP Helper API, or running NETSTAT -s from the command line.

Table 13.14. Significant members of the IPStatistics class.

Method or Property

Purpose

DefaultTtl

Gets the default TTL

ForwardingEnabled

Determines if forwarding is enabled; returns Boolean

Interfaces

Gets the number of interfaces

IPAddresses

Gets the number of IP addresses

OutputPacketRequests

Gets the number of output packet requests

OutputPacketRoutingDiscards

Gets the number of output packet routing discards

OutputPacketsDiscarded

Gets the number of output packets discarded

OutputPacketsWithNoRoute

Gets the number of output packets with no route

PacketFragmentFailures

Gets the number of packet fragment failures

PacketReassembliesRequired

Gets the number of packet reassemblies required

PacketReassemblyFailures

Gets the number of packet reassembly failures

PacketReassemblyTimeout

Retrieves the packet reassembly timeout

PacketsFragmented

Gets the number of packets fragmented

PacketsReassembled

Gets the number of packets reassembled

ReceivedPackets

Gets the number of received packets

ReceivedPacketsDelivered

Gets the number of received packets delivered

ReceivedPacketsDiscarded

Gets the number of received packets discarded

ReceivedPacketsForwarded

Gets the number of received packets forwarded

ReceivedPacketsWithAddressErrors

Gets the number of received packets with address errors

ReceivedPacketsWithHeadersErrors

Gets the number of received packets with headers errors

ReceivedPacketsWithUnknownProtocol

Gets the number of received packets with unknown protocol

Routes

Gets the number of routes used

The NetworkInterface class, as returned by GetNetworkInterfaces, is described in Table 13.15.

Table 13.15. Significant members of the NetworkInterface class.

Method or Property

Purpose

GetInterfaceStatistics

Retrieves information on network activity on the interface. Returns InterfaceStatistics.

GetIPAddressInformation

Returns information on the IP address assigned to the interface. Returns IPAddressInformation.

GetIPv4Properties

Gets information concerning local IP routing, etc. Returns IPv4Properties.

GetPhysicalAddress

Retrieves the interface’s MAC address. Returns byte[].

Description

A friendly name for the interface. Returns String.

DnsEnabled

Determines if DNS is enabled on the interface. Returns Boolean.

DynamicDnsEnabled

Determines if Dynamic DNS is enabled on the interface. Returns Boolean.

Ipv4Index

Determines the IP version 4 index on the interface. Returns int64.

Ipv6Index

Determines the IP version 6 index on the interface. Returns int64.

IPVersionSupported

Determines the IP version(s) supported by the interface. Returns IPVersionSupportedFlags.

IsConnected

Determines if the interface is connected to an active network. Returns Boolean.

Mtu

Determines the maximum transmission unit of the interface. Returns int64.

Name

Gets a name for the interface. Returns string.

OperationalStatus

Gets the operational status of the interface. Returns OperationalStatus.

Type

Determines the interface hardware. Returns InterfaceType (e.g., modem, ISDN, ADSL, Ethernet, etc.).

The InterfaceStatistics class, as returned by GetInterfaceStatistics, is described in Table 13.16 (all properties return int64 unless otherwise specified).

Table 13.16. Significant members of the InterfaceStatistics class.

Method or Property

Purpose

BytesReceived

Gets the number of bytes received

BytesSent

Gets the number of bytes sent

IncomingPacketsDiscarded

Gets the number of incoming packets discarded

IncomingPacketsWithErrors

Gets the number of incoming packets with errors

IncomingUnknownProtocolPackets

Gets the number of incoming unknown protocol packets

NonUnicastPacketsReceived

Gets the number of non-Unicast packets received

NonUnicastPacketsSent

Gets the number of non-Unicast packets sent

OutgoingPacketsDiscarded

Gets the number of outgoing packets discarded

OutgoingPacketsWithErrors

Gets the number of outgoing packets with errors

OutputQueueLength

Gets the number of output queue length

Speed

Gets the speed of the interface

UnicastPacketsReceived

Gets the number of Unicast packets received

UnicastPacketsSent

Gets the number of Unicast packets sent

The IPAddressInformation class, as returned by GetIPAddressInformation, is described in Table 13.17.

Table 13.17. Significant members of the IPAddressInformation class.

Method or Property

Purpose

Address

Gets the IP address

DnsEligible

Determines if the address is eligible for DNS

Transient

Determines if the address is transient

The IPv4Properties class, as returned by GetIPv4Properties, is described in Table 13.18. These properties may be alternatively ascertained on an adapter-by-adapter basis through the GetAdaptersInfo Windows IP Helper API function.

Table 13.18. Significant members of the IPv4Properties class.

Method or Property

Purpose

GetDhcpServerAddresses

Retrieves the local DHCP server addresses. Returns IPAddress[].

GetGatewayAddresses

Retrieves the local gateway addresses. Returns IPAddress[].

GetWinsServersAddresses

Retrieves the local WINS servers addresses. Returns IPAddress[].

AutomaticPrivateAddressingActive

Determines if automatic private addressing is active. Returns Boolean.

AutomaticPrivateAddressingEnabled

Determines if automatic private addressing is enabled. Returns Boolean.

DhcpEnabled

Determines if DHCP is enabled. Returns Boolean.

RoutingEnabled

Determines if routing is enabled. Returns Boolean.

UsesWins

Determines if the computer uses WINS. Returns Boolean.

The TcpStatistics class, as returned by GetTcpStatistics, is described in Table 13.19 (all properties return int64 unless otherwise stated). This is equivalent to calling the GetTcpTable Windows IP Helper API, or running NETSTAT -p tcp -a from the command line.

Table 13.19. Significant members of the TcpStatistics class.

Method or Property

Purpose

ConnectionsAccepted

Determines the number of connections accepted

ConnectionsInitiated

Determines the number of connections initiated

CumulativeConnections

Determines the number of cumulative connections

CurrentConnections

Determines the number of current connections

ErrorsReceived

Determines the number of errors received

FailedConnectionAttempts

Determines the number of failed connection attempts

MaximumConnections

Determines the maximum number of connections

MaximumTransmissionTimeOut

Determines the maximum transmission time out

MinimumTransmissionTimeOut

Determines the minimum transmission time out

ResetConnections

Determines the number of reset connections

SegmentsReceived

Determines the number of segments received

SegmentsResent

Determines the number of segments resent

SegmentsSent

Determines the number of segments sent

SegmentsSentWithReset

Determines the number of segments sent with reset

The UdpStatistics class, as returned by GetUdpStatistics, is described in Table 13.20 (all properties return int64 unless otherwise stated). This is equivalent to the GetUdpStatistics Windows IP Helper API function.

Table 13.20. Significant members of the UdpStatistics class.

Method or Property

Purpose

DatagramsReceived

Determines the number of datagrams received

DatagramsSent

Determines the number of datagrams sent

IncomingDatagramsDiscarded

Determines the number of incoming datagrams discarded

IncomingDatagramsWithErrors

Determines the number of incoming datagrams with errors

UdpListeners

Determines the number of active UDP listeners

Conclusion

This chapter has shown three different means to tap nonintrusively into the data that flows between computers. When local system traffic monitoring is all that is required, then use of the pure .NET implementation is highly recommended, but for an enterprisewide implementation, then PacketX combined with WinPCap is possibly the best option. Where financial constraints prevent the use of a third-party commercial component, then rvPacket will probably point you in the right direction.

It would be impossible to document the format of every protocol that could exist on a network, so only IP and TCP have been described in this chapter. Interested readers are advised to consult the relevant RFC for information on any specific protocol.

The next chapter deals with a form of telecommunication that has been with us since the 1880s (i.e., the ubiquitous phone call); however, the chapter is taken from a Computer Telephony Integration (CTI) developer’s perspective. Prepare to be introduced to the telephony API.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.206.225