Cannot convert from SharpPcap.RawCapture to PacketDotNet.Packet - c#

I've been following the guide over at http://www.codeproject.com/KB/IP/sharppcap.aspx for implementing a simple packet sniffer to automate authentications for me, I've managed to get to the Filtering section, and have had to make some adjustments to the tutorial code so far for it to work, but I am now stumped.
The error I am receiving is;
The best overloaded method match for 'PacketDotNet.TcpPacket.GetEncapsulated(PacketDotNet.Packet)' has some invalid arguments
Argument 1: cannot convert from 'SharpPcap.RawCapture' to 'PacketDotNet.Packet'
But I've yet to make any references to PacketDotNet my self (everything so far has been SharpPcap).
Entire code I have so far is included, the problem is in the device_OnPacketArrival() function.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PacketDotNet;
using SharpPcap;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string ver = SharpPcap.Version.VersionString;
Console.WriteLine("SharpPcap {0}, Example1.IfList.cs", ver);
// Retrieve the device list
CaptureDeviceList devices = CaptureDeviceList.Instance;
// If no devices were found print an error
if (devices.Count < 1)
{
Console.WriteLine("No devices were found on this machine");
return;
}
// Extract a device from the list
ICaptureDevice device = devices[0];
// Register our handler function to the
// 'packet arrival' event
device.OnPacketArrival +=
new SharpPcap.PacketArrivalEventHandler(device_OnPacketArrival);
// Open the device for capturing
int readTimeoutMilliseconds = 1000;
device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
// tcpdump filter to capture only TCP/IP packets
string filter = "ip and tcp";
device.Filter = filter;
Console.WriteLine();
Console.WriteLine("-- The following tcpdump filter will be applied: \"{0}\"",
filter);
Console.WriteLine("-- Listening on {0}, hit 'Enter' to stop...",
device.Description);
// Start capturing packets indefinitely
device.Capture();
// Close the pcap device
// (Note: this line will never be called since
// we're capturing indefinitely
device.Close();
}
private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
var tcp = TcpPacket.GetEncapsulated(e.Packet);
}
}
}

A SharpPcap.RawPacket is used to hold the raw data captured over the network adapter but PacketDotNet needs the packet parsed before the GetEncapsulated() methods will work. The step you need will look like:
var packet = PacketDotNet.Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);
Then you can extract the encapsulated TcpPacket via the GetEncapsulated() method by passing it packet.
Example 12 in the SharpPcap source download at https://sourceforge.net/projects/sharppcap/ shows the syntax and how packets can be modified.
Keep in mind that PacketType.GetEncapsulated() is returning a reference to that portion of the packet so modifying it will alter the original packet.

As an update to Chris Morgan's answer (because I find myself doing this today), getEncapsulated() is now obsolete, instead you should use packet.Extract() to extract the encapsulated packet.

Alternatively, you can use Pcap.Net, which only has one Packet class that you can dynamically parse to get whatever it may contain without doing any packet cast.
You just get a Packet object and do (for example):
uint sequenceNumber = packet.Ethernet.IpV4.Tcp.SequenceNumber;
No need to cast it or know what kind of packet it is in advance, all parsing is done dynamically.

Related

Read Pulse value from Coin selector using Rasbperry PI 4 in C# Console Application

