I've written the following code to (successfully) connect to a socks5 proxy.
I send a user/pw auth and get an OK reply (0x00), but as soon as I tell the proxy to connect to whichever ip:port, it gives me 0x01 (general error).
Socket socket5_proxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint proxyEndPoint = new IPEndPoint(IPAddress.Parse("111.111.111.111"), 1080); // proxy ip, port. fake for posting purposes.
socket5_proxy.Connect(proxyEndPoint);
byte[] init_socks_command = new byte[4];
init_socks_command[0] = 0x05;
init_socks_command[1] = 0x02;
init_socks_command[2] = 0x00;
init_socks_command[3] = 0x02;
socket5_proxy.Send(init_socks_command);
byte[] socket_response = new byte[2];
int bytes_recieved = socket5_proxy.Receive(socket_response, 2, SocketFlags.None);
if (socket_response[1] == 0x02)
{
byte[] temp_bytes;
string socks5_user = "foo";
string socks5_pass = "bar";
byte[] auth_socks_command = new byte[3 + socks5_user.Length + socks5_pass.Length];
auth_socks_command[0] = 0x05;
auth_socks_command[1] = Convert.ToByte(socks5_user.Length);
temp_bytes = Encoding.Default.GetBytes(socks5_user);
temp_bytes.CopyTo(auth_socks_command, 2);
auth_socks_command[2 + socks5_user.Length] = Convert.ToByte(socks5_pass.Length);
temp_bytes = Encoding.Default.GetBytes(socks5_pass);
temp_bytes.CopyTo(auth_socks_command, 3 + socks5_user.Length);
socket5_proxy.Send(auth_socks_command);
socket5_proxy.Receive(socket_response, 2, SocketFlags.None);
if (socket_response[1] != 0x00)
return;
byte[] connect_socks_command = new byte[10];
connect_socks_command[0] = 0x05;
connect_socks_command[1] = 0x01; // streaming
connect_socks_command[2] = 0x00;
connect_socks_command[3] = 0x01; // ipv4
temp_bytes = IPAddress.Parse("222.222.222.222").GetAddressBytes(); // target connection. fake ip, obviously
temp_bytes.CopyTo(connect_socks_command, 4);
byte[] portBytes = BitConverter.GetBytes(3333);
connect_socks_command[8] = portBytes[0];
connect_socks_command[9] = portBytes[1];
socket5_proxy.Send(connect_socks_command);
socket5_proxy.Receive(socket_response);
if (socket_response[1] != 0x00)
MessageBox.Show("Damn it"); // I always end here, 0x01
I've used this as a reference: http://en.wikipedia.org/wiki/SOCKS#SOCKS_5
Have I completely misunderstood something here? How I see it, I can connect to the socks5 fine. I can authenticate fine. But I/the proxy can't "do" anything?
Yes, I know the proxy works.
Yes, the target ip is available and yes the target port is open/responsive.
I get 0x01 no matter what I try to connect to.
Any help is VERY MUCH appreciated!
Thanks,
Chuck
You might be getting bitten by endianness. Is BitConverter.GetBytes returning you the right bytes, for instance? Did you step through it and check if your byte arrays contain what you expect them to?
That looks like little endian, and networking-related things usually use big endian. BitConverter always uses system endianness, so you'll have to reverse bytes by hand if you're running on a little endian system (which you would seem to be doing). BitConverter.IsLittleEndian will tell you whether your system is little endian or not.
Also, it'd be a good idea to cast your value to short, e.g. BigConverter.GetBytes((short)3333). That way you'll get just the two bytes you need.
Related
I'm trying to implement IP fragmentation using Pcap.Net.
It is simple for packets that are already built as the L3 payload is just split into parts.
I have a code that does it. It returns the list of packet fragments for sending it into the wire.
private static List<Packet> FragmentPacket(Packet packet)
{
EthernetLayer ethernetLayer = (EthernetLayer)packet.Ethernet.ExtractLayer();
IpV4Layer ipV4Layer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
PayloadLayer payload = (PayloadLayer)packet.Ethernet.IpV4.Payload.ExtractLayer();
// implement IP fragmentation
int totalLength = payload.Length;
int fragmentLength = 1480;
int fragmentOffset = 0;
IpV4FragmentationOptions FragOptions;
List<Packet> fragmentsList = new List<Packet>();
while (fragmentOffset < totalLength)
{
if (fragmentOffset + fragmentLength >= totalLength)
{
//last fragment
FragOptions = IpV4FragmentationOptions.None;
fragmentLength = totalLength - fragmentOffset;
}
else
{
//more fragments to go
FragOptions = IpV4FragmentationOptions.MoreFragments;
}
IpV4Layer newipV4Layer =
new IpV4Layer
{
Source = ipV4Layer.Source,
CurrentDestination = ipV4Layer.CurrentDestination,
Fragmentation = new IpV4Fragmentation(FragOptions, (ushort)fragmentOffset),
HeaderChecksum = null, // Will be filled automatically.
Identification = 123,
Options = IpV4Options.None,
Protocol = ipV4Layer.Protocol,
Ttl = ipV4Layer.Ttl, // 128,
TypeOfService = ipV4Layer.TypeOfService,
};
byte[] newBuffer = payload.Data.ToArray();
PayloadLayer fragmentedPayload = new PayloadLayer { Data = new Datagram(newBuffer, fragmentOffset, fragmentLength) };
PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, fragmentedPayload);
fragmentsList.Add(builder.Build(DateTime.Now));
fragmentOffset = fragmentOffset + fragmentedPayload.Length;
}
return fragmentsList;
}
But what I'm actually doing is:
1) receiving large packet via Loopback interface (it is usually bigger than physical interface's MTU)
2) disassembling it, modifying IP addresses
3) building a new packet and sending it via Ethernet interface
Unfortunately, if the IP payload is bigger than MTU, exception happens as the packet needs to be fragmented before sending.
Because I'm changing IP address, then for TCP/UDP packets, the L4 checksum must be recalculated and this recalculation must take into account L3 header. Therefore it is needed to build L3+L4+payload part (to have L4 checksum properly calculated) and then split L4+payload into parts to fit L3 MTU.
I came into a solution in which I'm building a new packet (which is bigger than MTU) and then push it via above function to tear it into parts, and then I'm sending it using:
foreach (Packet newpacket in packetList)
communicator.SendPacket(newpacket);
This, however, requires to build the same packet twice and I'm trying to find a way in Pcap.Net to partially build a packet (including recalculation of L4 checksum) and at the same time divide it into fragments to fit MTU.
I don't know how to (and if this is possible in Pcap.Net) prepare L3 payload that would consist of tcpLayer/udpLayer + L4 payload since TCP checksum is calculated during building and then finally build the rest of packet.
If that was possible, I would just need to build the packet once splitting it into parts at the same time.
I am using Lapsnapper (a transponder timing system) running on Android.
Lapsnapper enables a TCP/IP server with which a connection can be made, to build a custom interface and get some other relevant data RE: the transponders etc from the system.
I do not understand the Lapsnapper tcp server specification.
I have done some tcp stuff before, but I am mostly a higher level programmer and to be honest I am a bit out of my depth with this raw TCP stuff.
The spec reads:
What I don't understand is how to "send" the tcp data?
I don't understand how 0x70, 0x17 equates to (6000) and 2 bytes...
The same goes for 0x13, 0x00, 0x00, 0x00 = 19 which the spec says should be 4 bytes, but a string of "19" is 2 bytes?
I am trying to understand what I am reading. Any help would be appreciated as I need to do quite a bit of comms to this server, and I want to understand what I am doing...
I have asked for help from lapsnapper support, but in the mean time I would like to learn something new as per the above.
What do I actually "send" on the TCP connection?
The spec says that I should expect a message back, but with my current implementation, a connection seems to be established, but I never receive anything back.
Response Message to expect:
My code:
(P.S This code block works if I do a simple connection to a SMTP server and I can do a basic connection with reply from said smtp server. I however never receive a reply when I try to talk to the Lapsnapper TCP server using the code below)
string lapSnapperIP = "10.0.0.131";
int lapsnapperPort = 9001;
string lapSnapperMessageID;
string lapsnapperLengthOfMessage;
string lapsnapperProductID;
string lapsnapperServerVersion;
string lapsnapperPasswordLength;
string lapsnapperPassword;
lapSnapperMessageID = "6000";
lapsnapperLengthOfMessage = "19"; //to implement
lapsnapperProductID = "50";
lapsnapperServerVersion = "100000";
lapsnapperPasswordLength = "4";
lapsnapperPassword = "1234";
string lapSnapperDataSend;
lapSnapperDataSend = lapSnapperMessageID + lapsnapperLengthOfMessage + lapsnapperProductID + lapsnapperServerVersion + lapsnapperPasswordLength + lapsnapperPassword;
s.Connect(lapSnapperIP, lapsnapperPort);
byte[] sendMessage = Encoding.UTF8.GetBytes(lapSnapperDataSend);
byte[] receiveBytes = new byte[256];
int i = 0;
string receivedMessage = "";
//send data
i = s.Send(sendMessage);
//receive data
i = s.Receive(receiveBytes); // (no reply here...)
receivedMessage = Encoding.UTF8.GetString(receiveBytes);
Thanks
I have found the below code on the internet, and I need to allow my users to enter their own IP Address and Port number, as opposed to hard-coded.
I allow my users to enter a IP and Port from two individual text boxes.
try
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting");
tcpclnt.Connect(syn_ip.Text, 7878);
Console.WriteLine("Connected");
//String str=Console.ReadLine();x
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes("data here");
Console.WriteLine("Transmitting.");
stm.Write(ba, 0, ba.Length);
byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);
for (int i = 0; i < k; i++)
Console.Write(Convert.ToChar(bb[i]));
tcpclnt.Close();
}
catch (Exception ex)
{
Console.WriteLine("Error:" + ex.ToString());
}
It will let me send my data over using the above, but I really do need to be able to enter in the port number.
When I do try something like the below, I get the following error: Argument: Cannot convert from 'string' to 'int'.
tcpclnt.Connect(syn_ip.Text, syn_port.Text);
Thanks for all the help in advance :)
James.
In this code
tcpclnt.Connect(syn_ip.Text, syn_port.Text);
syn_port.Text is a string type, but an integer is expected. The simple fix is
tcpclnt.Connect(syn_ip.Text, int.Parse(syn_port.Text));
This will throw an exception at runtime if anything but an integer is entered. Instead, consider the more robust solution
int port;
bool ok = int.TryParse(syn_port.Text, out port);
if (ok)
{
tcpclnt.Connect(syn_ip.Text, port);
}
else // Some error message
Note that you should also modify the UI to only allow integers to be entered. You should also never trust a UI (as a general practice), so also validate that you received an integer in your code that uses the input.
You need to convert the port to an integer value.
int port = Int32.Parse(syn_port.Text);
tcpclnt.Connect(syn_ip.Text, port);
tcpclnt.Connect(syn_ip.Text, int.Parse(syn_port.Text));
You just need to convert the port string to an int, as the error suggests.
Since you're trying to convert user input I would recommend int.TryParse considering it could not always be an int.
int port;
if (int.TryParse(syn_port.Text, port))
{
tcpclnt.Connect(syn_ip.Text, port);
}
I am trying to provide a "click to dial" solution for someone to a bluetooth device such as a mobile phone. I have been trying to do so using the 32feet.net bluetooth api.
I haven't really done anything with bluetooth (since the days of at commands via a bluetooth serial port) but I have paired the device in question, which supports the handsfree service with the pc. I have the following code to attempt to connect and send a dial command.
String deviceAddr = "11:11:11:11:11:11";
BluetoothAddress addr = BluetoothAddress.Parse(deviceAddr);
BluetoothEndPoint rep = new BluetoothEndPoint(addr, BluetoothService.Handsfree);
BluetoothClient cli = new BluetoothClient();
cli.Connect(rep);
Stream peerStream = cli.GetStream();
String dialCmd = "ATD 0000000000\r\n";
Byte[] dcB = System.Text.Encoding.ASCII.GetBytes(dialCmd);
peerStream.Write(dcB, 0, dcB.Length);
// Begin Edit ------------------------------------------------------------
Byte[] sResponse = new Byte[100];
peerStream.Read(sResponse, 0, 99);
TextBox1.Text = System.Text.Encoding.ASCII.GetString(sResponse);
// End Edit --------------------------------------------------------------
peerStream.Close();
cli.Close();
MessageBox.Show("Done");
Since it seems to run through these lines of code, taking an appropriate time to connect at the relevant spot or crashing out if the device address is wrong and it can't connect. Obviously the AT command is not the right thing to be sending it.
Can anyone enlighten me as to what I might need to send to a bluetooth device via the handsfree profile to get it to dial?
Begin Edit -------------------------------------------
I decided to read from the stream and see if there was a response of any sort after sending the AT command through. Since I am just testing to see if I can make it work I am just dumping the response into a textbox.
The response I read from the stream is :
ERROR
There doesn't seem to be an error codes or anything.
End Edit ---------------------------------------------
Edit --------------------------------------------------
Sent command : AT+CMER\r
Result : OK
then
Sent command : AT+CIND=?\r
Result :
+CIND: ("service",(0-1)),("call",(0-1)),("callsetup",(0-3)),("battchg",(0-5)),("signal",(0-5)),("roam",(0-1)),("callheld",(0-2))
then
Send command : ATD 0000000000\r
Result:
OK
D: ("service",(0-1)),("call",(0-1)),("callsetup",(0-3)),("battchg",(0-5)),("signal",(0-5)),("roam",(0-1)),("callheld",(0-2))
Still it doesn't actually dial :(
End Edit ----------------------------------------------
Solution ----------------------------------------------
The following code now works to dial via my iPhone. It's really rough at the moment, as I have just been testing to see if I could make it work. It's enough to get started for anyone else wanting to do a similar thing.
String deviceAddr = "00:00:00:00:00:00";
BluetoothAddress addr = BluetoothAddress.Parse(deviceAddr);
BluetoothEndPoint rep = new BluetoothEndPoint(addr, BluetoothService.Handsfree);
BluetoothClient cli = new BluetoothClient();
cli.Connect(rep);
Stream peerStream = cli.GetStream();
String dialCmd1 = "AT+CMER\r";
String dialCmd2 = "AT+CIND=?\r";
String dialCmd3 = "AT+BRSF=\r";
String dialCmd4 = "ATD 0000000000;\r";
Byte[] dcB = System.Text.Encoding.ASCII.GetBytes(dialCmd1);
peerStream.Write(dcB, 0, dcB.Length);
Byte[] sRes = new Byte[200];
peerStream.Read(sRes, 0, 199);
textBox1.Text = textBox1.Text + "\n\r----------\n\r" + System.Text.Encoding.ASCII.GetString(sRes);
dcB = System.Text.Encoding.ASCII.GetBytes(dialCmd2);
peerStream.Write(dcB, 0, dcB.Length);
peerStream.Read(sRes, 0, 199);
textBox1.Text = textBox1.Text + "\n\r----------\n\r" + System.Text.Encoding.ASCII.GetString(sRes);
dcB = System.Text.Encoding.ASCII.GetBytes(dialCmd3);
peerStream.Write(dcB, 0, dcB.Length);
peerStream.Read(sRes, 0, 199);
textBox1.Text = textBox1.Text + "\n\r----------\n\r" + System.Text.Encoding.ASCII.GetString(sRes);
dcB = System.Text.Encoding.ASCII.GetBytes(dialCmd4);
peerStream.Write(dcB, 0, dcB.Length);
peerStream.Read(sRes, 0, 199);
textBox1.Text = textBox1.Text + "\n\r----------\n\r" + System.Text.Encoding.ASCII.GetString(sRes);
peerStream.Close();
cli.Close();
Try to find what is the response for AT\r (or) ATH\r.
If the response is "OK\r\n", try your dial command with no space after ATD and number.
As maintainer of 32feet.NET I'd love to find the answer to this. Hopefully someone with knowledge of HSP/HFP will explain why this doesn't work. My only general guess is that since we're not accepting/creating the SCO channel for the audio channel the phone refuses the connection.
Once thing in your case however... AT commands are terminated by a CR (0Dh); or does the semicolon act the same??
hello i have problem with receiving data from serial port in c# in am inserting a new line operator at the end of data buffer. then i send this data buffer on serial port, after this my c# GUI receiver will take this data via Readline() function but it always give me raw data not the actual one how to resolve this problem.
//configuring the serial port this code in c# with problem
serialPort.PortName = "COM1";
serialPort.BaudRate = 9600;
serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
//opening the serial port
if(!serialPort.IsOpen)
serialPort.Open();
//read 2byte data for msG code from serial port
string strReadData=serialPort.ReadLine();
char[] temp=new char[350];
//strReadData.CopyTo(1, temp, 0, strReadData.Length - 2);
//strReadData = temp.ToString();
//string strReadData = serialPort.ReadExisting();
//strReadData.Replace(' ', '\0');
//strReadData.Replace(' ', '');
byte[] RecievedData = Encoding.ASCII.GetBytes(strReadData);
RecievedDataDecoder(RecievedData);
//close the port
if(serialPort.IsOpen)
serialPort.Close();
but my c++ receiver is working perfectly i dont know what is the problem here is working c++ code
// variables used with the com port
BOOL m_bPortReady;
HANDLE m_hCom;
DCB m_dcb;
COMMTIMEOUTS m_CommTimeouts;
BOOL bWriteRC;
BOOL bReadRC;
DWORD iBytesWritten;
DWORD iBytesRead;
DWORD dwCommEvent;
DWORD dwRead;
char sBuffer[128];
m_hCom = CreateFile("Com1",
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security
OPEN_EXISTING,
0, // no overlapped I/O
NULL); // null template
m_bPortReady = SetupComm(m_hCom, 128, 128); // set buffer sizes
m_bPortReady = GetCommState(m_hCom, &m_dcb);
m_dcb.BaudRate = 9600;
m_dcb.ByteSize = 8;
m_dcb.Parity = NOPARITY;
m_dcb.StopBits = ONESTOPBIT;
m_dcb.fAbortOnError = TRUE;
m_bPortReady = SetCommState(m_hCom, &m_dcb);
m_bPortReady = GetCommTimeouts (m_hCom, &m_CommTimeouts);
m_CommTimeouts.ReadIntervalTimeout = 50;
m_CommTimeouts.ReadTotalTimeoutConstant = 50;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 10;
m_CommTimeouts.WriteTotalTimeoutConstant = 50;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 10;
m_bPortReady = SetCommTimeouts (m_hCom, &m_CommTimeouts);
if (!SetCommMask(m_hCom, EV_RXCHAR))
{
printf("Error in set comm mask");
}
while(1)
{
if (WaitCommEvent(m_hCom, &dwCommEvent, NULL))
{
if (ReadFile(m_hCom, &sBuffer, 128, &iBytesRead, NULL))
printf("");
else
{
printf("Error in reading");
break;
}
}
else
{
printf("Error in Waiting");
break;
}
printf("%s",sBuffer);
strcpy(sBuffer,"");
}
CloseHandle(m_hCom);
getch();
exit(0);
Your question is a bit vague, but the ReadLine() method will return when the port receives a carriage return and line feed byte combination by default on Windows. Or \r\n, or 0x0d 0x0a if you prefer.
If the 'buffer' you are sending in the fist place contains several messages delimited by \r\n, then ReadLine() will only return the first one, then the port will close in the C# code you have posted.
Maybe your code is in a loop, but it is not shown.
Beyond that, after any data that you have received, your are converting it back to an array of bytes, determined by ASCII encoding. Are you sending ASCII in the first place? If not, it is likely that you could be missing information.
Also, if all you do is convert the received string into bytes, you could just receive the data as bytes in the first place.
I think you need to explain in a bit more detail exactly what is in the buffer you are sending, and what exactly do you receive.
Most of my serial port errors are caused by bad baude rate settings. This might be your problem too. (You can set the baude rate in some constructors of the SerialPort class, or with the BaudRate property)