Sockets in Pascal - sockets

How do you use network sockets in Pascal?
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Here's an example taken from http://www.bastisoft.de/programmierung/pascal/pasinet.html
program daytime;
{ Simple client program }
uses
sockets, inetaux, myerror;
const
RemotePort : Word = 13;
var
Sock : LongInt;
sAddr : TInetSockAddr;
sin, sout : Text;
Line : String;
begin
if ParamCount = 0 then GenError('Supply IP address as parameter.');
with sAddr do
begin
Family := af_inet;
Port := htons(RemotePort);
Addr := StrToAddr(ParamStr(1));
if Addr = 0 then GenError('Not a valid IP address.');
end;
Sock := Socket(af_inet, sock_stream, 0);
if Sock = -1 then SockError('Socket: ');
if not Connect(Sock, sAddr, sizeof(sAddr)) then SockError('Connect: ');
Sock2Text(Sock, sin, sout);
Reset(sin);
Rewrite(sout);
while not eof(sin) do
begin
Readln(sin, Line);
Writeln(Line);
end;
Close(sin);
Close(sout);
Shutdown(Sock, 2);
end.

If you're using FPC or Lazarus(which is basically a rad IDE for FPC and a clone of delphi) you could use the Synapse socket library. It's amazing.

If you are using Delphi, I highly recommend Indy sockets, a set of classes for easy manipulation of sockets and many other internet protocols (HTTP, FTP, NTP, POP3 etc.)

You cannot use OpenSSL with Indy version 10.5 that shippes with Delphi 2007. You have to download version 10,6 from http://www.indyproject.org/ and install it into the IDE.
Note that other packages might use Indy, like RemObjects, and therefore they have to be re-compiled too and this can be tricky due to cross-references.

Related

WSAEWOULDBLOCK 10035

I'm trying to make client-server connection, I don't know much about sockets etc. so I used github example for luajitsocket and im getting error "A non-blocking socket operation could not be completed immediately."
So I dont even know how can I fix that, that's why Im asking here
My code:
local port = 8080
local address = socket.find_first_address("*", port)
do -- server
local server = assert(socket.create("inet", "dgram", "udp"))
assert(server:set_blocking(false))
assert(server:bind(address))
print("hosting at ", address:get_ip(), address:get_port())
function update_server()
local data, addr = server:receive_from()
if data then
print(data)
assert(server:send_to(addr, "hello from server " .. os.clock()))
elseif addr ~= "timeout" then
error(addr)-- here
end
end
end
do -- client
local client = assert(socket.create("inet", "dgram", "udp"))
assert(client:set_blocking(false))
local next_send = 0
function update_client()
if next_send < os.clock() then
assert(client:send_to(address, "hello from client " .. os.clock()))
next_send = os.clock() + math.random() + 0.5
end
local data, addr = client:receive_from(address)
if data then
print(data, addr:get_ip(), addr:get_port())
elseif addr ~= "timeout" then
error(addr)
end
end
end
while true do
update_server()
update_client()
end
taken from: https://github.com/CapsAdmin/luajitsocket/blob/master/examples/udp_client_server.lua
I was looking about this error on google but can't find any working solution. Thanks in advance!
After set_blocking(false) that return code should not be considered abnormal.
You're probably getting it from receive_from(), which you should not be calling constantly, you should do it when select() or poll() tells you the socket has data waiting.

Unicast/multicast packet using xdp/tc eBPF

I am trying to design a load balancer using ebpf. I want to transmit the incoming packet to different destinations (devices connected in the same network). Although I have used the clone_bpf_redirect() helper function to redirect the packet to real/ virtual interfaces and it's working fine, now I want to broadcast/unicast the packet to other devices connected in the same network.
XDP does not support it, as far as I know. Therefore, using tc bpf hook. Is there any helper function or which action should I use? Can anyone please guide me on how can I do this?
**eBpf load divider**: 192.168.98.178 (load divider)
**Receiver 1**: 192.168.98.131
**Receiver 2**: 192.168.98.138
iph->daddr = htonl(3232260739); //Dest: 192.168.98.131
iph->check = 0;
iph->check = checksum((unsigned short *)iph, sizeof(struct iphdr));
// Update upd packet checksum of
sum = old_daddr + (~ntohs(*(unsigned short *)&iph->daddr) & 0xffff);
sum += ntohs(udp->check);
sum = (sum & 0xffff) + (sum>>16);
udp->check = htons(sum + (sum>>16) - 1);
// clone the packet and redirect to infdex
bpf_clone_redirect(skb, skb->ifindex, 0);
//clone the packet and redirect to infdex (virtual interface 2)
bpf_clone_redirect(skb, skb->ifindex + 2, 0);
//clone the packet and redirect to infdex (virtual interface 4)
bpf_clone_redirect(skb, skb->ifindex + 4, 0);
return TC_ACT_OK;
// Or
// return TC_ACT_REDIRECT;
sudo tc filter add dev ens33 ingress bpf da obj bpf_loadbalancer.o sec ingress
after this, I am getting the 1 packet to 3 different ifindex but I want to get the same packet to other devices connected into the network. How can I redirect the packet out of the device, not the interfaces?

