[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 407
  • Last Modified:

reading/writing data buffers over a windows socket

@Rlibby or anyone else who can give suggestions :)

Please refer to http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21391643.html for redirect code that I'm using.

Now that the relay is functioning how I want it to I want to start immediately modifying some of the inbound data. Based on the translated port redirect I'm assuming some things as I have usually messed with TClientSocket components that have Sendtext methods for sending socket data, as well as SendBuf.
Any ideas on a good way to do this, I have a couple packet positions that I'd like to manipulate (copy data between them) patch recv buffer and send it back out the relay.

 Since the buffer is a character array, string manipulations would require me to create a temp buffer, point it to the filled recv buf and convert the array of chars to a string, make some string modifications, convert the string back to a character array and send the buffer back out? Is it possible to operate on a filling recv buffer with string manipulation routines easily, could I see a quick example or a general idea of modifying a recv, stripping html tags or something of that nature. It seems I'm not looking in the right places for Delphi Winsock programming related material and it forced me to get an experts-exchange account :( But I have been impressed with answers so far =)

thanks
Thor371
0
Thor371
Asked:
Thor371
  • 5
  • 4
1 Solution
 
Russell LibbySoftware Engineer, Advisory Commented:
Thor371,

Sorry to have missed this q. Hopefully I can assist with your questions now though....

When dealing with tcp data a few things must be understood first:

1.) The data should not be considered an array of char, or string, or any other type except byte.(array of byte). While it MAY contain textual data (like an http:// request), this is not a rule. For example, one could just as easily send a record structure as data.

type
 TMyRecord = packed record
   data1:  Integer;
   data2:  Array [0..31] of Char;
   data3:  Byte;
 end;

var
 MyRecord: TMyRecord;

begin

 send(socket, MyRecord, SizeOf(MyRecord), 0);
 ... etc


end;

If you tried to recv the above data and perform string operations on it you would run into problems. This brings up the next point.

2.) TCP is a streaming type transport, not a message based transport. What does this mean? For starters, please read:

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21246833.html

To clarify using an example: A client writes 1MB to the socket, this data is then pushed to the server, which starts reading the data in. From the clients point of view, the 1MB of data made up the "message" or transmission. But what happens on the server side? More than likely it will take multiple reads to get all of the data. Without aggreement (defining) on a message based protocol, the server will have no idea where one message ends, and the next begins. Nor will it have any way to evaluate or understand the data being recv'd.  If you look at the RFC for http, it defines a mechanism for both the client and server to handle data. Eg: the header set ends with a double crlf, the first crlf line defines the method (get/post/head), etc, etc. This is a perfect example of a defined protocol that both the client (browsers) and server (web servers) understand. If the data being sent/recv'd does not conform to the protocol, then it is discarded.

also remember: while a client may send a "message" out as a single chunk, the server must be prepared to perform multiple reads in order to retrieve the "message".

So the big step for you will be in determining what type of data you plan on handling from the clients. What protocol scheme will you use? etc.
Because of all the current unknowns, I don't wish to provide code (so as not to confuse). If you have some ideas on the data (messages) being sent, and care to share those, then I could provide example code for

- recv'ing the incoming data
- buffering the data
- performing data translations
- sending the data back out


Hope this gives you something to go on,
Russell






0
 
Thor371Author Commented:
Hey, Russell. Thanks for the feedback. I've actually read quite a few RFCs regarding transport and network protocols (TCP, UDP, ICMP, IP, IGMP) along with some application-layer as well such as TFTP and Socks5. While I may have not read them through 100% I certainly understand them quite clearly... stream protocols vs. datagram, the TCP 3-way handshake, IP fragmentation bits (0, DF, LF) ,TCP flag control bits and the like. Here are some specifics, involving the exact TCP packet payload that I need string operations performed on.

This payload is complete, taken from a connection to a Yahoo! RTCP voice server. I understand this protocol well and how it works (the login, RTCP & RTP sessions etc):

00 80 00 00 81 C8 00 44 00 00   .€..È.D..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 CC   ..............€Ì
00 38 00 00 00 00 43 41 21 59 00 0A 00 00 00 00   .8....CA!Y......
00 00 08 04 42 DA 46 20 03 19 63 68 2F 43 68 61   ....BÚF ..ch/Cha
74 74 65 72 42 6F 78 3A 32 3A 3A 32 31 37 34 38   tterBox:2::21748
30 37 38 2D 2D 31                                 078--1

