Commit 8ace455f authored by Damien Lucas's avatar Damien Lucas

Some modifications in structures in order to be compliant with:

    . SAP (RFC 2974)
    . SDP (RFC 2327)

Now, packets are compliant. But there is still a lot of work to fully
implement the RFCs
parent 9b612d0e
default: all
all: sapserver
g++ -Wall -o sapserver sapserver.cpp
all:
g++ -Wall -c -o program.o program.cpp
g++ -Wall -c -o message.o message.cpp
g++ -Wall -c -o parser.o parser.cpp
g++ -Wall -c -o broadcast.o broadcast.cpp
g++ -Wall -o sapserver sapserver.cpp message.o parser.o program.o broadcast.o
clean:
rm -f sapserver
rm -f sapserver message.o program.o parser.o broadcast.o
distclean: clean
/*****************************************************************************
* broadcast.cpp : SAP Broadcast class
****************************************************************************
* Copyright (C) 1998-2003 VideoLAN
* $Id: broadcast.cpp,v 1.1 2003/05/22 02:22:45 nitrox Exp $
*
* Authors: Damien Lucas <nitrox@videolan.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string>
#include <vector>
using namespace std;
#include "program.h"
#include "message.h"
#include "broadcast.h"
Broadcast::Broadcast(unsigned int t)
{
group=HELLO_GROUP;
port=HELLO_PORT;
ttl=t;
return;
}
Broadcast::~Broadcast(){return;}
int Broadcast::Init(void)
{
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0)
{
perror("socket");
return(-1);
}
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(group);
addr.sin_port=htons(port);
setsockopt( fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl) );
return 0;
}
int Broadcast::Send(Message* m)
{
/* Create the final message */
m->CreateFinalMessage();
/* Get the message and the length */
char* message=m->GetFinalMessage();
unsigned int length=m->GetFinalMessageLen();
if(message==NULL)
{
fprintf(stderr, "Bad message, skipping\n");
return (-1);
}
if (sendto(fd,message,length,0,
(struct sockaddr *) &addr,sizeof(addr)) < 0)
{
perror("sendto");
return(-1);
}
return 0;
}
/*****************************************************************************
* broacast.h : SAP Broadcast Class definition
****************************************************************************
* Copyright (C) 1998-2003 VideoLAN
* $Id: broadcast.h,v 1.1 2003/05/22 02:22:45 nitrox Exp $
*
* Authors: Damien Lucas <nitrox@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define HELLO_PORT 9875
#define HELLO_GROUP "224.2.127.254"
class Broadcast {
public:
Broadcast(unsigned int t);
~Broadcast();
int Init(void);
int Send(Message*);
private:
int fd; /* File descriptor on the socket */
struct sockaddr_in addr; /* IP Address to broadcast to */
char* group;
uint16_t port;
unsigned int ttl;
};
/*****************************************************************************
* message.cpp : SAP Message class
****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: message.cpp,v 1.1 2003/05/22 02:22:45 nitrox Exp $
*
* Authors: Damien Lucas <nitrox@videolan.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
#include "program.h"
#include "message.h"
/*****************************************************************************
* Constructors
*****************************************************************************/
Message::Message(char t, uint16_t v, const char* ip)
{
version = v;
compressed = 0;
encrypted = 0;
type = t;
ip_server=inet_addr(ip); //TODO automaticaly get it ?
msg=NULL;
sdp="";
sap=NULL;
return;
}
/*****************************************************************************
* Destructor
*****************************************************************************/
Message::~Message(void)
{
if(msg) free(msg);
if(sap) free(sap);
return;
}
void Message::SetEncrypted(void)
{
fprintf(stderr, "Encryption is not available\n");
return;
}
void Message::SetCompressed(void)
{
fprintf(stderr, "Compression is not available\n");
return;
}
/*****************************************************************************
* BuildHeader - Build the Message Header once initialized
* According to RFC 2974
*****************************************************************************/
void Message::BuildHeader(void)
{
unsigned int mh_size;
mh_size = 4;
mh_size += 4; //(IPv4 specific)
// size+= authentification length (N/A)
// size+= optional payload type (N/A) (always 3 for stuffing)
mh_size += 3;
sap=(char*)malloc(mh_size*sizeof(char));
/* Byte 1 : Version number V1 = 001 (3 bits)
* Address type IPv4/IPv6 = 0/1 (1 bit)
* Reserved 0 (1 bit)
* Message Type ann/del = 0/1 (1 bit)
* Encryption on/off = 0/1 (1 bit)
* Compressed on/off = 0/1 (1 bit) */
sap[0]=0x20;
//if ( ip_version == SAP_IPV6 ) sap[0]|=0x10;
if ( type == SAP_DELETE ) sap[0]|=0x04;
if ( encrypted == SAP_ON ) sap[0]|=0x02;
if ( compressed == SAP_ON ) sap[0]|=0x01;
/* Byte 2 : Authentification length - Not supported */
sap[1]=0x00;
/* Byte 3 & Byte 4 : Message Id Hash */
sap[2]=version;
sap[3]=version>>8;
/* next 4 (or 16) byte: Originating source */
sap[4]=ip_server;
sap[5]=ip_server>>8;
sap[6]=ip_server>>16;
sap[7]=ip_server>>24;
sap[8]='v';
sap[9]='=';
sap[10]='0';
header_len=11;
return;
}
void Message::AddProgram(Program *p)
{
// TODO Ugly, only , ... more than one program ??
// RFC 2327 Compliance ?
string o="o="+p->GetUser()+" 3247692199 3247895918 IN IP4 "+
p->GetMachine()+" \n";
string s="s="+p->GetName()+" \n";
string u="u="+p->GetSite()+" \n";
string t="t=3247691400 32501 17800 \n";
string a="a=type:test \n";
string m="m=audio 1234 udp 14 \n";
string c="c=IN IP4 "+p->GetAddress()+"/15 \n";
sdp += o + s + u + t + a + m + c;
return;
}
void Message::CreateFinalMessage(void)
{
unsigned int i;
/* Check the length */
msg_len = sdp.size() + header_len;
if(msg_len>1024)
{
msg_len=0;
msg=NULL; //RFC 2974 Chap 6.
return;
}
msg=(char*)malloc(msg_len*sizeof(char));
for(i=0; i<header_len; i++)
{
msg[i]=sap[i];
}
for(; i<msg_len; i++)
{
msg[i]=sdp[i-header_len];
}
}
char* Message::GetFinalMessage(){return msg;}
unsigned int Message::GetFinalMessageLen(){return msg_len;}
/*****************************************************************************
* message.h : SAP Message Class definition
****************************************************************************
* Copyright (C) 1998-2003 VideoLAN
* $Id: message.h,v 1.1 2003/05/22 02:22:45 nitrox Exp $
*
* Authors: Damien Lucas <nitrox@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define SAP_ON 1
#define SAP_OFF 0
#define SAP_ANNOUNCE 0
#define SAP_DELETE 1
#define SAP_IPV4 4
#define SAP_IPV6 6
class Message {
public:
Message(char message_type, uint16_t version, const char* ip);
~Message();
void BuildHeader(void);
void AddProgram(Program*);
void SetEncrypted();
void SetCompressed();
void CreateFinalMessage();
char* GetFinalMessage();
unsigned int GetFinalMessageLen();
private:
uint16_t version; // Version of this annoucement
bool compressed; // Is the message compressed with zlib ?
bool encrypted; // Is the message encrypted ?
uint8_t type; // Announce or Deletion
uint32_t ip_server; // IP of the server (IPV4 specific)
char* sap; // header of the message
string sdp; // SDP message
char* msg; // final message
unsigned int header_len; //len of the SAP HEADER
unsigned int msg_len; //len of the complete packet
};
/*****************************************************************************
* parser.cpp : SAP configuration file parser
****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: parser.cpp,v 1.1 2003/05/22 02:22:45 nitrox Exp $
*
* Authors: Fabrice Ollivier <cif@via.ecp.fr>
* Arnaud Schauly <gitan@via.ecp.fr>
* Clment Stenac <zorglub@via.ecp.fr>
* Damien Lucas
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string>
#include <vector>
using namespace std;
#include "sapserver.h"
#include "program.h"
#include "message.h"
#include "parser.h"
Config::Config(string f)
{
file=f;
ttl=DEFAULT_TTL;
}
Config::~Config()
{
//TODO free the Programs table
}
unsigned int Config::GetTTL()
{
return ttl;
}
void Config::SetTTL(unsigned int t)
{
ttl=t;
}
bool Config::GetDaemonMode(void)
{
return daemon;
}
void Config::SetDaemonMode(bool d)
{
daemon=true;
}
void Config::SetFile(char* s)
{
file=s;
}
/**********************************************************
* Gets what is before delim in source. Puts it into dest *
**********************************************************/
void Config::strgetb(char *source,char *dest,char delim)
{
unsigned long i = 0;
while(source[i] != delim && i < strlen(source))
{
dest[i]=source[i];
i++;
}
dest[i]=0;
}
/**********************************************************
* Gets what is before delim in source. Puts it into dest *
**********************************************************/
void Config::strgeta(char *source,char *dest,char delim)
{
unsigned long i=0,j=0;
dest[0]=0;
while(source[i] != delim && i < strlen(source))
{
i++;
}
i++;
if(i>=strlen(source))
{
return;
}
while(i < strlen(source))
{
if(source[i]!='\n') dest[j]=source[i];
else dest[j]=0;
j++;i++;
}
dest[j]=0;
}
/********************************************************************
Reads the configuration file and fills the program list
*********************************************************************/
int Config::Parse()
{
FILE *fd;
char line[1024]; //TODO line length should not be limited
char tline[1024];
unsigned int something=0;
Program *pp= new Program();
fd=fopen(file.c_str(),"r");
if(!fd)
{
fprintf(stderr, "Unable to open %s\n",file.c_str());
return(-1);
}
while(!feof(fd))
{
memset(line,'0',1024);
fgets(line,1024,fd);
if(!strlen(line))
{
break;
}
strgetb(line,line,'#'); /* Handle the comments */
if(strstr(line,"ttl="))
{
strgeta(line,tline,'=');
ttl=atoi(tline);
}
if(strstr(line,"[program]"))
{
if(something)
{
/* We were in a program with at least one field filled */
Programs.push_back(pp);
pp=new Program();
something=0;
}
}
if(strstr(line,"name="))
{
strgeta(line,tline,'=');
something=1;
pp->SetName(tline);
}
if(strstr(line,"user="))
{
strgeta(line,tline,'=');
something=1;
pp->SetUser(tline);
}
if(strstr(line,"machine="))
{
strgeta(line,tline,'=');
something=1;
pp->SetMachine(tline);
}
if(strstr(line,"site="))
{
strgeta(line,tline,'=');
something=1;
pp->SetSite(tline);
}
if(strstr(line,"address="))
{
strgeta(line,tline,'=');
something=1;
pp->SetAddress(tline);
}
}
if(something) Programs.push_back(pp);
return(0);
}
/*****************************************************************************
* parser.h : SAP configuration file parser definition
****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: parser.h,v 1.1 2003/05/22 02:22:45 nitrox Exp $
*
* Authors: Fabrice Ollivier <cif@via.ecp.fr>
* Arnaud Schauly <gitan@via.ecp.fr>
* Clment Stenac <zorglub@via.ecp.fr>
* Damien Lucas <nitrox@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
class Config
{
public:
Config(string);
~Config();
int Parse();
unsigned int GetTTL();
void SetTTL(unsigned int);
bool GetDaemonMode(void);
void SetDaemonMode(bool);
void SetFile(char*);
vector<Program*> Programs;
private:
string file;
int ttl;
bool daemon;
void strgetb(char *source,char *dest,char delim);
void strgeta(char *source,char *dest,char delim);
};
/*****************************************************************************
* program.cpp : SAP Program class
****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: program.cpp,v 1.1 2003/05/22 02:22:45 nitrox Exp $
*
* Authors: Damien Lucas <nitrox@videolan.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
#include "program.h"
Program::Program() {return;}
Program::~Program() {return;}
string Program::GetName(void) {return name;}
string Program::GetUser(void) {return user;}
string Program::GetMachine(void) {return machine;}
string Program::GetSite(void) {return site;}
string Program::GetAddress(void){return address;}
void Program::SetName(char* n){name=n;}
void Program::SetUser(char* u){user=u;}
void Program::SetMachine(char* m){machine=m;}
void Program::SetSite(char* s){site=s;}
void Program::SetAddress(char* a){address=a;}
Program::Program(string n, string u, string m, string s, string a)
{
name=n;
user=u;
machine=m;
site=s;
address=a;
}
/*****************************************************************************
* program.h : SAP programs classes definition
****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: program.h,v 1.1 2003/05/22 02:22:45 nitrox Exp $
*
* Authors: Damien Lucas <nitrox@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
class Program
{
public:
Program(string, string, string, string, string);
Program();
~Program();
string GetName();
string GetUser();
string GetMachine();
string GetSite();
string GetAddress();
void SetName(char*);
void SetUser(char*);
void SetMachine(char*);
void SetSite(char*);
void SetAddress(char*);