#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include "cp343.h"
void hilfe(void);
void splash(void);
int cp343_connect(char *host, int port, int v);
void cp343_release(int socket);
void cp343_standard(cp343header *d);
int cp343_fetch(int s, cp343header *h, void *data, int v);
int cp343_write(int s, cp343header *h, void *data, int v);
void cp343_dump(void *data, int n);
void cp343_dumpword(void *d, int n);
int main(int argc, char **argv)
{
int fs, ws, v=1, fe=0, wr=0;
static char *ziel=0;
int wport=2000;
int fport=2001;
unsigned char fdb, wdb;
char c;
int bytes=0, i;
cp343header send;
cp343header rec;
void *data;
unsigned char *l;
unsigned char *h;
data = calloc(1, MAXBUF);
ziel=calloc(1,1024);
strcpy(ziel,"cp343");
fdb=41; /* Standardmässig DB41 abfragen für Fetch */
wdb=50; /* Standardmässig DB41 abfragen für Write */
// Komandozeile Auswerten
while((c=getopt(argc, argv, "hfwd:p:vF:W:"))>0)
{
switch(c)
{
case 'h': hilfe(); exit(0); break;
case 'd': strcpy(ziel, optarg); break;
case 'p': fport=atoi(optarg); break;
case 'v': v++; break;
case 'f': fe++; break;
case 'w': wr++; break;
case 'F': fdb=atoi(optarg); break;
case 'W': wdb=atoi(optarg); break;
default: hilfe(); exit(0); break;
}
}
splash();
printf("Vedrbinde mit: %s, Port: %d \n", ziel, fport);
fs=cp343_connect(ziel, fport, v);
if(!fs)
{
printf("Fehler: Keine Verbindung zu %s:%d\n", ziel, fport);
return(1);
}
printf ("Verbunden mit %s:%d\n", ziel, fport);
printf("Verbinde mit: %s, Port: %d \n", ziel, wport);
ws=cp343_connect(ziel, wport, v);
if(!ws)
{
printf("Fehler: Keine Verbindung zu %s:%d\n", ziel, wport);
return(1);
}
printf ("Verbunden mit %s:%d\n", ziel, wport);
// Bereite Empfangsdaten für FETCH vor
cp343_standard(&rec);
rec.opcode=5;
rec.orgblock=3;
rec.orglgt=8;
rec.idorg=0x01;
rec.dbnr=fdb;
rec.start_msb=0;
rec.start_lsb=0;
rec.lgt_msb=0;
rec.lgt_lsb=10;
rec.empty=0xff;
rec.empty_lgt=2;
if(fe) cp343_fetch(fs, &rec, data, v);
// Bereite Sendedaten für WRITE vor
memset(data, 0, MAXBUF);
cp343_standard(&send);
send.opcode=3;
send.orgblock=3;
send.orglgt=8;
send.idorg=0x01;
send.dbnr=wdb;
send.start_msb=0;
send.start_lsb=0;
send.lgt_msb=0;
send.lgt_lsb=10;
send.empty=0xff;
send.empty_lgt=2;
bytes=(256*send.lgt_msb + send.lgt_lsb)*2;
// Daten erzeugen
for(i=0; i<bytes; i=i+2)
{
l=data+i+1; h=data+i; *l=i/2;
}
if(wr) cp343_write(ws, &send, data, v);
cp343_release(fs);
if(v) printf ("Verbindung mit %s : %d getrennt\n", ziel, fport);
cp343_release(ws);
if(v) printf ("Verbindung mit %s : %d getrennt\n", ziel, wport);
return(0);
}
int cp343_connect(char *cp, int port, int v)
{
struct protoent *protocol;
struct hostent *he;
struct sockaddr_in s7cp;
int s;
protocol = getprotobyname("TCP");
if (!protocol)
{
printf("TCP Protokoll nicht verwendbar\n");
return (0);
}
// Ereugen eines Sockets
s = socket(AF_INET, SOCK_STREAM, protocol->p_proto);
if(!s)
{
printf("Fehler: Socket nicht anlegbar\n");
return(0);
}
// Umrechnen des gegebenen Hostnamens via gethostbyname()
if ((he = gethostbyname(cp)) == NULL)
{
printf("Fehler: Host nicht bestimmbar\n");
return(0);
}
// umkopieren der Adressdaten in die Socket Strukturen
memcpy(&s7cp.sin_addr, he->h_addr_list[0], he->h_length);
s7cp.sin_family = AF_INET;
s7cp.sin_port = htons(port);
// Connect ausführen zum Zielsystem
if (connect(s, (struct sockaddr *)&s7cp, sizeof(s7cp)))
{
printf("Fehler: Connect \n");
return(0);
}
return(s);
}
void cp343_release(int socket)
{
close(socket);
}
/** Funktion: cp343_standard(cp343header *d)
* Einen cp343 Header mit Standard daten vorbelegen
*/
void cp343_standard(cp343header *d)
{
memset(d, 0, sizeof(cp343header));
d->sysid[0]='S';
d->sysid[1]='5';
d->headerlgt=16;
d->idopcode=1;
d->idopcodelgt=3;
d->empty=0xff;
d->empty_lgt=2;
}
int cp343_fetch(int s, cp343header *h, void *data, int v)
{
int c=0;
int b=0;
void *bd=0;
// Anfragetelegramm für FETCH schreiben
b=sizeof(cp343header);
memcpy(data, h, b);
bd=data+b;
c=write(s, data, b);
printf("%d Fetch: Bytes geschrieben\n",c);
if(v>1) cp343_dump(data, 0);
// Status Antwort abholen
printf("Versuche Antwortblock 16 Bytes zu lesen\n");
//sync();
memset(data, 0, sizeof(cp343header));
c=read(s, data, 16);
printf("%d Status Bytes gelesen\n",c);
if(v>1) cp343_dump(data, 0);
b=(256*h->lgt_msb + h->lgt_lsb)*2;
memset(data, 0, MAXBUF);
h=data;
if((h->idorg) == 0 && v>1)
{
c=read(s, data, b);
if(v>1) cp343_dumpword(data, b/2);
printf("%c",c);
}
return(c);
}
int cp343_write(int s, cp343header *h, void *data, int v)
{
int c=0;
int b=0;
void *bd=0;
static void *buffer=0;
if(!buffer) buffer=calloc(1, MAXBUF);
// Anfragetelegramm für FETCH schreiben
b=sizeof(cp343header);
memcpy(buffer, h, b);
bd=buffer+b;
memcpy(bd, data, b);
b+=sizeof(cp343header);
c=write(s, buffer, b);
if (v) printf("%d Write: Bytes geschrieben\n",c);
if(v>1)
cp343_dump(data, 0);
if(v>1)
cp343_dumpword(bd,(256*h->lgt_msb + h->lgt_lsb));
// Status Antwort abholen
if(v) printf("Versuche Antwortblock %u zu lesen\n", (unsigned char) sizeof(cp343header));
memset(buffer, 0, MAXBUF);
sync();
c=read(s, buffer, sizeof(cp343header));
h=buffer;
if(v) printf("%d Status Bytes gelesen, Status: %c %c\n",c, h->idorg, h->dbnr);
if(v>1) cp343_dump(buffer, 0);
return(h->idorg);
}
void cp343_dump(void *d, int n)
{
int i;
unsigned char *c;
if(!n)
{
printf("Ausgabe des Header\n");
n=16;
}
else
printf ("Ausgabe der Daten\n");
for(i=0; i<n; i++)
{
c=d+i;
if(*c >32)
printf("%02d 0x%02x: %03d 0x%02x %c\n",i, i, *c, *c, *c);
else
printf("%02d 0x%02x: %03d 0x%02x\n",i, i, *c, *c);
}
}
/** Funktion: Daten Dumpen Bytes
*
*/
void cp343_dumpword(void *d, int n)
{
int i;
unsigned char *h;
unsigned char *l;
printf ("Ausgabe der Daten\n");
for(i=0; i<n*2; i=i+2)
{
h=d+i;
l=d+i+1;
printf("Word %02d 0x%02x: 0x%02x%02x\n", i/2, i/2, *h, *l);
}
}
void splash()
{
printf("==============================================\n");
printf(" -_-_ Jojo's kleines cp343 Testprogramm _-_- \n");
printf(" -_-_ (c) 2003 automatiX GmbH _-_- \n");
printf(" -_-_ http://www.automatix.de _-_- \n");
printf("==============================================\n");
}
/**
*
*
*/
void hilfe(void)
{
splash();
printf ("Hilfe:\n");
printf ("Dies kleine Testprogramm versucht eine Verbindung zu einem\n");
printf ("Siemens(tm) S7 CP343-1 Kommunikationsprozessor aufzubauen.\n");
printf ("\n");
printf ("Gebrauch:\n");
printf ("cp343 [Optionen]\n");
printf ("\n");
printf ("Optionen sind\n");
printf ("-v Anzeige von Rückmeldungen, mehrfach auffrufen, um detailiertere\n");
printf (" Meldungen zu erhalten\n");
printf ("-p Protokoll, Standard ist TCP/IP\n");
printf ("-d Zielrechner als FQDN, Name, keine 4-fache Dezimale\n");
printf ("-f Löse eine FETCH Operation aus\n");
printf ("-w Löse eine WRITE Operation aus\n");
printf ("\n");
}