From the above packet I need to modify/replace 0x42 0xDA 0x46 0x20 or "BÚF " in ASCII. "BÚF " itself is not always the same, but the position always remains the same whether it is equal to "BÚF " or not. These 4 Bytes are translated by the voice module (reading it) as "the next ip address to connect to". These Bytes are the most important in the packet as they dictate where the following connections in the login phase are to be made to. "BÚF " falls in the 95, 4 position (95 - 98) and this never changes. The hex Bytes before "BÚF " are 0x00 0x00 0x08 0x04, and these don't change as they're always constant (same exact position & same values). The Bytes directly after "BÚF " infact do change. What I would like to do is read the decimal value of each hex Byte in "BÚF " (where "BÚF " can be anything) and store them temporarily for later use and then replace them with the Bytes 0x7F 0x00 0x00 0x01 (loopback address) to be passed on. I want to keep the original "BUF " values stored for later use by the non-loopback connection (in my bouncer setup) so that the actual packets over the loopback connection in the setup will be forwarded to the correct destination.

To sum this up in simpler terms, here's what needs to take place. I need to bounce the initial connection to the RTCP "registration" server properly (I can already accomplish this since this bounced connection requires no modification to the payload data). From here, after the connection is made the above packet is received by my non-loopback connection and 0x42 0xDA 0x46 0x20 needs to be replaced with 0x7F 0x00 0x00 0x01 and passed along as normal (which this bounce setup still accomplishes fine) to the loopback connection. When that happens a new connection is initiated from loopback and needs to be bounced to the original recv value of those Bytes (which again is an ip address) being replaced so that the destination is still intact but the payload being read by the module is different so that the connection has to run through the loopback connection first. If you need any more clarification in this if you're not understanding what I'm trying to do then I'll try and provide it with a diagram or something of that nature.

Thanks,
Thor371
0
 
Thor371Author Commented:
hello?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Russell LibbySoftware Engineer, Advisory Commented:
Still here, just got caught up in a few things.... my apologies.

I understand the RTP/RTCP protocol, but my understanding is that Yahoo has deviated slightly from the h.323, so I can't say that I can make complete sense of the packet as described above. If you are familiar with the protocol (structure) layout, that would help things.

The reason I mention this is because it is best to deal with the data being recvd->sent as the server would. Without that, we would be left with dealing with the data as raw bytes (which is do-able, but possibly prone to errors). If you give me about 20 mins, then I will provide a sample scan/modify function that demonstrates what I am describing.

Regards,
Russell
0
 
Russell LibbySoftware Engineer, Advisory Commented:

// Handling of the buffer data. This scans the buffer for the bytes 0x00000804 and then replaces the
// next 4 bytes with 0x7F000001. The original (and replaced) 4 bytes are returned as an integer if
// the function
function ModifyRtcpBuffer(Buffer: PByteArray; Size: Integer; out Original: Integer): Boolean;
var  lpBuffer:      PByteArray;
     dwCount:       Integer;
const
     LOOPBACK:      Array [0..3] of Byte = (127, 0, 0, 1);
     LEADINGBYTES:  Array [0..3] of Byte = (0, 0, 8, 4);
begin

  // Set default result
  result:=False;

  // Set default out param
  Original:=0;

  // Get pointer to byte array
  lpBuffer:=Buffer;

  // Set default position
  dwCount:=0;

  // Scan the buffer for 0x00 0x00 0x08 0x04, we will require the value AFTER that
  while (dwCount <= (Size-8)) do
  begin
     // Check the current 4 bytes
     if CompareMem(lpBuffer, @LEADINGBYTES, 4) then
     begin
        // Found the leading bytes
        Inc(PChar(lpBuffer), SizeOf(Integer));
        // Set out param
        Original:=Integer(Pointer(lpBuffer)^);
        // Modify the data
        CopyMemory(lpBuffer, @LOOPBACK, SizeOf(Integer));
        // Success
        result:=True;
        // Done
        break;
     end;
     // Push next
     Inc(PChar(lpBuffer));
     Inc(dwCount);
  end;

end;

// Snippet for data handling
var  Buffer:        Array [0..4095] of Byte;
     dwSize:        Integer;
     dwOriginal:    Integer;