Hello guy i have problem in my code it always says low even i already insert coin in Coin Selector
using System;
using System.Device.Gpio;
using System.Threading;
try
{
Thread.Sleep(1000);
int pin = 16;
using var controller = new GpioController();
controller.OpenPin(pin, PinMode.Input);
while (true)
{
String ButtonState = controller.Read(pin).ToString();
Console.WriteLine(ButtonState); //checking the state if the digital value is changing
Thread.Sleep(1000);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Thread.Sleep(10000);
}
This is my current code and I already configure the coin selector.. How can i read the pulse value from the selector?
My wiring is the coin wire is connected to gpio pins (like gpio 16)
I already tried different types of wiring and code but still not working
I believe you are using the wrong pin. GPIO16 = pin36 and pin16 = GPIO23.
https://roboticsbackend.com/raspberry-pi-gpios-default-state/
Here is an picture of the pin layout.
There are multiple libraries that use different layouts so make sure you look at the documentation provided by these libraries.
Good luck!

C# Receive Multicast UDP in multiple programs on the same machine?

Thanks in advance for any help.
There is a program, not written by me that sends UDP multicast packets of info on the local LAN. I've looked the source and it appears they are correctly setup to multicast. This program is WSJT-X which if you are a Ham operator you might have heard of.
The UDP packets contain over the air signal decodes so lots of other programs including mine are interested in these packets.
The problem I'm having is that my UDP receive seems to consume the messages so no other software running on the same machine seems to receive them once my test software starts up.
Here is simple receiver:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ReadUDP
{
internal class Program
{
private static void Main(string[] args)
{
// Setup
int port = 2237;
var multicastIP = IPAddress.Parse("225.0.0.1");
// Create endpoints
var remoteEndPoint = new IPEndPoint(multicastIP, port);
var localEndPoint = new IPEndPoint(IPAddress.Any, port);
// Create and configure UdpClient
var udpclient = new UdpClient();
udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpclient.ExclusiveAddressUse = false;
udpclient.Client.MulticastLoopback = true;
udpclient.MulticastLoopback = true;
// Bind, Join
udpclient.Client.Bind(localEndPoint);
udpclient.JoinMulticastGroup(multicastIP, IPAddress.Any);
Task.Run(() =>
{
IPEndPoint sender = new IPEndPoint(0, 0);
while (true)
{
var recvBuffer = udpclient.Receive(ref sender);
var recvStr = Encoding.UTF8.GetString(recvBuffer);
Console.WriteLine("--------------------------------------------------------------------------");
Console.WriteLine($"From:{sender} Data:{recvStr}");
Console.WriteLine("--------------------------------------------------------------------------");
}
});
Console.ReadLine();
}
}
}
This simple program receives the data sent by WSJT-X just fine.
If I clone this project to a new directory, build a new copy of the program and run it, the copy never receives any of the broadcast data while the first copy is running. Only the first running copy gets data.
If I shutdown the first copy then the second copy starts to receive the data.
This acts like the first copy is consuming the message and no other clients receive it. I'm trying to prevent that. I just want to in effect, "peek" at the messages and allow other clients to receive them.
I've tried a a bunch of different options and settings, I've looked at many examples but I have not been able to solve this issue.
Any help would be greatly appreciated.
For those of you that don't have WSJT-X, the following simple UDP sender will send UDP packets:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ReadUDP
{
internal class Program
{
private static void Main(string[] args)
{
// Setup
int port = 2237;
var multicastIP = IPAddress.Parse("225.0.0.1");
// Create endpoints
var remoteEndPoint = new IPEndPoint(multicastIP, port);
var localEndPoint = new IPEndPoint(IPAddress.Any, port);
// Create and configure UdpClient
var udpclient = new UdpClient();
udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpclient.ExclusiveAddressUse = false;
udpclient.Client.MulticastLoopback = true;
udpclient.MulticastLoopback = true;
// Bind, Join
udpclient.Client.Bind(localEndPoint);
udpclient.JoinMulticastGroup(multicastIP, IPAddress.Any);
Task.Run(() =>
{
int msgnum = 1;
while (true)
{
var msg = $"Sending message {msgnum++}";
Console.WriteLine("--------------------------------------------------------------------------");
Console.WriteLine($"Send: {msg}");
Console.WriteLine("--------------------------------------------------------------------------");
var bytes = Encoding.UTF8.GetBytes(msg);
udpclient.Send(bytes, bytes.Length, remoteEndPoint);
Task.Delay(2000).Wait();
}
});
Console.ReadLine();
}
}
}
I am doing much the same thing but in VB.net.
WSJT-x runs on my "HamPC" and sends the udp packets to my "Programming" PC for decode.
Program skims the callsigns and looks up the stations Country/State via QRZ's XML service and plays a sound when a new state or country shows up on the band I am listening to.
I have yet to run 2 instances of my program on the "ProgrammingPC" but if I run into what you have I would add code so that the first running instance of my program will rebroadcast all of the packets exactly as received to another port for the second instance of my program to receive.
I found this thread looking for information on finding the Band information in the UDP packets transmitted by WJST-x. I've found and decoded the AudioFreq, TimeStamp and Signal Strength fields easily enough, now I'm scouring the data to locate the Band/Frequency which I need. Was easy in the first generation of my program which repeated read the all.txt file every 15 seconds at 01 16 31 and 41 seconds after the minute and determines which records are new (via simple line counting)
I have Googled high and low but cannot find a published structure of wjst-x's UDP packets - mainly offsets of the fields / how to decode them. I found the fields mentioned above by capturing the UDP packets looking at the contents byte by byte and comparing to the all.txt file for records written during the same transmissions.
The Band/Freq field should be the last one I need.
I believe my suggestion and retransmitting the packets intact to another port for the 2nd instance to receive on will work for you.
Program starts up unware if it is the 1st instance or not. It listen's on the primary port -- If data received on primary uses that port for receive and rebroadcasts the data as received to the 2nd port.
If no data was received on the 1st port it would switch and to listen on the 2nd port and not rebroadcast the data.
Perhaps a bandaid of a workaround but should work.
Best of luck! - 73 ne5B

Two-way communication between C# WPF application and python script

I'm trying to get a tow-way communication between a c# application and a python script that c# will call.
I have some input channels in c# that changes constantly at high frequency (5000-1000 data/s) for let's say a minute. On every change of those inputs,results are calculated and assigned to output variables. What i'm trying to do is to move the logic to a python script. For instance:
Inputs: double x,y
Output: double z
So the pyhton script should be capable of read the inputs, perform the logic and write the results at a symilar frequency.
Any recomendations? Has anyone did anything similar before?
First I tried to call the script on every change and read the console output. But the code in the script is not as simple as z=x*y and variables that store values are required in the pyhon script. For example, the script mught want to save the maximum value of x and y reached.
I had a look to ZeroMQ library for the communication, not sure how to use it though.
Here is a solution:
Simple C# program: client which sends data and receive
using System;
using ZeroMQ;
namespace ZeroMQ_Client
{
class Program
{
static void Main(string[] args)
{
using (var requester = new ZSocket(ZSocketType.REQ))
{
// Connect
requester.Connect("tcp://127.0.0.1:5555");
for (int n = 0; n < 10; ++n)
{
string requestText = "Hello";
Console.Write("Sending {0}...", requestText);
// Send
requester.Send(new ZFrame(requestText));
// Receive
using (ZFrame reply = requester.ReceiveFrame())
{
Console.WriteLine(" Received: {0} {1}!", requestText, reply.ReadString());
}
}
}
}
}
}
python program, you have to install pyzmq:
#
# Hello World server in Python
# Binds REP socket to tcp://*:5555
# Expects b"Hello" from client, replies with b"World"
#
import time
import zmq
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5555")
while True:
# Wait for next request from client
message = socket.recv()
print("Received request: %s" % message)
# Do some 'work'
time.sleep(1)
# Send reply back to client
socket.send(b"World")

c# serial read doesn't do function on certain serial input

I have a program that reads serial data from an arduino through a com port.
It works successfully when i program it to print the serial data onto a console, and it does so.
For example, the arduino says outputs "21", and the console writes "21".
But if I make an if statement saying If(data == "21"){/*dosomething*/}
it doesnt work even if the data is printed as "21".
Here are the parts of my code related to this issue.
Arduino
if(digitalRead(i) == HIGH && stat[i-2] == false){
Serial.print(i); Serial.println(1);
stat[i-2] = true;
}
The arduino code is kind of difficult to understand without the rest of the code, but all it does is scans all the ports to see if one of them is high. If it is, it prints the port number and a 1 next to it. For example if port 2 is high, it outputs "21". The same happens when port 2 is low, it outputs "20".
C# (an event handler)
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort serialPort1 = sender as SerialPort;
string dataString = (serialPort1).ReadLine();
screen.clearline();
Console.Write(dataString);
if (dataString == "connectAlready")
{
connect.con();
}
if (dataString == "20")
{
Console.WriteLine("pdown");
}
if (dataString == "21")
{
Console.WriteLine("pup");
}
}
This is the event handler called when data is received.
It prints data to the screen such as "21","20", but it does not perform the functions in the If statements.
Any help would be appreciated, thank you very much.
My guess is that the strings you are comparing aren't completely equal. Arduino's documentation for its println() function states that the serial print ends in a carriage return character ('\r'), followed by the newline character ('\n'). The SerialPort.ReadLine() function reads and returns the string "up to the NewLine value in the input buffer" (found here), so the '\r' character is probably still in dataString.
If this is your problem, you can solve it by removing the last character with something like:
dataString = dataString.TrimEnd('\r');

