|
C++ Raw Socket IGMP Program Example
Create a new CLR console application project and you might use RawSocketIGMPCP as the name.
|
Add/edit the following using directives at the top of the file.
using namespace System; using namespace System::Net; using namespace System::Net::Sockets; using namespace System::Collections; // Reference the protocol header classes using namespace ProtocolHeaderDefinitionCP; |
Build the project to see the included reference to the DLL is working and accessible.
Add the following usage() function.
static void usage() { Console::WriteLine("Executable_file_name [-c send-count] [-g x.y.z.w] [-i a.b.c.d] [-p pad]"); Console::WriteLine("Available options:"); Console::WriteLine(" -g x.y.z.w - Multicast group to send query for"); Console::WriteLine(" -i a.b.c.d - Local interface to send query on"); Console::WriteLine(" -p pad-bytes - Number of pad bytes at end of packet"); Console::WriteLine(" -c send-count - Number of times to send query"); Console::WriteLine(); } |
Next, add the main() code.
int main(array<System::String ^> ^args) { IPAddress^ groupAddress = IPAddress::Parse("234.6.7.8"); IPAddress^ localAddress = IPAddress::Any; int padByteCount = 0, sendCount = 5;
// Parse the command line if(args->Length) { for (int i = 0; i < args->Length; i++) { try { if ((args[i][0] == '-') || (args[i][0] == '/')) { switch (Char::ToLower(args[i][1])) { case 'c': // Number of times to send packet sendCount = Convert::ToInt32(args[++i]->ToString()); break; case 'g': // Multicast group groupAddress = IPAddress::Parse(args[++i]->ToString()); break; case 'i': // Local interface to send query from localAddress = IPAddress::Parse(args[++i]->ToString()); break; case 'p': // Amount of pad data padByteCount = Convert::ToInt32(args[++i]->ToString()); break; default: usage(); return 0; } } } catch(Exception^ err) { Console::WriteLine("Error: " + err->Message); usage(); return 0; } } } else { usage(); return 0; }
// Display the parameter Console::WriteLine("Sending query for group: {0}", groupAddress->ToString()); Console::WriteLine("Sending on interface : {0}", localAddress->ToString()); Console::WriteLine("Number of pad bytes : {0}", padByteCount); Console::WriteLine("Send count : {0}", sendCount);
IgmpHeader^ igmpHeader = gcnew IgmpHeader(); Ipv4Header^ ipv4Header = gcnew Ipv4Header(); ArrayList^ headerList = gcnew ArrayList(); IPEndPoint^ igmpDestination = gcnew IPEndPoint(IgmpHeader::AllSystemsAddress, 0); IPEndPoint^ localEndpoint = gcnew IPEndPoint(localAddress, 0); Socket^ igmpSocket; array<Byte>^ igmpPacket; array<Byte>^ padBytes;
// Build the IPv4 header Console::WriteLine("Building the IPv4 header..."); ipv4Header->Version = 4; ipv4Header->Protocol = (Byte)ProtocolType::Igmp; ipv4Header->Ttl = 1; ipv4Header->Offset = 0; ipv4Header->Length = 20; ipv4Header->TotalLength = (unsigned short)Convert::ToUInt16(IgmpHeader::IgmpHeaderLength + padByteCount); ipv4Header->SourceAddress = localAddress; ipv4Header->DestinationAddress = IgmpHeader::AllSystemsAddress;
// Add the header to the list of headers Console::WriteLine("Adding the header to the list of headers..."); headerList->Add(ipv4Header);
// Build the IGMP header igmpHeader->VersionType = IgmpHeader::IgmpMembershipQuery; igmpHeader->MaximumResponseTime = 100; igmpHeader->GroupAddress = groupAddress;
// Allocate pad bytes as necessary Console::WriteLine("Allocating pad bytes as necessary..."); padBytes = gcnew array<Byte>(padByteCount);
// Add the IGMP header to the list of headers Console::WriteLine("Adding the IGMP header to the list of headers..."); headerList->Add(igmpHeader);
// Build the packet Console::WriteLine("Building the packet..."); igmpPacket = igmpHeader->BuildPacket(headerList, padBytes);
// Create the raw socket Console::WriteLine("Creating the raw socket, Socket()..."); igmpSocket = gcnew Socket( groupAddress->AddressFamily, SocketType::Raw, ProtocolType::Igmp );
// Bind to a local interface Console::WriteLine("Binding to a local interface, Bind()..."); igmpSocket->Bind(localEndpoint);
// Set the HeaderIncluded option Console::WriteLine("Setting the HeaderIncluded option..."); igmpSocket->SetSocketOption(SocketOptionLevel::IP, SocketOptionName::HeaderIncluded, 1);
// Send the packet the requested number of times Console::WriteLine("Send the packet the requested number of times..."); for (int i = 0; i < sendCount; i++) { int rc = igmpSocket->SendTo(igmpPacket, igmpDestination);
Console::WriteLine("send {0} bytes to {1}", rc, igmpDestination->ToString()); } return 0; } |
Next, build the project and make sure there is no error. Then, run the project. Any error will be thrown by the exception handlers. The following is the sample output.
The following is the sample output when run at command prompt.
![]() |
|
Create a new console application project and you might use RawSocketIGMPCS as the name.
Next, rename the class to RawSocketIGMP to reflect the application that we are going to develop.
Add/edit the following using directives at the top of the file.
using System; using System.Net; using System.Net.Sockets; using System.Collections; // Reference the protocol header classes using ProtocolHeaderDefinition; |
Add the following method in the class.
static void usage() { Console.WriteLine("Executable_file_name [-c send-count] [-g x.y.z.w] [-i a.b.c.d] [-p pad]"); Console.WriteLine("Options:"); Console.WriteLine(" -g x.y.z.w - Multicast group to send query for"); Console.WriteLine(" -i a.b.c.d - Local interface to send query on"); Console.WriteLine(" -p pad-bytes - Number of pad bytes at end of packet"); Console.WriteLine(" -c send-count - Number of times to send query"); Console.WriteLine("...Else, default values will be used..."); Console.WriteLine(); } |
Next, add the Main() code.
static void Main(string[] args) { IPAddress groupAddress = IPAddress.Parse("234.6.7.8"), localAddress = IPAddress.Any; int padByteCount = 0, sendCount = 5;
usage(); Console.WriteLine();
// Parse the command line for (int i = 0; i < args.Length; i++) { try { if ((args[i][0] == '-') || (args[i][0] == '/')) { switch (Char.ToLower(args[i][1])) { case 'c': // Number of times to send packet sendCount = System.Convert.ToInt32(args[++i].ToString()); break; case 'g': // Multicast group groupAddress = IPAddress.Parse(args[++i].ToString()); break; case 'i': // Local interface to send query from localAddress = IPAddress.Parse(args[++i].ToString()); break; case 'p': // Amount of pad data padByteCount = System.Convert.ToInt32(args[++i].ToString()); break; default: usage(); return; } } } catch { usage(); return; } }
// Display the parameter Console.WriteLine("Sending query for group: {0}", groupAddress.ToString()); Console.WriteLine("Sending on interface : {0}", localAddress.ToString()); Console.WriteLine("Number of pad bytes : {0}", padByteCount); Console.WriteLine("Send count : {0}", sendCount);
IgmpHeader igmpHeader = new IgmpHeader(); Ipv4Header ipv4Header = new Ipv4Header(); ArrayList headerList = new ArrayList(); IPEndPoint igmpDestination = new IPEndPoint(IgmpHeader.AllSystemsAddress, 0), localEndpoint = new IPEndPoint(localAddress, 0); Socket igmpSocket; byte[ ] igmpPacket, padBytes;
// Build the IPv4 header Console.WriteLine("Building the IPv4 header..."); ipv4Header.Version = 4; ipv4Header.Protocol = (byte)ProtocolType.Igmp; ipv4Header.Ttl = 1; ipv4Header.Offset = 0; ipv4Header.Length = 20; ipv4Header.TotalLength = (ushort)System.Convert.ToUInt16(IgmpHeader.IgmpHeaderLength + padByteCount); ipv4Header.SourceAddress = localAddress; ipv4Header.DestinationAddress = IgmpHeader.AllSystemsAddress;
// Add the header to the list of headers Console.WriteLine("Adding the header to the list of headers..."); headerList.Add(ipv4Header);
// Build the IGMP header igmpHeader.VersionType = IgmpHeader.IgmpMembershipQuery; igmpHeader.MaximumResponseTime = 100; igmpHeader.GroupAddress = groupAddress;
// Allocate pad bytes as necessary Console.WriteLine("Allocating pad bytes as necessary..."); padBytes = new byte[padByteCount];
// Add the IGMP header to the list of headers Console.WriteLine("Adding the IGMP header to the list of headers..."); headerList.Add(igmpHeader);
// Build the packet Console.WriteLine("Building the packet..."); igmpPacket = igmpHeader.BuildPacket(headerList, padBytes);
// Create the raw socket Console.WriteLine("Creating the raw socket, Socket()..."); igmpSocket = new Socket( groupAddress.AddressFamily, SocketType.Raw, ProtocolType.Igmp );
// Bind to a local interface Console.WriteLine("Binding to a local interface, Bind()..."); igmpSocket.Bind(localEndpoint);
// Set the HeaderIncluded option Console.WriteLine("Setting the HeaderIncluded option..."); igmpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);
// Send the packet the requested number of times Console.WriteLine("Send the packet the requested number of times..."); for (int i = 0; i < sendCount; i++) { int rc = igmpSocket.SendTo(igmpPacket, igmpDestination);
Console.WriteLine("send {0} bytes to {1}", rc, igmpDestination.ToString()); } } |
We need to add references to the Protocol.cs so that all the definition defined in the ProtocolHeaderDefinition can be resolved. Select the project folder > Right click mouse > Select Add context menu > Select Existing Item context menu.
Browse and find the Protocol.cs file created previously. Select the file and click Add.
You can see the Protocol.cs file is included under the project folder as shown in the following Figure.
Next, build the project and make sure there is no error.
Then, run the project. Any error will be thrown by the exception handlers.
The following is the sample output.
The following is the sample output when run at command prompt.