It Is possible to send a RST flag in a TIdTCPClient?

I need to send a RST flag in one socket, is it possible?
When I close the TIdTCPClient, the TCP server program tells me that the connection is still alive, and after 2 minutes the connection disappears.
I'm doing this :
TCPCliente := TIdTCPClient.Create(nil);
TCPCliente.Host := edtIP.Text;
TCPCliente.Port := 492;
TCPCliente.ConnectTimeout := 1000;
TCPCliente.Connect;
TCPCliente.Socket.WriteLnRFC(TextoEnvio, IndyTextEncoding_8Bit);
Texto := TCPCliente.Socket.ReadLn(IndyTextEncoding_8Bit);
TCPCliente.Socket.Close;
TCPCliente.Disconnect;
TCPCliente.Free;
I'm using RAD Studio XE8.

How can I do a tcp syn port scan with golang?

I'm trying to write a tcp syn port scanner with golang, I found a solution in C version here: http://www.binarytides.com/tcp-syn-portscan-in-c-with-linux-sockets/
I'd like to implement it in go, how can I send a tcp header like this in golang:
//TCP Header
tcph->source = htons ( source_port );
tcph->dest = htons (80);
tcph->seq = htonl(1105024978);
tcph->ack_seq = 0;
tcph->doff = sizeof(struct tcphdr) / 4; //Size of tcp header
tcph->fin=0;
tcph->syn=1;
tcph->rst=0;
tcph->psh=0;
tcph->ack=0;
tcph->urg=0;
tcph->window = htons ( 14600 ); // maximum allowed window size
tcph->check = 0; //if you set a checksum to zero, your kernel's IP stack should fill in the correct checksum during transmission
tcph->urg_ptr = 0;
Do I have to use syscall or cgo? I'm really appreciated if someone could help me out.
You're going to want to use syscall. However the syscall package is not necessarily portable across different Operating Systems so if that matters to you then you'll have to write per os versions and use the file_os.go naming scheme to hold the os specific code.

Car OBDII WLAN protocol

I am currently searching for the specification of the WLAN protocoll to get OBDII data. There are some ELM327 similar adapter on the market which enables iPhone to connect to a OBDII interface with WLAN. This because Bluetooth serial port is scrambled because of the accessories interface. Other programs like Torque for android can also use this communication protocol. However I did not find the specs for creating a network client.
Any help is welcomed,
Thanks
Ok, after some more research, I found two sources:
Michael Gile has an open source library for iOS devices, meant for communicating with OBDII WiFi as well as Bluetooth devices.
PLX devices (creators of the KiWi) have a description how to communicate with the KiWi. The description is too large to include here, but it boils down to:
Connect using WiFi (sockets)
Wait until the device returns >
Issue command and await response
Requesting information can be done by sending a command in this format (ASCII characters):
MM PP\r
where MM is the test mode, PP is the PID, and \r is a carriage return (hex: 0x0d). All whitespace characters are ignored by the Kiwi. *Test modes 03 and 04 do not require a PID value.
The 'test modes' that are spoken of, are the ten diagnostic modes as defined in the SAE J1979 standard:
Test mode Description
01 Show current data
02 Show freeze frame data
03 Show diagnostic trouble codes
04 Clear trouble codes and stored values
05 Test results, oxygen sensors
06 Test results, non-continuously monitored
07 Show 'pending' trouble codes
08 Special control mode
09 Request vehicle information
0A Request permanent trouble codes
The PID values are the codes for the sensors in the car. A (non-exhaustive)list of possible PID values is on Wikipedia.
here what i do in C and socket:
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
char *ip = "192.168.0.10";
char str [128];
int i;
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(35000);
if(inet_pton(AF_INET, ip, &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
printf ("reading...\n");
strcpy (str,"AT Z\x0d");
sleep(2);
write (sockfd, str, strlen (str));
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
printf ("received: ");
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
printf ("\r\ntype: ");
fgets (str, sizeof (str), stdin);
i = strlen (str);
if (str [i-1] == 0x0a)
str [i-1] = 0;
strcat (str, "\x0d");
write (sockfd, str, strlen (str));
printf ("\r\n");
}
type 1 or 2 enter, you should see the prompt: ELM327
then after that, type whatever you want, for ex.: AT RV (will show voltage)
then use this pdf for all code:
https://www.obd-2.de/carcode/dl/ELM327DS.pdf
Have a look at ELM327 datasheet
Wifi dongles transparently bind the ELM327 RS232 port to a TCP server.
There's not really a WIFI protocol. You can use the ELM327 protocol via a raw TCP connection instead.
You can sent AT commands and OBD2 commands known as PID's with the telnet command:
telnet 192.168.0.1 35000
On succesful connection you can try to send:
AT Z
and the server should respond with "ELM327" and a version number.