Read data from serial port device in c#

We need to weigh a bunch of products, and store their weight in a DB.
We have a scale that can be plugged through a serial port, and then we want to scan the product's barcode with a barcode scanner.
I need to write a program that will read the scale data. I have read and followed a bunch of articles on how to do it, but I can't seem to make it work.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Weighting
{
public partial class Form1 : Form
{
SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
public Form1()
{
this.InitializeComponent();
this.port.Open();
this.port.Encoding = Encoding.ASCII;
this.port.Handshake = Handshake.None;
this.port.RtsEnable = true;
this.port.ReceivedBytesThreshold = 1;
this.port.DataReceived += new SerialDataReceivedEventHandler(this.port_DataReceived);
}
~Form1()
{
this.port.Close();
this.port.Dispose();
}
private void button2_Click(object sender, EventArgs e)
{
try
{
char[] data = new char[] { 's', ' ', '\r', '\n' };
this.port.Write(data, 0, 1);
Thread.Sleep(500);
var InputData = this.port.ReadLine();
if (!string.IsNullOrEmpty(InputData))
{
MessageBox.Show(InputData);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var InputData = this.port.ReadLine();
this.BeginInvoke(new Action(() =>
{
MessageBox.Show(InputData);
}));
}
}
}
The DataReceived handler is never fired, and ReadLine() never returns anything.
The specs of the scale can be found here (chapter 10) : http://www.kern-sohn.com/manuals/files/English/FCB-BA-e-0911.pdf
Note that it's very possible that my serial port, or my cable don't work, or that the scale doesn't send data, or whatever (it's been about 15 years since I have used a serial port device). How can y test that everything works ?
Thank you!
Update
The connection parameters have been taken (and interpreted) from an old Excel macro:
With MSComm1
.CommPort = 1
.Handshaking = 0
.RThreshold = 1
.RTSEnable = True
.Settings = "9600,n,8,1"
.SThreshold = 1
.PortOpen = True
End With
This macro supposedly used to work a few years back, but I couldn't make it work myself (the MSComm1 object is not defined).
Your connection setup looks to match the documentation, but your code smells quite a bit (this is nothing against you, the .NET SerialPort is a nightmare to work with!).
You are not setting the SerialPort.NewLine property to Environment.NewLine (CRLF) and it is instead using the default value of \n (LF). This alone doesn't solve the problem, because you would just have a carriage return at end of the result of calling ReadLine().
The real issue is the DataReceived handler. A lot of people recommend using it but through my exhaustive testing it diminishes determinism of results greatly, particularly when communicating in a friendly encoding such as ASCII. Because you initiate the command by sending your s character, I would honestly get rid of it, and just call ReadLine() right after your Write. (You do not need to Thread.Sleep because ReadLine will simply block until the terminated string is read in or a timeout is reached).
Your ReceivedBytesThreshold is set to 1, and that specifies the buffer size to fill before raising DataReceived so you're trying to read a whole line for every byte received (give or take, DataReceived is very unpredictable).
Here's an example of how I would clean it up (in addition to removing the DataReceived handler). I can't be certain if this will clear your problem up, but making these corrections will lead to much easier debugging. As a temporary change to aid with debugging, you could bring your Sleep call back in and call ReadExisting instead of ReadLine and examine what it pulls (if anything) from the buffer.
private void button2_Click(object sender, EventArgs e)
{
try
{
this.port.Write("s");
var InputData = this.port.ReadLine();
if (!string.IsNullOrEmpty(InputData))
{
MessageBox.Show(InputData);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I've just finished writing a library to sit on top of the .NET SerialPort for my company and have run into the same sort of issues (plus a million more) as you. If you would like further clarification feel free to ask.
As pointed out by #user3894601, the problem was solved by using the original cable, and using a USB adapter.

Categories

Resources