begin

  // Recv the data
  dwSize:=recv(SocketRecv, Buffer, SizeOf(Buffer), 0);

  // Attempt to modify the data (possibly), check the result to determine if it WAS modified
  if ModifyRtcpBuffer(@Buffer, dwSize, dwOriginal) then
  begin
     // Save off the original or do whatever you need to do with the value.
     // While it is an integer, please note that it is easily cast into a
     // pointer to an array of bytes.
     if PByteArray(@dwOriginal)^[0] = 0 then
        beep;
  end;

  // Send the data to the outbound socket
  result:=(send(SocketSend, Buffer, dwSize, 0) = dwSize);

end;


Regards,
Russell

0
 
Thor371Author Commented:
Thanks Russell,

You definitely get the points as you have been very helpful and wise, but before I grade this one can you please help me put together a test example with the relay code in the last thread? There seems to be a couple small things for instance you said I should declare buffer as array of byte rather than of char etc. I placed the code where I think it should go and commented it,  it might not be correct in its placement. I'm new to winsock and delphi so i didn't want to break the code and make a fool of myself :( when things are in working form I understand them much better.

unit Bouncer;
////////////////////////////////////////////////////////////////////////////////
interface
////////////////////////////////////////////////////////////////////////////////
//   Include units
////////////////////////////////////////////////////////////////////////////////
uses
  Windows,
  SysUtils,
  WinSock;

function   bounce(saddr, daddr: u_long; sport, dport: Integer): Integer;
function   startWinsock: Integer;
function ModifyRtcpBuffer(Buffer: PByteArray; Size: Integer; out Original: Integer): Boolean;

implementation

////////////////////////////////////////////////////////////////////////////////
//   Protected vars
////////////////////////////////////////////////////////////////////////////////
var
  wsaData:          TWSAData;

function ModifyRtcpBuffer(Buffer: PByteArray; Size: Integer; out Original: Integer): Boolean;
var  lpBuffer:      PByteArray;
     dwCount:       Integer;
const
     LOOPBACK:      Array [0..3] of Byte = (127, 0, 0, 1);
     LEADINGBYTES:  Array [0..3] of Byte = (0, 0, 8, 4);
begin

  // Set default result
  result:=False;

  // Set default out param
  Original:=0;

  // Get pointer to byte array
  lpBuffer:=Buffer;

  // Set default position
  dwCount:=0;

  // Scan the buffer for 0x00 0x00 0x08 0x04, we will require the value AFTER that
  while (dwCount <= (Size-8)) do
  begin
     // Check the current 4 bytes
     if CompareMem(lpBuffer, @LEADINGBYTES, 4) then
     begin
        // Found the leading bytes
        Inc(PChar(lpBuffer), SizeOf(Integer));
        // Set out param
        Original:=Integer(Pointer(lpBuffer)^);
        // Modify the data
        CopyMemory(lpBuffer, @LOOPBACK, SizeOf(Integer));
        // Success
        result:=True;
        // Done
        break;
     end;
     // Push next
     Inc(PChar(lpBuffer));
     Inc(dwCount);
  end;
end;

function bounce(saddr, daddr: u_long; sport, dport: Integer): Integer;
var  fds:              TFDSet;
     rc, rc2:          Integer;
     max, count:       Integer;
     acceptSocket:     TSocket;
     connectedSocket:  TSocket;
     s:                TSocket;
     addr:             TSockAddrIn;
     buf:              Array [0..256] of Char; // Need to change to byte array for modification function to work
    dwOriginal: integer;  // out parameter for modification function
begin

  count:=0;

  rc:=startWinsock;
     if (rc <> 0) then
     begin
     MessageBox(0, PChar(Format('Fehler: startWinsock, fehler code: %d', [rc])), nil, MB_OK);
     result:=1;
     exit;
  end
  else
     MessageBox(0, 'Winsock gestartet!', nil, MB_OK);

  // create Socket
  acceptSocket:=socket(PF_INET, SOCK_STREAM, 0);
     if (DWORD(acceptSocket) = DWORD(INVALID_SOCKET)) then
  begin
     MessageBox(0, PChar(Format('Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
  else
     MessageBox(0, 'Socket erstellt!', nil, MB_OK);

  s:=socket(PF_INET, SOCK_STREAM, 0);
  if (DWORD(s) = DWORD(INVALID_SOCKET)) then
     begin
     MessageBox(0, PChar(Format('Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
     else
     MessageBox(0, 'Socket erstellt!', nil, MB_OK);

  // connect
  ZeroMemory(@addr, SizeOf(TSockAddrIn));
  addr.sin_family:=AF_INET;
  addr.sin_port:=htons(dport);
  addr.sin_addr.s_addr:=daddr;

     rc2:=connect(s, addr, SizeOf(TSockAddrIn));
     if (rc2 = SOCKET_ERROR) then
  begin
     MessageBox(0, PChar(Format('Fehler: connect gescheitert, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
     else
     MessageBox(0, 'Verbunden', nil, MB_OK);

  // bind socket
  ZeroMemory(@addr, SizeOf(TSockAddrIn));
  addr.sin_family:=AF_INET;
  addr.sin_port:=htons(sport);
  addr.sin_addr.s_addr:=saddr;
  rc:=bind(acceptSocket,addr, SizeOf(TSockAddrIn));
     if (rc = SOCKET_ERROR) then
  begin
     MessageBox(0, PChar(Format('Fehler: bind, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
     else
     MessageBox(0, 'Socket an port gebunden', nil, MB_OK);

  // go into listen Modus
  rc:=listen(acceptSocket, 10);
  if (rc = SOCKET_ERROR) then
  begin
     MessageBox(0, PChar(Format('Fehler: listen, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
  else
     MessageBox(0, 'acceptSocket ist im listen Modus....', nil, MB_OK);

  // accept connection
  connectedSocket:=accept(acceptSocket, nil, nil);

  if (DWORD(connectedSocket) = DWORD(INVALID_SOCKET)) then
  begin
     MessageBox(0, PChar(Format('Fehler: accept, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
  else
     MessageBox(0, 'Neue Verbindung wurde akzeptiert!', nil, MB_OK);

     max:=s;
     if (connectedSocket > max) then max:=connectedSocket;

     while (rc <> SOCKET_ERROR) and (rc2 <> SOCKET_ERROR) do
  begin
     FD_ZERO(fds);
     FD_SET(s, fds);
     FD_SET(connectedSocket, fds);
     select(Succ(max), @fds, nil, nil, 0);

        if FD_ISSET(connectedSocket, fds) then
     begin
        rc:=recv(connectedSocket, buf, 256, 0);
           buf[rc]:=#0;

{ ***

 if ModifyRtcpBuffer(@buf, rc, dwOriginal) then
  begin
     if PByteArray(@dwOriginal)^[0] = 0 then
        beep;
  end;
send(s, buf, rc, 0);

***}

 send(s, buf, rc, 0);
     end;

        if FD_ISSET(s, fds) then
     begin
           rc2:=recv(s, buf, 256, 0);
          buf[rc2]:=#0;
           send(connectedSocket, buf, rc2, 0);
     end;

        // Kill bouncer on disconnect
        if (rc = 0) then
     begin
        Inc(count);
        if (count > 1) then break;
     end;
  end;
  closesocket(acceptSocket);
  closesocket(connectedSocket);
end;

function startWinsock: Integer;
begin
  // Init the winsock library
  result:=WSAStartup(MAKEWORD(2,0), wsaData);
end;

end.

Thank You
Thor371
0
 
Russell LibbySoftware Engineer, Advisory Commented:

No problem on the test example...

One thing that I should make clear (as it is applicable not only to delphi, but C, C++, etc other languages) is that while I said an array of byte, an array of char is suitable for this task. The reason for this it that the data sizes are the same:

SizeOf(CHAR) = SizeOf(BYTE) = 1

The only difference between the 2 is type casting (how its viewed). An array of char can be considered an array of byte, as an integer = array of 4 bytes, a word = array of 2 bytes, etc. etc. Basically, its all in the interpretation of WHAT the data is. In this case, I view it as an array of byte because the data is not all textual (and null terminated). But as you will also see, I did not change your buffer declaration and it still works the same.
 
Other notes... ;-)
I am still unclear as to how the original IP address in the buffer is to be used (for later connections?), so I just put in some sample code that shows the IP addr (assuming that is what I think it is) in a message box. I declared it as an integer, but should you need to change the type; say to TInAddr, then feel free to do so... just so long as the out param buffer is >= 4 bytes.

If you run into problems then let me know, and I will try and assist further. And again, I apologize for any previous delays.

Kind regards,
Russell


unit bouncer;
////////////////////////////////////////////////////////////////////////////////
interface
////////////////////////////////////////////////////////////////////////////////
//   Include units
////////////////////////////////////////////////////////////////////////////////
uses
  Windows,
  SysUtils,
  WinSock;

function   bounce(saddr, daddr: u_long; sport, dport: Integer): Integer;
function   startWinsock: Integer;
function   ModifyRtcpBuffer(Buffer: PByteArray; Size: Integer; out Original: Integer): Boolean;

implementation

////////////////////////////////////////////////////////////////////////////////
//   Protected vars
////////////////////////////////////////////////////////////////////////////////
var
  wsaData:          TWSAData;

function ModifyRtcpBuffer(Buffer: PByteArray; Size: Integer; out Original: Integer): Boolean;
var  lpBuffer:      PByteArray;
     dwCount:       Integer;
const
     LOOPBACK:      Array [0..3] of Byte = (127, 0, 0, 1);
     LEADINGBYTES:  Array [0..3] of Byte = (0, 0, 8, 4);
begin

  // Set default result
  result:=False;

  // Set default out param
  Original:=0;

  // Get pointer to byte array
  lpBuffer:=Buffer;

  // Set default position
  dwCount:=0;

  // Scan the buffer for 0x00 0x00 0x08 0x04, we will require the value AFTER that
  while (dwCount <= (Size-8)) do
  begin
     // Check the current 4 bytes
     if CompareMem(lpBuffer, @LEADINGBYTES, 4) then
     begin
        // Found the leading bytes
        Inc(PChar(lpBuffer), SizeOf(Integer));
        // Set out param
        Original:=Integer(Pointer(lpBuffer)^);
        // Modify the data
        CopyMemory(lpBuffer, @LOOPBACK, SizeOf(Integer));
        // Success
        result:=True;
        // Done
        break;
     end;
     // Push next
     Inc(PChar(lpBuffer));
     Inc(dwCount);
  end;

end;

function bounce(saddr, daddr: u_long; sport, dport: Integer): Integer;
var  fds:              TFDSet;
     rc, rc2:          Integer;
     max, count:       Integer;
     acceptSocket:     TSocket;
     connectedSocket:  TSocket;
     s:                TSocket;
     lpszAddr:         PChar;
     addr:             TSockAddrIn;
     buf:              Array [0..256] of Char; // No change is required, as the data types char and byte
                                               // are the same size.
     dwOriginal:       Integer;  // out parameter for modification function
begin

  count:=0;
  dwOriginal:=0;

  rc:=startWinsock;

  lpszAddr:=inet_ntoa(TInAddr(saddr));
  if Assigned(lpszAddr) then MessageBox(0, lpszAddr, nil, MB_OK);

     if (rc <> 0) then
     begin
     MessageBox(0, PChar(Format('Fehler: startWinsock, fehler code: %d', [rc])), nil, MB_OK);
     result:=1;
     exit;
  end
  else
     MessageBox(0, 'Winsock gestartet!', nil, MB_OK);

  // create Socket
  acceptSocket:=socket(PF_INET, SOCK_STREAM, 0);
     if (DWORD(acceptSocket) = DWORD(INVALID_SOCKET)) then
  begin
     MessageBox(0, PChar(Format('Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
  else
     MessageBox(0, 'Socket erstellt!', nil, MB_OK);

  s:=socket(PF_INET, SOCK_STREAM, 0);
  if (DWORD(s) = DWORD(INVALID_SOCKET)) then
     begin
     MessageBox(0, PChar(Format('Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
     else
     MessageBox(0, 'Socket erstellt!', nil, MB_OK);

  // connect
  ZeroMemory(@addr, SizeOf(TSockAddrIn));
  addr.sin_family:=AF_INET;
  addr.sin_port:=htons(dport);
  addr.sin_addr.s_addr:=daddr;

     rc2:=connect(s, addr, SizeOf(TSockAddrIn));
     if (rc2 = SOCKET_ERROR) then
  begin
     MessageBox(0, PChar(Format('Fehler: connect gescheitert, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
     else
     MessageBox(0, 'Verbunden', nil, MB_OK);

  // bind socket
  ZeroMemory(@addr, SizeOf(TSockAddrIn));
  addr.sin_family:=AF_INET;
  addr.sin_port:=htons(sport);
  addr.sin_addr.s_addr:=saddr;
  rc:=bind(acceptSocket,addr, SizeOf(TSockAddrIn));
     if (rc = SOCKET_ERROR) then
  begin
     MessageBox(0, PChar(Format('Fehler: bind, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
     else
     MessageBox(0, 'Socket an port gebunden', nil, MB_OK);

  // go into listen Modus
  rc:=listen(acceptSocket, 10);
  if (rc = SOCKET_ERROR) then
  begin
     MessageBox(0, PChar(Format('Fehler: listen, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
  else
     MessageBox(0, 'acceptSocket ist im listen Modus....', nil, MB_OK);

  // accept connection
  connectedSocket:=accept(acceptSocket, nil, nil);

  if (DWORD(connectedSocket) = DWORD(INVALID_SOCKET)) then
  begin
     MessageBox(0, PChar(Format('Fehler: accept, fehler code: %d', [WSAGetLastError])), nil, MB_OK);
     result:=1;
     exit;
  end
  else
     MessageBox(0, 'Neue Verbindung wurde akzeptiert!', nil, MB_OK);

     max:=s;
     if (connectedSocket > max) then max:=connectedSocket;

     while (rc <> SOCKET_ERROR) and (rc2 <> SOCKET_ERROR) do
     begin
        FD_ZERO(fds);
        FD_SET(s, fds);
        FD_SET(connectedSocket, fds);
        select(Succ(max), @fds, nil, nil, nil);

     if FD_ISSET(connectedSocket, fds) then
     begin
        rc:=recv(connectedSocket, buf, 256, 0);
        buf[rc]:=#0;

        if ModifyRtcpBuffer(@buf, rc, dwOriginal) then
        begin
           // dwOriginal contains the original 4 bytes. I am assuming this is an
           // IP address, as we replaced it with 127.0.0.1. If so, then this
           // address is easily used in the socket functions, an example is given
           // below.
           lpszAddr:=inet_ntoa(TInAddr(dwOriginal));
           if Assigned(lpszAddr) then MessageBox(0, lpszAddr, nil, MB_OK);
        end;
        send(s, buf, rc, 0);

     end;
     if FD_ISSET(s, fds) then
     begin
        rc2:=recv(s, buf, 256, 0);
        buf[rc2]:=#0;
        send(connectedSocket, buf, rc2, 0);
     end;

     // Kill bouncer on disconnect
     if (rc = 0) then
     begin
        Inc(count);
        if (count > 1) then break;
     end;

  end;

  closesocket(acceptSocket);
  closesocket(connectedSocket);

end;

function startWinsock: Integer;
begin
  // Init the winsock library
  result:=WSAStartup(MAKEWORD(2,0), wsaData);
end;

end.

0
 
Thor371Author Commented:
Russell,
Thanks again and here's the points you earned! =) I appreciate both your patience and good attitude as it seems you're the only person assisting with my questions. A couple things I should address. With a slight modification to the modify function it's working. I did notice [probably my mistake] that it's writing loopback in more than one part of the packet. I take it 0084 isn't matched as a whole entity, rather portions matched? example++ packet says 00 00 (7F 00 00 01) is written here after too.

Not sure if this was rhetorical or not but you asked "I am still unclear as to how the original IP address in the buffer is to be used (for later connections?)", Yes you're right. That's the next question maybe you can assist me with (please don't feel obligated by any means though), but if you're up for the task in helping with the problem I will award you more points. I've opened another question here

 http://experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21406337.html

I'm interested in just about anything that uses RTP/RTCP or as you mentioned h.323 deviations (internet telephony) etc. etc.
I still have questions to ask but I understand that I should open another post and ask.

Thanks,
Thor371
0
 
Russell LibbySoftware Engineer, Advisory Commented:
Thor371,

Thanks for the points, much appreciated. And the modification your seeing has to do with what I mentioned earlier:

> The reason I mention this is because it is best to deal with the data being recvd->sent as the server would. Without that, we would be left with dealing
> with the data as raw bytes (which is do-able, but possibly prone to errors).

The data is being scanned as raw bytes, and if the sequence of 0084 appears more than once, well ;-) the data after it gets modified (as I said, prone to errors). If its always in the first packet, then you could just run the packets through the modify routine until the first match was found, then skip calling the modify routine. Or if there is MORE constant data (like the 0084) around the data being modified, that would help against "false" matches.

And yes, my question was rhetorical in a sense, and I was just looking to confirm what I *assumed* (hate to use that word <g>). Regarding the other open Q, I won't get a chance to look at it for a few days, but if no one else helps I will be sure to at least attempt assistance.

Russell
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now