I'm apologizing before hand, but this is my call for help because I just can't write code very well anymore
Or am just not thinking.... probably the latter ;).
I'm still not getting it to work for me. My newbiness has definitely gotten me in a bind
Maybe this is my massive bit of desperation. But I can implement what I want to in C (when creating the packet)
But I still need Perl to interpret the data from a web page.
Could I just possibly interface this C code with my perl to generate the packet for me?
Perl will just pass the values through to my C code with the correct arguments?
#include "Simple.h"
#include "Mad.h"
#include "RcvIpcPorts.h"
#define MAD_SIZE 512
void longswapheader(MadHeader *pmh)
{
U32 i;
U32 *pl = (U32 *)pmh;
for ( i = 0; i < sizeof(MadHeader) ; i+=4, pl++ )
{
*pl = ntohl(*pl);
}
}
int SendMad(U8 *buffer, int sd, struct sockaddr_in *send_addr, U16 att
+r)
{
MadHeader *pmh;
fd_set fds;
int bytes;
printf("Press Enter to Send...\n");
getchar();
pmh = (MadHeader *)buffer;
pmh->BaseVersion = 0;
pmh->ClassId = Mad_Class_V_ComMgt;
pmh->ClassVersion = 1;
pmh->R = 0;
pmh->MethodId = Method_CM_Send; /* 3== send */
pmh->Status = 0;
pmh->ClassSpecific = 0;
pmh->TransactionId = 0;
pmh->AttributeId = attr;
pmh->rsv0 = 0;
pmh->AttributeModifier = 0;
longswapheader(pmh);
FD_ZERO(&fds);
FD_SET(sd, &fds);
if ((select(32/*sd+1*/, (fd_set *) 0, &fds, (fd_set *) 0, (struct
+timeval *) 0) < 1) ||
!FD_ISSET(sd, &fds))
{
printf("select failed err %d\n", errno);
return -1;
}
else
{
bytes = sendto(sd, buffer, MAD_SIZE, 0, (__SOCKADDR_ARG)send_a
+ddr, sizeof(struct sockaddr_in));
}
return bytes;
}
int main(int argc, char *argv[])
{
int sd, rc;
int passive = 0;
struct sockaddr_in addr, recv_addr, send_addr;
MadHeader *pmh;
U8 send_buffer[MAD_SIZE], receive_buffer[MAD_SIZE];
CommID lcid, rcid;
sd= socket(PF_INET, SOCK_DGRAM, 0);
printf("socket sd %d\n", sd);
if ( sd == -1 )
{
printf("socket failed\n");
}
memset(&addr, 0, sizeof(addr));
memset(&recv_addr, 0, sizeof(recv_addr));
memset(&send_addr, 0, sizeof(send_addr));
memset(send_buffer, 0, sizeof(send_buffer));
memset(receive_buffer, 0, sizeof(receive_buffer));
addr.sin_family = PF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
send_addr.sin_family = AF_INET;
if ( (argc > 1) && (strcmp(argv[1],"passive") == 0) )
{
passive = 1;
send_addr.sin_port = htons(CMA_P_PORT);
addr.sin_port = htons(IBIS_P_PORT);
}
else
{
passive = 0;
send_addr.sin_port = htons(CMA_A_PORT);
addr.sin_port = htons(IBIS_A_PORT);
}
send_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if ( bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0 )
{
printf("bind failed\n");
}
pmh = (MadHeader *)send_buffer;
int i;
if ( passive )
{
for ( i=0; i < 1; i=1)
{
// receive a REQ
rc = ReceiveMad(receive_buffer, sd, &recv_addr);
if ( rc < 0 ) continue;
lcid = ((MadPacket *)receive_buffer)->Payload.REQ.commID;
rcid = ((MadPacket *)receive_buffer)->Payload.REQ.rsv0;
printf("lcid %lu rcid %lu\n", lcid, rcid);
// send REP
((MadPacket *)send_buffer)->Payload.REP.commID = lcid;
((MadPacket *)send_buffer)->Payload.REP.remCommID = rcid;
rc = SendMad(send_buffer, sd, &send_addr, Attr_CM_ConnectR
+eply);
if ( rc < 0 ) continue;
// receive an RTU
rc = ReceiveMad(receive_buffer, sd, &recv_addr);
if ( rc < 0 ) continue;
// receive DREQ
rc = ReceiveMad(receive_buffer, sd, &recv_addr);
if ( rc < 0 ) continue;
// send DREP
((MadPacket *)send_buffer)->Payload.REP.commID = lcid;
((MadPacket *)send_buffer)->Payload.REP.remCommID = rcid;
rc = SendMad(send_buffer, sd, &send_addr, Attr_CM_Disconne
+ctReply);
if ( rc < 0 ) continue;
}
}
else
{
for ( i=0; i < 1; i=1)
{
// send REQ
rc = SendMad(send_buffer, sd, &send_addr, Attr_CM_ConnectR
+equest);
if ( rc < 0 ) continue;
// receive REP
rc = ReceiveMad(receive_buffer, sd, &recv_addr);
if ( rc < 0 ) continue;
lcid = ((MadPacket *)receive_buffer)->Payload.REP.commID;
rcid = ((MadPacket *)receive_buffer)->Payload.REP.remCommI
+D;
printf("lcid %lu rcid %lu\n", lcid, rcid);
((MadPacket *)send_buffer)->Payload.RTU.commID = lcid;
((MadPacket *)send_buffer)->Payload.RTU.remCommID = rcid;
// send RTU
rc = SendMad(send_buffer, sd, &send_addr, Attr_CM_ReadyToU
+se);
if ( rc < 0 ) continue;
// send DREQ
((MadPacket *)send_buffer)->Payload.DREQ.commID = lcid;
((MadPacket *)send_buffer)->Payload.DREQ.remCommID = rcid;
rc = SendMad(send_buffer, sd, &send_addr, Attr_CM_Disconne
+ctRequest);
if ( rc < 0 ) continue;
// receive DREP
rc = ReceiveMad(receive_buffer, sd, &recv_addr);
if ( rc < 0 ) continue;
}
}
close(sd);
return 0;
}
So that's my C. But my ugly arse PERL code looks like this:
#madtest.cgi - perl script that interprets a user inputted mad for
#agent testing.
use Socket;
use Sys::Hostname;
%postInputs = readPostInput();
my ( $count, $hisiaddr, $hispaddr, $histime,
$host, $iaddr, $paddr, $port, $proto,
$rin, $rout, $rtime, $SECS_of_70_YEARS, $setipaddr);
$setipaddr = $postInputs{'IPAddress'};
$ipaddr = inet_aton($setipaddr);
$PORTNO = 7777;
$MAD_SIZE = 512;
$proto = getprotobyname('udp');
$paddr = sockaddr_in($PORTNO, $ipaddr); # port, ipaddress
@madArray = ($postInputs{'BaseVersion'}, $postInputs{'MgmtClass'}
+, $postInputs{'ClassVersion'}, $postInputs{'Method'}, (pack "s", $pos
+tInputs{'Status'}), (pack "s", $postInputs{'ClassSpecific'}), (pack
+"s", $postInputs{'AttributeID'}), $postInputs{'Reserved'}, (pack "l",
+ $postInputs{'AttributeModifier'}), (pack "Z",$postInputs{'Data'}));
$packet= pack( "c c c C n n NN n N a*",
$postInputs{'BaseVersion'}, $postInputs{'MgmtClass'}, $postInpu
+ts{'ClassVersion'}, ($postInputs{'R'}<<7)|$postInputs{'Method'}, $pos
+tInputs{'Status'},
$postInputs{'ClassSpecific'}, $postInputs{TransactionID_Hi}, $T
+ransID_Lo, $postInputs{'Reserved'}, $postInputs{'AttributeModifier'}
,$postInputs{'Data'});
#Next Throw data out to a UDP Server (Our Interprocess Communication.)
#
#Go into binary mode
binmode (SOCKET);
select(socket(SOCKET, PF_INET, SOCK_DGRAM, $proto)) || die "socket:
+$!";
#bind(SOCKET, $paddr) || die "bind: $!";
#$| = 1;
$z2=0;
while ($z2 < $madCount)
{
send(SOCKET, $packet, 0, $paddr);
#this doesn't work, obviously. :( send(SOCKET, $packet, MAD_SIZE, $pad
+dr);
$z2++;
}
close(SOCKET) || die "dead socket: $!";
select(STDOUT);
printThankYou();
####Method that splits up pair/values
sub readPostInput(){
my (%searchField, $buffer, $pair, @pairs);
if ($ENV{ 'REQUEST_METHOD'} eq 'POST'){
read(STDIN, $buffer, $ENV{ 'CONTENT_LENGTH'});
#separate the name values into an array named @pairs
@pairs = split (/&/, $buffer);
#Array is then Url decoded into $searchField hash.
foreach $pair (@pairs){
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])
/pack("C", hex($1))/eg;
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])
/pack("C", hex($1))/eg;
$searchField{ $name} = $value;
}
}
return (%searchField);
}
#return a web page
sub printThankYou(){
# no need to actually put this in for example.
}
2001-10-13 Edit by Corion : Added CODE tags |