How to reassemble TCP packets depending on tcp flags Value:
I'm expecting a code like this:
public void device_onPacketArrival(object sender, CaptureEventArgs e)
{
var tcpPacket=TcpPacket.GetEncapsulated(PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data));
if(tcpPacket.Allflags.toString()== something means that this is the last part of the fragmented packet)
stop reassampling procedure
else
continuing reassembling procedure
}
the only thing that I want is to know what the value of flags means that this is the last part of the fragemented packet?
Because you used %d, which is for decimal integers, instead of %f or %g for doubles.
Because %d is not the format specifier for a double, it's for an int. You should use the correct format string, such as %f.
The format specified "%d" defines an integer NOT a double variable.
Use "%e" or "%g".
Look up the printf format specifiers. %d is for integer values. What you want is probably %f or %e or %g or alike. Have a look at this example:
Example:
#include <stdio.h>
int main() {
double x = 3.141;
printf("%d\n", x);
printf("%e\n", x);
printf("%f\n", x);
printf("%g\n", x);
}
The output is:
$ gcc test.c && /a.out
154573528
3.141000e+00
3.141000
3.141
Note that printf is inherently type unsafe. In above example you see that the output using the integer format specifier is radically different from the others. That is because no conversion is performed, but the byte pattern is directly interpreted as another type, possibly causing invalid memory accesses thereby.
Disclaimer: Note that it's generally less dangerous to use printf then to use a chainsaw. But your mileage may vary if you don't care what end to hold in hands and which one to point at the wood you try to cut. Therefore, you should carefully look out for the documentation of the functions you use.
For reference:
http://en.cppreference.com/w/c/io/fprintf
you can't simply reassemble TCP packets, because its Flags doesn't have more bit or Don't fragment bit IP packet is the only one which has flags like that, so you can only reassemble IP packets using the Flags:
‘Don’t Fragment’ bit. When this bit is set then IP datagram is never fragmented, rather its thrown away if a requirement for fragment arises. The third bit represents the ‘More Fragment’ bit. If this bit is set then it represents a fragmented IP datagram that has more fragments after it. In case of last fragment of an IP datagram this bit is not set signifying that this is the last fragment of a particular IP datagram.
Might have already been said, but since you declared the array variable as a double data-type, you cannot all of a sudden print it using %d which is a data type for an integer. Therefore, I would use the %f or %lf to print it. The aforementioned should work better if you're dealing with double data types
Related
I am programming a messaging app that converts strings to and from unicode in order to later encrypt those strings.
Example from my code:
g = g + Char.ConvertFromUtf32(Convert.ToInt32(d));
This line works just fine but it only supports int 32 as input variables. And that's a problem as in some occasions depending on user input the conversion to int32 will fail due to size limitations of int32.
One solution I see is to limit user input, but that would compromise message security which I would rather avoid.
Any ideas on how to solve my problem?
The method Char.ConvertFromUtf32(Int32) does not convert any int32 into a string representing the Unicode point, but only values in the defined Unicode range:
Exceptions ArgumentOutOfRangeException
utf32 is not a valid 21-bit Unicode code point ranging from U+0
through U+10FFFF, excluding the surrogate pair range from U+D800
through U+DFFF.
Also, it's not clear what d is, and where it comes from.
I have a simple server written in c# listening on some port. I have an application in c++ and I need the application to send some information to the server. This information is a struct containing 5 integers. I was thinking that I can send it also as a string: something like: "ID=3, anotherInt=5...". Is it a good idea? If not, how should I do that?
How to make it work? What is your advice?
Thank you.
I think you have a mistake in your code.
char *ln = "String to send";
connect(client_socket, (struct sockaddr *)&clientService, sizeof(clientService));
send(client_socket,(const char*)&ln, sizeof(ln), 0);
The prototype for send function is:
ssize_t send(int socket, const void *message, size_t length, int flags);
ln is already a pointer to your char buffer. You are passing in &ln, which is the address
of the pointer. Shouldn't it be just "ln"?
You should fix the send() method in client code. sizeof() is wrong way to find the length of string, casts applied on "ln" aren't quite right for what you need there. Check <<this link>> for an example and see how it works for you. BTW, C# code in the server needs some serious re-writing if it were to work predictably. You are using 4096 byte buffer and calls to Read() aren't guaranteed to fetch the entire transmission in one go. You will need a loop just for Read to make sure you are reading everything you need - ofcourse, this needs a clear definition of communication semantics. Happy networking!
First of all, (const char*)&ln is not correct. ln is a char *, so when you take the address of it using & you are getting a char **, which you are then casting to a char *. This is undefined behavior. You'll want to get rid of the & operator. Also you'll probably want to read up on what pointers are and how to use them.
As a rule of thumb, don't cast willy-nilly to make the compiler shut up. The errors are trying to tell you something. However, the sockaddr and sockaddr_in thing is correct; the api is designed that way. If you turn on -Wall in your compiler options, it should give you a warning in the correct place.
ALSO: you want strlen(ln) and not sizeof.
Quick n Dirty Rundown on Pointers
When a type includes * before the variable name, the variable holds a pointer to a value of that type. A pointer is much like a reference in C#, it is a value holding the location of some data. These are commonly passed into functions when a function wants to look at a piece of data that the caller owns, sometimes because it wants to modify it. A string is represented as a char *, which is a pointer to the first character in the string. The two operators that are related to pointers are & and *. & takes an lvalue and returns a pointer to that value. * takes a pointer and returns the value it points to. In this case, you have a string, as a char *, and the function you're calling wants a char *, so you can pass it in directly without casting or using * or &. However, for the other function you have a struct sockaddr_in and it wants a struct sockaddr *, so you (correctly) use & to get a struct sockaddr_in *, then cast it to a struct sockaddr *. This is called "type punning," and is an unpleasant reality of the API. Google will give you a better description of type punning than I can.
connect(client_socket, (struct sockaddr *)&clientService, sizeof(clientService));
this is ok, but this line should read:
send(client_socket,(const char*)ln, strlen(ln), 0);
where the conversion (const char*) can be omitted.
In your code the value of pointer ln is sent (correctly) but you most likely want to send the string it's pointing to in it's entire length.
Concerning the messages to be send: Converting integers to ascii is not a bad idea. You also may have a look at JSON or Googles protobuf format. Formatters or Parsers can easily be written from scratch.
I'm deserializing data from a web page generated by php that is using ip2long(). However, when I try to make a new ip address by using the integer value in the constructor of IPAddress the dotted version of the ip address is in reverse order?
ex:
4.3.2.1 should really be 1.2.3.4
Any ideas of how to fix this?
It sounds like someone is using little-endian and someone is using network byte order (big-endian) for the packed value. For instance the octect sequence compromising an integer, AA,BB,CC,DD in LE is DD,CC,BB,AA in BE/NBO -- a nice symmetrical reverse!
Since the IPAddress(Int64) constructor documentations says:
The Int64 value is assumed to be in network byte order.
I would imagine that ip2long in PHP is generating a value in little-endian. Good thing IPAddress also takes byte[] for the constructor, now get those elbows greasy... just pass the bytes in the "correct" order.
Happy coding.
The code at How to convert an int to a little endian byte array? should give some ideas.
Or, as Josh points out, there is a HostToNetworkOrder method to do this.
use long2ip() to reverse the process of ip2long()
<?php
// make sure IPs are valid. also converts a non-complete IP into
// a proper dotted quad as explained below.
$ip = long2ip(ip2long("127.0.0.1")); // "127.0.0.1"
$ip = long2ip(ip2long("10.0.0")); // "10.0.0.0"
$ip = long2ip(ip2long("10.0.256")); // "10.0.1.0"
?>
you shouldn't really have any problems after all it's a standard in php
I'm working on a networking application in C#, sending a lot of plain numbers across the network. I discovered the IPAddress.HostToNetworkOrder and IPAddress.NetworkToHostOrder methods, which are very useful, but they left me with a few questions:
I know I need to encode and decode integers, what about unsigned ones? I think yes, so at the moment I'm doing it by casting a pointer to the unsigned int into a pointer to an int, and then doing a network conversion for the int (since there is no method overload that takes unsigned ints)
public static UInt64 HostToNetworkOrder(UInt64 i)
{
Int64 a = *((Int64*)&i);
a = IPAddress.HostToNetworkOrder(a);
return *((UInt64*)&a);
}
public static UInt64 NetworkToHostOrder(UInt64 a)
{
Int64 i = *((Int64*)&a);
i = IPAddress.HostToNetworkOrder(i);
return *((UInt64*)&i);
}
2. What about floating point numbers (single and double). I think no, however If I do need to should I do a similar method to the unsigned ints and cast a single pointer into a int pointer and convert like so?
EDIT:: Jons answer doesn't answer the second half of the question (it doesn't really answer the first either!), I would appreciate someone answering part 2
I suspect you'd find it easier to use my EndianBinaryReader and EndianBinaryWriter in MiscUtil - then you can decide the endianness yourself. Alternatively, for individual values, you can use EndianBitConverter.
You'd better read several RFC documents to see how different TCP/IP protocols (application level, for example, HTTP/FTP/SNMP and so on).
This is generally speaking, a protocol specific question (both your questions), as your packet must encapsulate the integers or floating point number in a protocol defined format.
For SNMP, this is a conversion that changing an integer/float number to a few bytes and changing it back. ASN.1 is used.
http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One
I have a couple of parameters, which need to be sent to a client app via TCP/IP.
For example:
//inside C++ program
int Temp = 10;
int maxTemp = 100;
float Pressure = 2.3;
Question: What is the best practice to format a string? I need to make sure that the whole string is received by the client and it should be easier at the client end to decode the string.
Basically, I want to know, what should be the format of the string, which I am going to send?
PS: Client app is in C# and the sender's app is in Qt (C++).
This is pretty subjective, but if it will always be as simple as described, then: keep it simple:
ASCII, space delimited, invariant (culture-independent) format integers in their fully expanded form (no E etc), CR as the end sentinel, so:
10 100 2
(with a CR at the end) This scales to any number of records, and will be easy to decode from just about any platform.
If it gets more nuanced: use a serializer built for the job, and just share details of what serialization format you are using.
Use ASCII, of the form paramName paramValue, space delimited, culture-independent format and use integers in their full form (no E notation) and a carriage return at the end, for example: T 10 P 100 mT 2 with CR at the end. In the other side, you can simply split the string by white spaces and note that even indices are parameters and odds indices are parameter values. Note that for every even parameter name index i then i+1 is its corresponding odd index parameter value. Also mind the CR at the end.