CC= gcc
#CFLAGS= -Wall -Wunused
CFLAGS=
-DEFS= md5.h iputils.h utils.h pidfile.h cfreader.h icmpcheck.h tcpcheck.h httpget.h smtpwrapper.h ipvswrapper.h keepalived.h
-OBJECTS= md5.o iputils.o utils.o pidfile.o cfreader.o icmpcheck.o tcpcheck.o httpget.o smtpwrapper.o ipvswrapper.o keepalived.o
+DEFS= md5.h iputils.h utils.h pidfile.h cfreader.h icmpcheck.h tcpcheck.h httpget.h smtpwrapper.h ipvswrapper.h libipfwc/libipfwc.h libipfwc/ipfwc_kernel_headers.h ipfwwrapper.h keepalived.h
+OBJECTS= md5.o iputils.o utils.o pidfile.o cfreader.o icmpcheck.o tcpcheck.o httpget.o smtpwrapper.o ipvswrapper.o ipfwwrapper.o libipfwc/libipfwc.a keepalived.o
INCLUDE= -I/usr/src/linux/include
.c.o:
-# $(CC) -o $@ $(CFLAGS) $(INCLUDE) -c $*.c
- $(CC) -o $@ $(INCLUDE) -DDEBUG -c $*.c
+ $(CC) -o $@ $(CFLAGS) $(INCLUDE) -c $*.c
all: $(EXEC)
strip $(EXEC)
$(EXEC): $(OBJECTS) $(DEFS)
$(CC) -o $(EXEC) $(CFLAGS) $(OBJECTS)
-clean:
- rm -f core *.o $(EXEC) /etc/lvs.conf /etc/keepalived/keepalived.conf /usr/sbin/keepalived /usr/bin/genhash
- rm -rf /etc/keepalived
+libipfwc/libipfwc.a:
+ cd libipfwc/ && $(MAKE) libipfwc.a
+
+subclean:
+ cd libipfwc/ && $(MAKE) clean
+
+clean: subclean
+ rm -f core *.o $(EXEC)
install:
install -m 700 keepalived /usr/sbin/
mkdir /etc/keepalived
mkdir /etc/keepalived/log
touch /etc/keepalived/log/keepalived.log
- install -m 644 etc/lvs.conf /etc/
install -m 644 etc/keepalived/keepalived.conf /etc/keepalived/
* data structure representation the conf file representing
* the loadbalanced server pool.
*
- * Version: $Id: cfreader.c,v 0.2.6 2001/03/01 $
+ * Version: $Id: cfreader.c,v 0.2.1 2000/12/09 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
- * Alexandre Cassen : 2001/03/01 :
- * <+> Change the dynamic data structure. Move to a tree data
- * structure.
- * <+> Revisited the pointer handling for the dynamic data
- * structure.
- * <+> Adding keywords support for the configuration file.
- * <+> Adding support for email notification.
- *
- * Alexandre Cassen : 2000/12/09 : Initial release
+ * Alexandre Cassen : Initial release
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*
* Part: cfreader.c include file.
*
- * Version: $Id: cfreader.h,v 0.2.6 2001/03/01 $
+ * Version: $Id: cfreader.h,v 0.2.1 2000/12/09 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
- * Alexandre Cassen : 2001/03/01 :
- * <+> Adding keywords.
- * <+> Change change the whole data structure.
- * <+> Adding LVS ID & notification email for alertes.
- *
- * Alexandre Cassen : Initial release : 2000/12/09
+ * Alexandre Cassen : Initial release
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
virtualserver *lvstopology;
} configuration_data;
+/* prototypes */
+//configuration_data * ConfReader(configuration_data *conf_data);
+//void ClearConf(configuration_data * lstptr);
+//void PrintConf(configuration_data * lstptr);
+
#endif
+++ /dev/null
-# Makefile
-# Alexandre Cassen <Alexandre.Cassen@wanadoo.fr>
-
-EXEC= confreader
-CC= gcc
-#CFLAGS= -Wall -Wunused
-CFLAGS=
-DEFS= main.h cfreader.h
-OBJECTS= main.o cfreader.o utils.o
-INCLUDE= -I/usr/src/linux/include
-
-.c.o:
-# $(CC) -o $@ $(CFLAGS) $(INCLUDE) -c $*.c
- $(CC) -o $@ $(INCLUDE) -DDEBUG -c $*.c
-
-all: $(EXEC)
- strip $(EXEC)
- @echo ""
- @echo "Make complete"
-
-$(EXEC): $(OBJECTS) $(DEFS)
- $(CC) -o $(EXEC) $(CFLAGS) $(OBJECTS)
-
-clean:
- rm -f core *.o $(EXEC)
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: Configuration file parser/reader. Place into the dynamic
- * data structure representation the conf file representing
- * the loadbalanced server pool.
- *
- * Version: $Id: cfreader.c,v 0.2.1 2000/12/09 $
- *
- * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
- *
- * Changes:
- * Alexandre Cassen : Initial release
- *
- * 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.
- */
-
-#include "cfreader.h"
-
-int AlreadyExist_VS(virtualserver *lstptr, char ip[16], char port[6])
-{
- virtualserver *pointerptr=lstptr;
-
- while(lstptr != NULL) {
- if((strcmp(lstptr->addr_ip,ip)==0) && (strcmp(lstptr->addr_port,port)==0)) {
- lstptr=pointerptr;
- return 1;
- }
- lstptr=(virtualserver *)lstptr->next;
- }
- lstptr=pointerptr;
- return 0;
-}
-
-int AlreadyExist_SVR(realserver *lstptr, char ip[16], char port[6])
-{
- realserver *pointerptr=lstptr;
-
- while(lstptr != NULL) {
- if((strcmp(lstptr->addr_ip,ip)==0) && (strcmp(lstptr->addr_port,port)==0)) {
- lstptr=pointerptr;
- return 1;
- }
- lstptr=(realserver *)lstptr->next;
- }
- lstptr=pointerptr;
- return 0;
-}
-
-notification_email * AddItem_Email(notification_email *lstemail,notification_email *email)
-{
- notification_email *pointerlst=lstemail;
-
- if (lstemail != NULL) {
- while(lstemail->next != NULL) lstemail=(notification_email *)lstemail->next;
- lstemail->next=(struct notification_email *)email;
- return pointerlst;
- } else {
- lstemail=email;
- return lstemail;
- }
-}
-
-virtualserver * AddItem_VS(virtualserver *lstvs,virtualserver *vs)
-{
- virtualserver *pointerlst=lstvs;
-
- if(AlreadyExist_VS(lstvs,vs->addr_ip,vs->addr_port)) return lstvs;
-
- if (lstvs != NULL) {
- while(lstvs->next != NULL) lstvs=(virtualserver *)lstvs->next;
- lstvs->next=(struct virtualserver *)vs;
- return pointerlst;
- } else {
- lstvs=vs;
- return lstvs;
- }
-}
-
-realserver * AddItem_SVR(realserver *lstsvr,realserver *svr)
-{
- realserver *pointerlst=lstsvr;
-
- if(AlreadyExist_SVR(lstsvr,svr->addr_ip,svr->addr_port)) return lstsvr;
-
- if (lstsvr != NULL) {
- while(lstsvr->next != NULL) lstsvr=(realserver *)lstsvr->next;
- lstsvr->next=(struct realserver *)svr;
- return pointerlst;
- } else {
- lstsvr=svr;
- return lstsvr;
- }
-}
-
-urls * AddItem_Url(urls *lsturls,urls *url)
-{
- urls *pointerlst=lsturls;
-
- if (lsturls != NULL) {
- while(lsturls->next != NULL) lsturls=(urls *)lsturls->next;
- lsturls->next=(struct urls *)url;
- return pointerlst;
- } else {
- lsturls=url;
- return lsturls;
- }
-}
-
-urls * RemoveUrl(urls * lstptr)
-{
- urls *t;
-
- t=(urls *)lstptr->next;
- free(lstptr);
- return t;
-}
-
-realserver * RemoveSVR(realserver * lstptr)
-{
- realserver *t;
-
- t=(realserver *)lstptr->next;
-
- if(lstptr->method->http_get != NULL) {
- while(lstptr->method->http_get->check_urls != NULL)
- lstptr->method->http_get->check_urls=RemoveUrl(lstptr->method->http_get->check_urls);
- free(lstptr->method->http_get);
- }
-
- if(lstptr->method->tcp_vanilla != NULL)
- free(lstptr->method->tcp_vanilla);
-
- free(lstptr->method);
- free(lstptr);
- return t;
-}
-
-virtualserver * RemoveVS(virtualserver * lstptr)
-{
- virtualserver *t;
-
- t=(virtualserver *)lstptr->next;
- while(lstptr->svr != NULL) lstptr->svr=RemoveSVR(lstptr->svr);
- free(lstptr);
- return t;
-}
-
-notification_email * RemoveEmail(notification_email *lstptr)
-{
- notification_email *t;
-
- t=(notification_email *)lstptr->next;
- free(lstptr);
- return t;
-}
-
-void ClearConf(configuration_data * lstptr)
-{
- while(lstptr->email != NULL)
- lstptr->email=RemoveEmail(lstptr->email);
-
- while(lstptr->lvstopology != NULL)
- lstptr->lvstopology=RemoveVS(lstptr->lvstopology);
-}
-
-void PrintConf(configuration_data *lstconf)
-{
- notification_email *pointeremail;
- virtualserver *pointervs;
- realserver *pointersvr;
- urls *pointerurls;
- char *tempbuffer;
-
- tempbuffer=(char *)malloc(TEMPBUFFERLENGTH);
- memset(tempbuffer,0,TEMPBUFFERLENGTH);
-
- if(lstconf == NULL) {
- logmessage("Empty data configuration !!!\n",getpid());
- } else {
- logmessage("------< Global definitions >------\n",getpid());
- memset(tempbuffer,0,TEMPBUFFERLENGTH);
- sprintf(tempbuffer," LVS ID = %s\n",lstconf->lvs_id);
- logmessage(tempbuffer,getpid());
- memset(tempbuffer,0,TEMPBUFFERLENGTH);
- sprintf(tempbuffer," Delay loop = %s, Smtp server = %s\n",
- lstconf->delay_loop,lstconf->smtp_server);
- logmessage(tempbuffer,getpid());
- memset(tempbuffer,0,TEMPBUFFERLENGTH);
- sprintf(tempbuffer," Email notification from = %s\n",lstconf->email_from);
- logmessage(tempbuffer,getpid());
-
- pointeremail=lstconf->email;
- while(lstconf->email != NULL) {
- memset(tempbuffer,0,TEMPBUFFERLENGTH);
- sprintf(tempbuffer," Email notification = %s\n",lstconf->email->addr);
- logmessage(tempbuffer,getpid());
-
- lstconf->email=(notification_email *)lstconf->email->next;
- }
- lstconf->email=pointeremail;
-
- logmessage("------< LVS Topology >------\n",getpid());
- pointervs=lstconf->lvstopology;
- while(lstconf->lvstopology != NULL) {
- memset(tempbuffer,0,TEMPBUFFERLENGTH);
- sprintf(tempbuffer," VS IP = %s, PORT = %s\n",lstconf->lvstopology->addr_ip,
- lstconf->lvstopology->addr_port);
- logmessage(tempbuffer,getpid());
-
- sprintf(tempbuffer," -> lb_algo = %s, lb_kind = %s, persistence = %s, protocol = %s\n",
- lstconf->lvstopology->sched,lstconf->lvstopology->loadbalancing_kind,
- lstconf->lvstopology->timeout_persistence,lstconf->lvstopology->service_type);
- logmessage(tempbuffer,getpid());
-
- pointersvr=lstconf->lvstopology->svr;
- while(lstconf->lvstopology->svr != NULL) {
- sprintf(tempbuffer," -> SVR IP = %s, PORT = %s, WEIGHT = %s\n",
- lstconf->lvstopology->svr->addr_ip,lstconf->lvstopology->svr->addr_port,
- lstconf->lvstopology->svr->weight);
- logmessage(tempbuffer,getpid());
-
- /* Displaying ICMP_CHECK resume */
- if (lstconf->lvstopology->svr->method->flag_type == ICMP_CHECK_ID)
- logmessage(" -> Keepalive method = ICMP_CHECK\n",getpid());
-
- /* Displaying TCP_CHECK resume */
- if (lstconf->lvstopology->svr->method->flag_type == TCP_CHECK_ID) {
- logmessage(" -> Keepalive method = TCP_CHECK\n",getpid());
- sprintf(tempbuffer," -> Connection timeout = %s\n",
- lstconf->lvstopology->svr->method->tcp_vanilla->connection_to);
- logmessage(tempbuffer,getpid());
- }
-
- /* Displaying HTTP_GET resume */
- if (lstconf->lvstopology->svr->method->flag_type == HTTP_GET_ID) {
- pointerurls=lstconf->lvstopology->svr->method->http_get->check_urls;
- logmessage(" -> Keepalive method = HTTP_GET\n",getpid());
- while (lstconf->lvstopology->svr->method->http_get->check_urls != NULL) {
- sprintf(tempbuffer," -> Url = %s, Digest = %s\n",
- lstconf->lvstopology->svr->method->http_get->check_urls->url,
- lstconf->lvstopology->svr->method->http_get->check_urls->digest);
- logmessage(tempbuffer,getpid());
- lstconf->lvstopology->svr->method->http_get->check_urls=(urls *)lstconf->lvstopology->svr->method->http_get->check_urls->next;
- }
- lstconf->lvstopology->svr->method->http_get->check_urls=pointerurls;
-
- sprintf(tempbuffer," -> Connection timeout = %s, Nb get retry = %s\n",
- lstconf->lvstopology->svr->method->http_get->connection_to,
- lstconf->lvstopology->svr->method->http_get->nb_get_retry);
- logmessage(tempbuffer,getpid());
- sprintf(tempbuffer," -> Delay before retry = %s\n",
- lstconf->lvstopology->svr->method->http_get->delay_before_retry);
- logmessage(tempbuffer,getpid());
- }
-
- lstconf->lvstopology->svr=(realserver *)lstconf->lvstopology->svr->next;
- }
- lstconf->lvstopology->svr=pointersvr;
-
- lstconf->lvstopology=(virtualserver *)lstconf->lvstopology->next;
- }
- lstconf->lvstopology=pointervs;
-
- }
- free(tempbuffer);
-}
-
-configuration_data * ConfReader(configuration_data *conf_data)
-{
- FILE *stream;
- char *string="";
- virtualserver *pointervs;
- virtualserver *vsfill;
- realserver *svrfill;
- notification_email *emailfill;
- keepalive_check *methodfill;
- http_get_check *httpgetfill;
- urls *urlsfill;
- tcp_vanilla_check *tcpcheckfill;
-
- stream=fopen(CONFFILE,"r");
- if(stream==NULL) {
- logmessage("ConfReader : Can not read the config file\n",getpid());
- return(NULL);
- }
-
- string=(char *)malloc(TEMPBUFFERLENGTH);
- memset(string,0,TEMPBUFFERLENGTH);
- conf_data=(configuration_data *)malloc(sizeof(configuration_data));
- memset(conf_data,0,sizeof(configuration_data));
-
- /* Initialise the dynamic data structure */
- conf_data->email=NULL;
- conf_data->lvstopology=NULL;
-
- while(!feof(stream)) {
- fscanf(stream,"%s",string);
-
- /* Fill in the global defs structure */
- if(strcmp(string,GLOBALDEFS) == 0)
- do {
- if(strcmp(string,DELAY) == 0)
- fscanf(stream,"%s",conf_data->delay_loop);
- if(strcmp(string,SMTP) == 0)
- fscanf(stream,"%s",conf_data->smtp_server);
- if(strcmp(string,EMAILFROM) == 0)
- fscanf(stream,"%s",conf_data->email_from);
- if(strcmp(string,LVSID) == 0)
- fscanf(stream,"%s",conf_data->lvs_id);
- if(strcmp(string,EMAIL) == 0)
- do {
- fscanf(stream,"%s",string);
- if(strcmp(string,BEGINFLAG)!=0 && strcmp(string,ENDFLAG)!=0) {
- emailfill=(notification_email *)malloc(sizeof(notification_email));
- memset(emailfill,0,sizeof(notification_email));
- strncat(emailfill->addr,string,sizeof(emailfill->addr));
- emailfill->next=NULL;
- conf_data->email = AddItem_Email(conf_data->email,emailfill);
- }
- } while(strcmp(string,ENDFLAG) != 0);
- fscanf(stream,"%s",string);
- } while(strcmp(string,ENDFLAG) != 0);
-
- /* Fill in virtual server structure */
- if(strcmp(string,VS) == 0) {
- vsfill=(virtualserver *)malloc(sizeof(virtualserver));
- vsfill->next=NULL;
- conf_data->lvstopology = AddItem_VS(conf_data->lvstopology,vsfill);
-
- pointervs=conf_data->lvstopology;
- while(conf_data->lvstopology->next != NULL)
- conf_data->lvstopology=(virtualserver *)conf_data->lvstopology->next;
-
- fscanf(stream,"%s",vsfill->addr_ip);
- fscanf(stream,"%s",vsfill->addr_port);
- do {
- if(strcmp(string,LBSCHED) == 0)
- fscanf(stream,"%s",vsfill->sched);
- if(strcmp(string,LBKIND) == 0)
- fscanf(stream,"%s",vsfill->loadbalancing_kind);
- if(strcmp(string,PTIMEOUT) == 0)
- fscanf(stream,"%s",vsfill->timeout_persistence);
- if(strcmp(string,PROTOCOL) == 0)
- fscanf(stream,"%s",vsfill->service_type);
-
- /* Fill in real server structure */
- if(strcmp(string,SVR) == 0) {
- svrfill=(realserver *)malloc(sizeof(realserver));
- memset(svrfill,0,sizeof(realserver));
- fscanf(stream,"%s",svrfill->addr_ip);
- fscanf(stream,"%s",svrfill->addr_port);
- svrfill->alive=1;
- do {
- if(strcmp(string,BEGINFLAG)!=0 && strcmp(string,ENDFLAG)!=0) {
- if(strcmp(string,WEIGHT) == 0)
- fscanf(stream,"%s",svrfill->weight);
-
- if(strcmp(string,ICMPCHECK) == 0) {
- methodfill=(keepalive_check *)malloc(sizeof(keepalive_check));
- memset(methodfill,0,sizeof(keepalive_check));
- methodfill->flag_type=ICMP_CHECK_ID;
- methodfill->http_get=NULL;
- methodfill->tcp_vanilla=NULL;
- }
-
- if(strcmp(string,TCPCHECK) == 0) {
- methodfill=(keepalive_check *)malloc(sizeof(keepalive_check));
- memset(methodfill,0,sizeof(keepalive_check));
- methodfill->flag_type=TCP_CHECK_ID;
- tcpcheckfill=(tcp_vanilla_check *)malloc(sizeof(tcp_vanilla_check));
- memset(tcpcheckfill,0,sizeof(tcp_vanilla_check));
- do {
- fscanf(stream,"%s",string);
- if(strcmp(string,BEGINFLAG)!=0 && strcmp(string,ENDFLAG)!=0) {
- if(strcmp(string,CTIMEOUT) == 0)
- fscanf(stream,"%s",tcpcheckfill->connection_to);
- }
- } while (strcmp(string,ENDFLAG) != 0);
- methodfill->http_get=NULL;
- methodfill->tcp_vanilla=tcpcheckfill;
- }
-
- if(strcmp(string,HTTPGET) == 0) {
- methodfill=(keepalive_check *)malloc(sizeof(keepalive_check));
- memset(methodfill,0,sizeof(keepalive_check));
- methodfill->flag_type=HTTP_GET_ID;
- httpgetfill=(http_get_check *)malloc(sizeof(http_get_check));
- memset(httpgetfill,0,sizeof(http_get_check));
- httpgetfill->check_urls=NULL;
- do {
- if(strcmp(string,BEGINFLAG)!=0 && strcmp(string,ENDFLAG)!=0) {
-
- if(strcmp(string,CTIMEOUT) == 0)
- fscanf(stream,"%s",httpgetfill->connection_to);
- if(strcmp(string,NBGETRETRY) == 0)
- fscanf(stream,"%s",httpgetfill->nb_get_retry);
- if(strcmp(string,DELAYRETRY) == 0)
- fscanf(stream,"%s",httpgetfill->delay_before_retry);
-
- if(strcmp(string,URL) == 0) {
- urlsfill=(urls *)malloc(sizeof(urls));
- memset(urlsfill,0,sizeof(urls));
- urlsfill->next=NULL;
- do {
- fscanf(stream,"%s",string);
- if(strcmp(string,BEGINFLAG)!=0 && strcmp(string,ENDFLAG)!=0) {
-
- if(strcmp(string,URLPATH) == 0)
- fscanf(stream,"%s",urlsfill->url);
- if(strcmp(string,DIGEST) == 0)
- fscanf(stream,"%s",urlsfill->digest);
-
- }
- } while (strcmp(string,ENDFLAG) != 0);
- httpgetfill->check_urls=AddItem_Url(httpgetfill->check_urls,urlsfill);
- }
-
- }
- fscanf(stream,"%s",string);
- } while (strcmp(string,ENDFLAG) != 0);
- methodfill->http_get=httpgetfill;
- methodfill->tcp_vanilla=NULL;
- }
- }
- fscanf(stream,"%s",string);
- } while(strcmp(string,ENDFLAG) != 0);
- svrfill->method=methodfill;
- svrfill->next=NULL;
- conf_data->lvstopology->svr = AddItem_SVR(conf_data->lvstopology->svr,svrfill);
- }
-
- fscanf(stream,"%s",string);
- } while(strcmp(string,ENDFLAG) != 0);
- conf_data->lvstopology=pointervs;
- }
- }
-
- free(string);
- fclose(stream);
-
- return(conf_data);
-}
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: cfreader.c include file.
- *
- * Version: $Id: cfreader.h,v 0.2.1 2000/12/09 $
- *
- * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
- *
- * Changes:
- * Alexandre Cassen : Initial release
- *
- * 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.
- */
-
-#ifndef CFREADER_H
-#define CFREADER_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define CONFFILE "keepalived.conf"
-
-#define TEMPBUFFERLENGTH 100
-
-/* Keywords definition */
-#define GLOBALDEFS "global_defs"
-#define VS "virtual_server"
-#define SVR "real_server"
-#define BEGINFLAG "{"
-#define ENDFLAG "}"
-#define DELAY "delay_loop"
-#define EMAIL "notification_email"
-#define EMAILFROM "notification_email_from"
-#define LVSID "lvs_id"
-#define SMTP "smtp_server"
-#define LBSCHED "lb_algo"
-#define LBKIND "lb_kind"
-#define PTIMEOUT "persistence_timeout"
-#define PROTOCOL "protocol"
-#define WEIGHT "weight"
-#define URL "url"
-#define URLPATH "path"
-#define DIGEST "digest"
-#define CTIMEOUT "connect_timeout"
-#define NBGETRETRY "nb_get_retry"
-#define DELAYRETRY "delay_before_retry"
-
-#define ICMPCHECK "ICMP_CHECK"
-#define TCPCHECK "TCP_CHECK"
-#define HTTPGET "HTTP_GET"
-#define SSLGET "SSL_GET"
-
-/* Check method id */
-#define ICMP_CHECK_ID 0x001
-#define TCP_CHECK_ID 0x002
-#define HTTP_GET_ID 0x003
-#define SSL_GET_ID 0x004
-
-/* Structure definition */
-typedef struct _tcp_vanilla_check {
- char connection_to[4+1];
-} tcp_vanilla_check;
-
-typedef struct _urls {
- char url[100+1];
- char digest[32+1];
-
- struct urls *next;
-} urls;
-
-typedef struct _http_get_check {
- char connection_to[4+1];
- char nb_get_retry[1+1];
- char delay_before_retry[4+1];
- urls *check_urls;
-} http_get_check;
-
-typedef struct _keepalive_check {
- int flag_type;
- http_get_check *http_get;
- tcp_vanilla_check *tcp_vanilla;
-} keepalive_check;
-
-typedef struct _real_server {
- char addr_ip[15+1];
- char addr_port[5+1];
- char weight[3+1];
- keepalive_check *method;
- int alive;
-
- struct realserver *next;
-} realserver;
-
-typedef struct _virtual_server {
- char addr_ip[15+1];
- char addr_port[5+1];
- char sched[5+1];
- char loadbalancing_kind[5+1];
- char timeout_persistence[4];
- char service_type[3+1];
- realserver *svr;
-
- struct virtualserver *next;
-} virtualserver;
-
-typedef struct _notification_email {
- char addr[40+1];
-
- struct notification_email *next;
-} notification_email;
-
-typedef struct _configuration_data {
- char delay_loop[4+1];
- char email_from[40+1];
- char smtp_server[15+1];
- char lvs_id[20+1];
- notification_email *email;
-
- virtualserver *lvstopology;
-} configuration_data;
-
-/* prototypes */
-//configuration_data * ConfReader(configuration_data *conf_data);
-//void ClearConf(configuration_data * lstptr);
-//void PrintConf(configuration_data * lstptr);
-
-#endif
+++ /dev/null
-# Configuration File for keepalived
-
-
-global_defs {
- delay_loop 60
- notification_email {
- acassen@domain.com
- 0633225522@domain.com
- }
- notification_email_from keepalived@domain.com
- smtp_server 192.168.3.62
- lvs_id LVS_MAIN
-}
-
-virtual_server 10.10.10.2 1358 {
- lb_algo rr
- lb_kind NAT
- persistence_timeout 50
- protocol TCP
-
- real_server 192.168.200.2 1358 {
- weight 1
- HTTP_GET {
- url {
- path /testurl/test.jsp
- digest ec90a42b99ea9a2f5ecbe213ac9eba03
- }
- url {
- path /testurl2/test.jsp
- digest 640205b7b0fc66c1ea91c463fac6334c
- }
- connect_timeout 3
- nb_get_retry 3
- delay_before_retry 2
- }
- }
- real_server 192.168.200.3 1358 {
- weight 1
- HTTP_GET {
- url {
- path /testurl/test.jsp
- digest 640205b7b0fc66c1ea91c463fac6334c
- }
- connect_timeout 3
- nb_get_retry 3
- delay_before_retry 2
- }
- }
-}
-
-virtual_server 10.10.10.2 8080 {
- lb_algo rr
- lb_kind NAT
- persistence_timeout 50
- protocol TCP
-
- real_server 192.168.200.4 8080 {
- weight 1
- TCP_CHECK {
- connect_timeout 3
- }
- }
- real_server 192.168.200.5 8080 {
- weight 1
- ICMP_CHECK
- }
- real_server 192.168.200.6 8080 {
- weight 1
- TCP_CHECK {
- connect_timeout 3
- }
- }
-}
-
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: Main program structure.
- *
- * Version: $Id: keepalived.c,v 0.2.3 2001/01/01 $
- *
- * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
- *
- * Changes:
- * Alexandre Cassen : 2001/01/01 :
- * <+> Change the signalhandling.
- *
- * Alexandre Cassen : 2000/12/09 : Initial release
- *
- * 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.
- */
-
-#include "main.h"
-
-int main(int argc, char **argv)
-{
- int delay_loop=60;
- printf(PROG" v"VERSION"\n");
-
- if (chdir(CONF_HOME_DIR)) {
- fprintf(stderr,"%s: ",CONF_HOME_DIR);
- perror(NULL);
- exit(1);
- }
-
- if ((confDATA=(configuration_data *)ConfReader(confDATA)) == NULL) {
- exit(0);
- }
-
- PrintConf(confDATA);
- ClearConf(confDATA);
-
- return 0;
-}
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: General program utils.
- *
- * Version: $Id: utils.c,v 0.2.1 2000/12/09 $
- *
- * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
- *
- * Changes:
- * Alexandre Cassen : Initial release
- *
- * 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.
- */
-
-void print_buffer(int count, char *buff)
-{
- int i,j,c;
- int printnext=1;
-
- if(count) {
- if(count%16)
- c=count+(16-count%16);
- else c=count;
- } else
- c=count;
-
- for(i=0;i<c;i++) {
- if(printnext) {
- printnext--;
- printf("%.4x ",i&0xffff);
- }
- if(i<count)
- printf("%3.2x",buff[i]&0xff);
- else
- printf(" ");
- if(!((i+1)%8)) {
- if((i+1)%16)
- printf(" -");
- else {
- printf(" ");
- for(j=i-15;j<=i;j++)
- if(j<count) {
- if( (buff[j]&0xff) >= 0x20 && (buff[j]&0xff)<=0x7e)
- printf("%c",buff[j]&0xff);
- else printf(".");
- } else printf(" ");
- printf("\n"); printnext=1;
- }
- }
- }
-}
-
-void logmessage(char *msg,int idevent)
-{
- printf("%s",msg);
-}
+++ /dev/null
-ipchains -A forward -j MASQ -p tcp -s 192.168.200.0/24 1358 -d 0.0.0.0/0
-ipchains -A forward -j MASQ -p tcp -s 192.168.200.0/24 8080 -d 0.0.0.0/0
-
-ipvsadm -A -t 10.10.10.2:1358 -s rr -p 50
-ipvsadm -A -t 10.10.10.2:8080 -s rr -p 50
#
# processname: keepalived
# pidfile: /var/run/keepalived.pid
-# config: /etc/lvs.conf
# config: /etc/keepalived/keepalived.conf
case "$1" in
start)
echo -n "Starting Keepalived for LVS: "
- sh /etc/lvs.conf
daemon keepalived
echo
;;
CFLAGS= -Wall
DEFS= genhash.h md5.h
OBJECTS= md5.o genhash.o
+INCLUDE= -I/usr/src/linux/include
.c.o:
- $(CC) -o $@ $(CFLAGS) -c $*.c
+ $(CC) -o $@ $(CFLAGS) $(INCLUDE) -c $*.c
all: $(EXEC)
strip $(EXEC)
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
+ * Alexandre Cassen : 2001/03/27 :
+ * <+> Use non blocking socket.
+ *
* Alexandre Cassen : 2000/12/09 Initial release
*
* This program is free software; you can redistribute it and/or
/* Build version */
#define PROG "genhash"
-#define VERSION "0.2.0 (12/09, 2000), Alexandre Cassen"
+#define VERSION "0.2.3 (27/03, 2001), Alexandre Cassen"
#endif
* url, compute a MD5 over this result and match it to the
* expected value.
*
- * Version: $Id: httpget.c,v 0.2.6 2001/03/01 $
+ * Version: $Id: httpget.c,v 0.2.1 2000/12/09 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
- * Alexandre Cassen : 2001/03/01 :
- * <+> Use a non blocking timeouted tcp connection.
- * <+> Adding support for multi-url. Can perform a HTTP GET
- * over multiple url on the same tcp service (usefull for
- * HTTP server owning multiple applications servers).
- * <+> Adding HTTP GET retry.
- * <+> Remove the libmd call, use the L. Peter Deutsch
- * independant md5 implementation.
- * <+> Parse the whole HTTP get reply, computing a md5sum
- * over the html response part.
- * <+> Adding delay support between HTTP get retry.
- *
- * Alexandre Cassen : Initial release : 2000/12/09
+ * Alexandre Cassen : Initial release
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*
* Part: httpget.c include file.
*
- * Version: $Id: httpget.h,v 0.2.6 2001/03/01 $
+ * Version: $Id: httpget.h,v 0.2.1 2000/12/09 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
- * Alexandre Cassen : 2001/03/01 :
- * <+> Change the GET method.
- *
- * Alexandre Cassen : 2000/12/09 : Initial release
+ * Alexandre Cassen : Initial release
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#define GET_BUFFER_LENGTH 2048
#define LOGBUFFER_LENGTH 100
+/* prototypes */
+//int HTTP_GET(char *IP_DST,char *PORT_DST,char *URL,char *MDResult,int ctimeout,int getretry,int rdelay);
+
#endif
--- /dev/null
+/*
+ * Soft: Keepalived is a failover program for the LVS project
+ * <www.linuxvirtualserver.org>. It monitor & manipulate
+ * a loadbalanced server pool using multi-layer checks.
+ *
+ * Part: IPFW Kernel wrapper. Use Rusty firewall manipulation
+ * library to add/remove server MASQ rules to the kernel
+ * firewall framework.
+ *
+ * Version: $Id: ipfwwrapper.c,v 0.2.7 2001/03/30 $
+ *
+ * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
+ *
+ * Changes:
+ * Alexandre Cassen : Initial release
+ *
+ * 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.
+ */
+
+#include "ipfwwrapper.h"
+
+int ipfw_cmd(int cmd, virtualserver *vserver)
+{
+ struct ip_fwuser ctl;
+ struct in_addr inaddr;
+ int ret = 1;
+ char *debugmsg;
+
+ debugmsg=(char *)malloc(LOGBUFFER_LENGTH);
+ memset(&ctl,0,sizeof(struct ip_fwuser));
+
+ /* Create the firewall MASQ rule */
+ strcpy(ctl.label,IP_FW_LABEL_MASQUERADE);
+ ctl.ipfw.fw_proto = (strcmp(vserver->service_type,"UDP")==0)?IPPROTO_UDP:IPPROTO_TCP;
+ inet_aton(vserver->svr->addr_ip,&ctl.ipfw.fw_src);
+ inet_aton(IPFW_SRC_NETMASK,&ctl.ipfw.fw_smsk);
+ ctl.ipfw.fw_spts[0] = ctl.ipfw.fw_spts[1] = atoi(vserver->svr->addr_port);
+ ctl.ipfw.fw_dpts[0] = 0x0000;
+ ctl.ipfw.fw_dpts[1] = 0xFFFF;
+ ctl.ipfw.fw_tosand = 0xFF;
+ ctl.ipfw.fw_tosxor = 0x00;
+
+ if (cmd&IP_FW_CMD_ADD) {
+ ipfwc_delete_entry(IP_FW_LABEL_FORWARD,&ctl);
+ if (!(errno&EINVAL)) {
+#ifdef DEBUG
+ memset(debugmsg,0,LOGBUFFER_LENGTH);
+ sprintf(debugmsg,"ipfw_cmd : MASQ firewall rule [%s:%s] already exist.\n",
+ vserver->svr->addr_ip,vserver->svr->addr_port);
+ logmessage(debugmsg);
+#endif
+ }
+ ret &= ipfwc_insert_entry(IP_FW_LABEL_FORWARD,&ctl,1);
+ }
+
+ if (cmd&IP_FW_CMD_DEL) {
+ ret &= ipfwc_delete_entry(IP_FW_LABEL_FORWARD,&ctl);
+ if (errno&EINVAL) {
+#ifdef DEBUG
+ memset(debugmsg,0,LOGBUFFER_LENGTH);
+ sprintf(debugmsg,"ipfw_cmd : Can not delete MASQ firewall rule [%s:%s].\n",
+ vserver->svr->addr_ip,vserver->svr->addr_port);
+ logmessage(debugmsg);
+#endif
+ }
+ }
+
+ if(!ret) {
+#ifdef DEBUG
+ memset(debugmsg,0,LOGBUFFER_LENGTH);
+ sprintf(debugmsg,"ipfw_cmd : firewall error (%s) processing [%s:%s] MASQ rule.\n",
+ strerror(errno),vserver->svr->addr_ip,vserver->svr->addr_port);
+ logmessage(debugmsg);
+#endif
+ free(debugmsg);
+ return IPFW_ERROR;
+ }
+
+ free(debugmsg);
+ return IPFW_SUCCESS;
+}
+
* <www.linuxvirtualserver.org>. It monitor & manipulate
* a loadbalanced server pool using multi-layer checks.
*
- * Part: keepalived.c include file.
+ * Part: ipfwwrapper.c include file.
*
- * Version: $Id: keepalived.c,v 0.2.1 2000/12/09 $
+ * Version: $Id: ipfwwrapper.h,v 0.2.7 2001/03/30 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* 2 of the License, or (at your option) any later version.
*/
-#ifndef KEEPALIVED_H
-#define KEEPALIVED_H
+#ifndef IPFWWRAPPER_H
+#define IPFWWRAPPER_H
-#include <stdlib.h>
#include <stdio.h>
-#include <signal.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <netdb.h>
#include <string.h>
-#include <sys/wait.h>
#include <unistd.h>
+#include <errno.h>
#include <ctype.h>
-#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <arpa/inet.h>
+#include "libipfwc/libipfwc.h"
#include "cfreader.h"
+#include "ipfwwrappercmd.h"
-#define LOGBUFFER_LENGTH 100
+#define IPFW_ERROR 0
+#define IPFW_SUCCESS 1
-/* Configuration file home directory */
-#define CONF_HOME_DIR "./"
+#define IPFW_SRC_NETMASK "255.255.255.255"
-/* Global variables */
-configuration_data *confDATA;
-
-/* Build version */
-#define PROG "confreader"
-#define VERSION "0.2.6 (02/20, 2001), Alexandre Cassen"
+#define LOGBUFFER_LENGTH 100
#endif
* <www.linuxvirtualserver.org>. It monitor & manipulate
* a loadbalanced server pool using multi-layer checks.
*
- * Part: keepalived.c include file.
+ * Part: ipfwwrapper.c include file.
*
- * Version: $Id: keepalived.c,v 0.2.1 2000/12/09 $
+ * Version: $Id: ipfwwrappercmd.h,v 0.2.7 2001/03/30 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* 2 of the License, or (at your option) any later version.
*/
-#ifndef KEEPALIVED_H
-#define KEEPALIVED_H
+#ifndef IPFWWRAPPERCMD_H
+#define IPFWWRAPPERCMD_H
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <fcntl.h>
+/* Cmd codes */
+#define IP_FW_CMD_ADD 0x0001
+#define IP_FW_CMD_DEL 0x0002
-#include "smtpwrapper.h"
-
-/* Build version */
-#define PROG "smtpwrapper"
-#define VERSION "0.2.6 (03/01, 2001), Alexandre Cassen"
+/* Return codes */
+#define IPFWNOTDEFINED 0x0003
+#define IPFWSVREXIST 0x0004
+#define IPFWNODEST 0x0005
#endif
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
+
+/* prototypes */
+//int in_cksum(register unsigned short *ptr , int nbytes);
+//int hostToaddr(char *host, u_long *val);
+
+
#endif
* Part: IPVS Kernel wrapper. Use setsockopt call to add/remove
* server to/from the loadbalanced server pool.
*
- * Version: $Id: ipvswrapper.c,v 0.2.1 2001/03/01 $
+ * Version: $Id: ipvswrapper.c,v 0.2.7 2001/03/27 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
- * Alexandre Cassen : 2000/12/09 : Initial release
+ * Alexandre Cassen : 2001/03/27 :
+ * <+> Added setsockopt return value.
+ * <+> Added support to the IP_MASQ_CMD ruleset.
+ * IP_MASQ_CMD_ADD : Adding a virtual service.
+ * IP_MASQ_CMD_DEL : Deleting a virtual service.
+ * IP_MASQ_CMD_ADD_DEST : Adding a real service.
+ * IP_MASQ_CMD_DEL_DEST : Deleting a real service.
+ *
+ * Alexandre Cassen : Initial release
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#include "ipvswrapper.h"
-int ipvs_pool_cmd(int cmd, virtualserver *vserver)
+int ipvs_cmd(int cmd, virtualserver *vserver)
{
struct ip_masq_ctl ctl;
struct in_addr inaddr;
memset(&ctl,0, sizeof(struct ip_masq_ctl));
ctl.m_target = IP_MASQ_TARGET_VS;
- ctl.m_cmd = (cmd)?IP_MASQ_CMD_ADD_DEST:IP_MASQ_CMD_DEL_DEST;
+ ctl.m_cmd = cmd;
strcpy(ctl.m_tname,vserver->sched);
-
- ctl.u.vs_user.weight = atoi(vserver->svr->weight);
+ ctl.u.vs_user.weight = -1;
if (strcmp(vserver->loadbalancing_kind,"NAT")==0)
ctl.u.vs_user.masq_flags = 0;
ctl.u.vs_user.netmask = ((u_int32_t) 0xffffffff); /* f:f:f:f for default netmask */
ctl.u.vs_user.protocol = (strcmp(vserver->service_type,"UDP")==0)?IPPROTO_UDP:IPPROTO_TCP;
- ctl.u.vs_user.timeout = (atoi(vserver->timeout_persistence)==0)?0:atoi(vserver->timeout_persistence);
- ctl.u.vs_user.vfwmark = 0;
+ if(!parse_timeout(vserver->timeout_persistence,&ctl.u.vs_user.timeout)) {
+#ifdef DEBUG
+ memset(debugmsg,0,LOGBUFFER_LENGTH);
+ sprintf(debugmsg,"ipvs_pool_cmd : Virtual service [%s:%s] illegal timeout.\n",
+ vserver->addr_ip, vserver->addr_port);
+ logmessage(debugmsg);
+#endif
+ }
ctl.u.vs_user.vs_flags = (ctl.u.vs_user.timeout!=0)?IP_VS_SVC_F_PERSISTENT:0;
+
+ ctl.u.vs_user.vfwmark = 0;
+ /* VS specific */
if (inet_aton(vserver->addr_ip,&inaddr) != 0)
ctl.u.vs_user.vaddr = inaddr.s_addr;
- if (inet_aton(vserver->svr->addr_ip,&inaddr) != 0)
- ctl.u.vs_user.daddr = inaddr.s_addr;
ctl.u.vs_user.vport = htons(atoi(vserver->addr_port));
- ctl.u.vs_user.dport = htons(atoi(vserver->svr->addr_port));
+
+ /* SVR specific */
+ if (ctl.m_cmd == IP_MASQ_CMD_ADD_DEST || ctl.m_cmd == IP_MASQ_CMD_DEL_DEST) {
+ ctl.u.vs_user.weight = atoi(vserver->svr->weight);
+ if (inet_aton(vserver->svr->addr_ip,&inaddr) != 0)
+ ctl.u.vs_user.daddr = inaddr.s_addr;
+ ctl.u.vs_user.dport = htons(atoi(vserver->svr->addr_port));
+ }
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sockfd == -1) {
#ifdef DEBUG
- logmessage("ipvs__pool_cmd : Can not initialize SOCK_RAW descriptor\n");
+ logmessage("ipvs_pool_cmd : Can not initialize SOCK_RAW descriptor\n");
#endif
free(debugmsg);
return IPVS_ERROR;
#endif
close(sockfd);
free(debugmsg);
- return IPVS_ERROR;
+ return IPVSNOTDEFINED;
+ } else if (errno == EEXIST) {
+#ifdef DEBUG
+ memset(debugmsg,0,LOGBUFFER_LENGTH);
+ sprintf(debugmsg,"ipvs_pool_cmd : Destination already exists [%s:%s]\n",vserver->svr->addr_ip,vserver->svr->addr_port);
+ logmessage(debugmsg);
+#endif
+ close(sockfd);
+ free(debugmsg);
+ return IPVSSVREXIST;
} else if (errno == ENOENT) {
#ifdef DEBUG
memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"ipvs_pool_cmd : No such destination %s\n",vserver->svr->addr_ip);
+ sprintf(debugmsg,"ipvs_pool_cmd : No such destination [%s:%s]\n",vserver->svr->addr_ip,vserver->svr->addr_port);
logmessage(debugmsg);
#endif
close(sockfd);
free(debugmsg);
- return IPVS_ERROR;
+ return IPVSNODEST;
}
close(sockfd);
free(debugmsg);
return IPVS_SUCCESS;
}
+
+/*
+ * Source code from the ipvsadm.c Wensong code
+ */
+
+int parse_timeout(char *buf, unsigned *timeout)
+{
+ int i;
+
+ if (buf == NULL) {
+ *timeout = IP_VS_TEMPLATE_TIMEOUT;
+ return 1;
+ }
+
+ if ((i=string_to_number(buf, 1, 86400*31)) == -1)
+ return 0;
+
+ *timeout = i * HZ;
+ return 1;
+}
+
+int string_to_number(const char *s, int min, int max)
+{
+ int number;
+ char *end;
+
+ number = (int)strtol(s, &end, 10);
+ if (*end == '\0' && end != s) {
+ /*
+ * We parsed a number, let's see if we want this.
+ * If max <= min then ignore ranges
+ */
+ if (max <= min || ( min <= number && number <= max))
+ return number;
+ else
+ return -1;
+ } else
+ return -1;
+}
+
#define IPVS_ERROR 0
#define IPVS_SUCCESS 1
-#define IPVS_CMD_DEL 0
-#define IPVS_CMD_ADD 1
+/* Return codes */
+#define IPVSNOTDEFINED 0x0003
+#define IPVSSVREXIST 0x0004
+#define IPVSNODEST 0x0005
#define LOGBUFFER_LENGTH 100
*
* Changes:
* Alexandre Cassen : 2001/03/01 :
- * <+> Adding support for multi-url md5sum check.
- * <+> Adding pidfile lock.
* <+> Change the signalhandling.
* <+> Change the dynamic data structure.
- * <+> Use a global var to stock the daemon pid.
*
* Alexandre Cassen : 2000/12/09 : Initial release
*
perform_checks(lstCONF);
sleep(atoi(lstCONF->delay_loop));
}
+
+ pidfile_rm();
+ return 0;
}
-static void sig_handler(int signum)
+void sig_handler(int signum)
{
keep_going=0;
ClearConf(lstCONF);
logmessage("Ending keepalived daemon\n");
- pidfile_rm();
- exit(1);
}
void perform_ipvs(int alive, virtualserver *lstptr)
lstptr->svr->addr_ip,lstptr->svr->addr_port,
lstptr->addr_ip,lstptr->addr_port);
logmessage(logbuffer);
- ipvs_pool_cmd(IPVS_CMD_ADD,lstptr);
+ ipvs_cmd(IP_MASQ_CMD_ADD_DEST,lstptr);
+ ipfw_cmd(IP_FW_CMD_ADD,lstptr);
} else {
lstptr->svr->alive=alive;
memset(logbuffer,0,LOGBUFFER_LENGTH);
lstptr->svr->addr_ip,lstptr->svr->addr_port,
lstptr->addr_ip,lstptr->addr_port);
logmessage(logbuffer);
- ipvs_pool_cmd(IPVS_CMD_DEL,lstptr);
+ ipvs_cmd(IP_MASQ_CMD_DEL_DEST,lstptr);
+ ipfw_cmd(IP_FW_CMD_DEL,lstptr);
}
free(logbuffer);
}
realserver *pointersvr;
while(lstptr != NULL) {
+ if (!ipvs_cmd(IP_MASQ_CMD_ADD,lstptr))
+ return 0;
pointersvr=lstptr->svr;
while(lstptr->svr != NULL) {
- if (!ipvs_pool_cmd(IPVS_CMD_ADD,lstptr))
+ if (!ipvs_cmd(IP_MASQ_CMD_ADD_DEST,lstptr)) {
+ lstptr->svr=pointersvr;
return 0;
+ }
+ if(!ipfw_cmd(IP_FW_CMD_ADD,lstptr)) {
+ lstptr->svr=pointersvr;
+ return 0;
+ }
lstptr->svr=(realserver *)lstptr->svr->next;
}
lstptr->svr=pointersvr;
#include "httpget.h"
#include "utils.h"
#include "ipvswrapper.h"
+#include "ipfwwrappercmd.h"
#define LOGBUFFER_LENGTH 100
/* Build version */
#define PROG "keepalived"
-#define VERSION "0.2.6 (03/01, 2001), Alexandre Cassen"
+#define VERSION "0.2.7 (03/30, 2001), Alexandre Cassen"
/* prototypes */
-static void sig_handler(int signum);
+void sig_handler(int signum);
void perform_checks(configuration_data * lstconf);
int init_services(virtualserver *lstptr);
--- /dev/null
+# Makefile to make libipfwc.
+
+CC = gcc
+COPTS = -g -O
+CFLAGS = -Wall -Wunused $(COPTS)
+
+libipfwc.a: libipfwc.a(libipfwc.o)
+
+libipfwc.o: libipfwc.h ipfwc_kernel_headers.h
+
+clean:
+ rm -f *.a *.o *~
--- /dev/null
+/* This is the userspace/kernel interface for Generic IP Chains,
+ required for libc6. */
+#ifndef _FWCHAINS_KERNEL_HEADERS_H
+#define _FWCHAINS_KERNEL_HEADERS_H
+
+#if defined(__GLIBC__) && __GLIBC__ == 2
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <net/if.h>
+#include <sys/types.h>
+
+typedef u_int64_t __u64;
+typedef u_int32_t __u32;
+typedef int32_t __s32;
+typedef u_int16_t __u16;
+typedef u_int8_t __u8;
+
+#else /* libc5 */
+#include <sys/socket.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/icmp.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#endif
+
+#define IP_FW_MAX_LABEL_LENGTH 8
+typedef char ip_chainlabel[IP_FW_MAX_LABEL_LENGTH+1];
+
+struct ip_fw
+{
+ struct in_addr fw_src, fw_dst; /* Source and destination IP addr */
+ struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */
+ __u32 fw_mark; /* ID to stamp on packet */
+ __u16 fw_proto; /* Protocol, 0 = ANY */
+ __u16 fw_flg; /* Flags word */
+ __u16 fw_invflg; /* Inverse flags */
+ __u16 fw_spts[2]; /* Source port range. */
+ __u16 fw_dpts[2]; /* Destination port range. */
+ __u16 fw_redirpt; /* Port to redirect to. */
+ __u16 fw_outputsize; /* Max amount to output to
+ NETLINK */
+ char fw_vianame[IFNAMSIZ]; /* name of interface "via" */
+ __u8 fw_tosand, fw_tosxor; /* Revised packet priority */
+};
+
+struct ip_fwuser
+{
+ struct ip_fw ipfw;
+ ip_chainlabel label;
+};
+
+/* Values for "fw_flg" field . */
+#define IP_FW_F_PRN 0x0001 /* Print packet if it matches */
+#define IP_FW_F_TCPSYN 0x0002 /* For tcp packets-check SYN only */
+#define IP_FW_F_FRAG 0x0004 /* Set if rule is a fragment rule */
+#define IP_FW_F_MARKABS 0x0008 /* Set the mark to fw_mark, not add. */
+#define IP_FW_F_WILDIF 0x0010 /* Need only match start of interface name. */
+#define IP_FW_F_NETLINK 0x0020 /* Redirect to netlink: 2.1.x only */
+#define IP_FW_F_MASK 0x003F /* All possible flag bits mask */
+
+/* Values for "fw_invflg" field. */
+#define IP_FW_INV_SRCIP 0x0001 /* Invert the sense of fw_src. */
+#define IP_FW_INV_DSTIP 0x0002 /* Invert the sense of fw_dst. */
+#define IP_FW_INV_PROTO 0x0004 /* Invert the sense of fw_proto. */
+#define IP_FW_INV_SRCPT 0x0008 /* Invert the sense of source ports. */
+#define IP_FW_INV_DSTPT 0x0010 /* Invert the sense of destination ports. */
+#define IP_FW_INV_VIA 0x0020 /* Invert the sense of fw_vianame. */
+#define IP_FW_INV_SYN 0x0040 /* Invert the sense of IP_FW_F_TCPSYN. */
+#define IP_FW_INV_FRAG 0x0080 /* Invert the sense of IP_FW_F_FRAG. */
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use
+ * a raw socket for this. Instead we check rights in the calls. */
+
+#define IP_FW_BASE_CTL 64 /* base for firewall socket options */
+
+#define IP_FW_APPEND (IP_FW_BASE_CTL) /* Takes ip_fwchange */
+#define IP_FW_REPLACE (IP_FW_BASE_CTL+1) /* Takes ip_fwnew */
+#define IP_FW_DELETE_NUM (IP_FW_BASE_CTL+2) /* Takes ip_fwdelnum */
+#define IP_FW_DELETE (IP_FW_BASE_CTL+3) /* Takes ip_fwchange */
+#define IP_FW_INSERT (IP_FW_BASE_CTL+4) /* Takes ip_fwnew */
+#define IP_FW_FLUSH (IP_FW_BASE_CTL+5) /* Takes ip_chainlabel */
+#define IP_FW_ZERO (IP_FW_BASE_CTL+6) /* Takes ip_chainlabel */
+#define IP_FW_CHECK (IP_FW_BASE_CTL+7) /* Takes ip_fwtest */
+#define IP_FW_MASQ_TIMEOUTS (IP_FW_BASE_CTL+8) /* Takes 3 ints */
+#define IP_FW_CREATECHAIN (IP_FW_BASE_CTL+9) /* Takes ip_chainlabel */
+#define IP_FW_DELETECHAIN (IP_FW_BASE_CTL+10) /* Takes ip_chainlabel */
+#define IP_FW_POLICY (IP_FW_BASE_CTL+11) /* Takes ip_fwpolicy */
+/* Masquerade controls */
+#define IP_FW_MASQ_INSERT (IP_FW_BASE_CTL+12)
+#define IP_FW_MASQ_ADD (IP_FW_BASE_CTL+13)
+#define IP_FW_MASQ_DEL (IP_FW_BASE_CTL+14)
+#define IP_FW_MASQ_FLUSH (IP_FW_BASE_CTL+15)
+
+/* Builtin chain labels */
+#define IP_FW_LABEL_FORWARD "forward"
+#define IP_FW_LABEL_INPUT "input"
+#define IP_FW_LABEL_OUTPUT "output"
+
+/* Special targets */
+#define IP_FW_LABEL_MASQUERADE "MASQ"
+#define IP_FW_LABEL_REDIRECT "REDIRECT"
+#define IP_FW_LABEL_ACCEPT "ACCEPT"
+#define IP_FW_LABEL_BLOCK "DENY"
+#define IP_FW_LABEL_REJECT "REJECT"
+#define IP_FW_LABEL_RETURN "RETURN"
+
+/* Files in /proc/net */
+#define IP_FW_PROC_CHAINS "ip_fwchains"
+#define IP_FW_PROC_CHAIN_NAMES "ip_fwnames"
+
+struct ip_fwpkt
+{
+ struct iphdr fwp_iph; /* IP header */
+ union {
+ struct tcphdr fwp_tcph; /* TCP header or */
+ struct udphdr fwp_udph; /* UDP header */
+ struct icmphdr fwp_icmph; /* ICMP header */
+ } fwp_protoh;
+ struct in_addr fwp_via; /* interface address */
+ char fwp_vianame[IFNAMSIZ]; /* interface name */
+};
+
+/* The argument to IP_FW_DELETE and IP_FW_APPEND */
+struct ip_fwchange
+{
+ struct ip_fwuser fwc_rule;
+ ip_chainlabel fwc_label;
+};
+
+/* The argument to IP_FW_CHECK. */
+struct ip_fwtest
+{
+ struct ip_fwpkt fwt_packet; /* Packet to be tested */
+ ip_chainlabel fwt_label; /* Block to start test in */
+};
+
+/* The argument to IP_FW_DELETE_NUM */
+struct ip_fwdelnum
+{
+ __u32 fwd_rulenum;
+ ip_chainlabel fwd_label;
+};
+
+/* The argument to IP_FW_REPLACE and IP_FW_INSERT */
+struct ip_fwnew
+{
+ __u32 fwn_rulenum;
+ struct ip_fwuser fwn_rule;
+ ip_chainlabel fwn_label;
+};
+
+/* The argument to IP_FW_POLICY */
+struct ip_fwpolicy
+{
+ ip_chainlabel fwp_policy;
+ ip_chainlabel fwp_label;
+};
+/*
+ * timeouts for ip masquerading
+ */
+
+struct ip_fw_masq;
+
+/* Masquerading stuff */
+#define IP_FW_MASQCTL_MAX 256
+#define IP_MASQ_MOD_NMAX 32
+
+struct ip_fw_masqctl
+{
+ int mctl_action;
+ union {
+ struct {
+ char name[IP_MASQ_MOD_NMAX];
+ char data[1];
+ } mod;
+ } u;
+};
+#endif
--- /dev/null
+/* Library which manipulates firewall rules. Version 0.2. */
+
+/* (C)1998 Paul ``Rusty'' Russell - Placed under the GNU GPL (See
+ COPYING for details). */
+
+/* 0.2: Accounting rules now return target label of "" not "-", so they
+ * can be fed right back in, as expected. */
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libipfwc.h"
+
+#define IP_VERSION 4
+#define IP_OFFSET 0x1FFF
+
+static int sockfd = -1;
+static void *ipfwc_fn = NULL;
+
+static int init = 0;
+
+/* Some people try -j REDIRECT or -j MASQ, without kernel support; a
+ little hacky, but record it out here in case we get an error. --RR */
+static enum {
+ IPFWC_NORMAL,
+ IPFWC_MASQ,
+ IPFWC_REDIRECT
+} ipfwc_type;
+
+static void ipfwc_settype(const struct ip_fwuser *fw)
+{
+ if (strcmp(fw->label, "MASQ") == 0)
+ ipfwc_type = IPFWC_MASQ;
+ else if (strcmp(fw->label, "REDIRECT") == 0)
+ ipfwc_type = IPFWC_REDIRECT;
+ else ipfwc_type = IPFWC_NORMAL;
+}
+
+static int ipfwc_init()
+{
+ ipfwc_fn = ipfwc_init;
+ init = 1;
+ return ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1);
+}
+
+static int
+do_setsockopt(int cmd, const void *data, int length)
+{
+ return setsockopt(sockfd, IPPROTO_IP, cmd, (char *)data, length) != -1;
+}
+
+/* Insert the entry `fw' in chain `chain' into position `rulenum'. */
+int ipfwc_insert_entry(const ip_chainlabel chain,
+ const struct ip_fwuser *fw,
+ unsigned int rulenum)
+{
+ struct ip_fwnew new = { rulenum, *fw, "" };
+ memcpy(new.fwn_label, chain, sizeof(new.fwn_label));
+
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_insert_entry;
+ ipfwc_settype(fw);
+ return do_setsockopt(IP_FW_INSERT, &new, sizeof(new));
+}
+
+/* Atomically replace rule `rulenum' in `chain' with `fw'. */
+int ipfwc_replace_entry(const ip_chainlabel chain,
+ const struct ip_fwuser *fw,
+ unsigned int rulenum)
+{
+ struct ip_fwnew new = { rulenum, *fw, "" };
+ memcpy(new.fwn_label, chain, sizeof(new.fwn_label));
+
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_replace_entry;
+ ipfwc_settype(fw);
+ return do_setsockopt(IP_FW_REPLACE, &new, sizeof(new));
+}
+
+/* Append entry `fw' to chain `chain'. Equivalent to insert with
+ rulenum = length of chain. */
+int ipfwc_append_entry(const ip_chainlabel chain, const struct ip_fwuser *fw)
+{
+ struct ip_fwchange new = { *fw, "" };
+ memcpy(new.fwc_label, chain, sizeof(new.fwc_label));
+
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_append_entry;
+ ipfwc_settype(fw);
+ return do_setsockopt(IP_FW_APPEND, &new, sizeof(new));
+}
+
+/* Delete the first rule in `chain' which matches `fw'. */
+int ipfwc_delete_entry(const ip_chainlabel chain, const struct ip_fwuser *fw)
+{
+ struct ip_fwchange del = { *fw, "" };
+ memcpy(del.fwc_label, chain, sizeof(del.fwc_label));
+
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_delete_entry;
+ return do_setsockopt(IP_FW_DELETE, &del, sizeof(del));
+}
+
+/* Delete the rule in position `rulenum' in `chain'. */
+int ipfwc_delete_num_entry(const ip_chainlabel chain, unsigned int rulenum)
+{
+ struct ip_fwdelnum del = { rulenum, "" };
+ memcpy(del.fwd_label, chain, sizeof(del.fwd_label));
+
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_delete_num_entry;
+ return do_setsockopt(IP_FW_DELETE_NUM, &del, sizeof(del));
+}
+
+static struct ip_fwtest *
+fw_to_fwtest(const struct ip_fw *fw, const ip_chainlabel chain)
+{
+ static struct ip_fwtest ipfwt;
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+ struct udphdr *udph;
+ struct icmphdr *icmph;
+
+ strcpy(ipfwt.fwt_label, chain);
+
+ iph = &ipfwt.fwt_packet.fwp_iph;
+
+ iph->version = IP_VERSION;
+ iph->ihl = sizeof(struct iphdr) / 4;
+ iph->tot_len = sizeof(struct ip_fwpkt);
+ iph->frag_off &= htons(~IP_OFFSET);
+ iph->protocol = fw->fw_proto;
+
+ iph->saddr = fw->fw_src.s_addr;
+ iph->daddr = fw->fw_dst.s_addr;
+
+ strncpy(ipfwt.fwt_packet.fwp_vianame, fw->fw_vianame, IFNAMSIZ);
+
+ if (fw->fw_flg & IP_FW_F_FRAG)
+ iph->frag_off |= htons(2); /* = 64 bytes - why not? */
+
+ /* The tcp and udp headers are ignored for fragments, anyway */
+ switch (iph->protocol) {
+ case IPPROTO_TCP:
+ tcph = &ipfwt.fwt_packet.fwp_protoh.fwp_tcph;
+ tcph->source = htons(fw->fw_spts[0]);
+ tcph->dest = htons(fw->fw_dpts[0]);
+ tcph->syn = (fw->fw_flg & IP_FW_F_TCPSYN) ? 1 : 0;
+ break;
+ case IPPROTO_UDP:
+ udph = &ipfwt.fwt_packet.fwp_protoh.fwp_udph;
+ udph->source = htons(fw->fw_spts[0]);
+ udph->dest = htons(fw->fw_dpts[0]);
+ break;
+ case IPPROTO_ICMP:
+ icmph = &ipfwt.fwt_packet.fwp_protoh.fwp_icmph;
+ icmph->type = fw->fw_spts[0];
+ icmph->code = fw->fw_dpts[0];
+ break;
+ }
+
+ return &ipfwt;
+}
+
+/* Check the packet `fw' on chain `chain'. Returns the verdict, or
+ NULL and sets errno. */
+const char *ipfwc_check_packet(const ip_chainlabel chain,
+ struct ip_fw *fw)
+{
+ int old_errno = errno;
+
+ if (!init && !ipfwc_init()) return NULL;
+
+ ipfwc_fn = ipfwc_check_packet;
+ if (do_setsockopt(IP_FW_CHECK, fw_to_fwtest(fw, chain),
+ sizeof(struct ip_fwtest)))
+ return "accepted";
+ else switch (errno) {
+ case ECONNRESET:
+ errno = old_errno;
+ return "masqueraded";
+ case ETIMEDOUT:
+ errno = old_errno;
+ return "denied";
+ case ECONNREFUSED:
+ errno = old_errno;
+ return "rejected";
+ case ECONNABORTED:
+ errno = old_errno;
+ return "redirected";
+ case ELOOP:
+ errno = old_errno;
+ return "caught in loop";
+ case ENFILE:
+ errno = old_errno;
+ return "passed through chain";
+
+ default:
+ return NULL;
+ }
+}
+
+/* Flushes the entries in the given chain (ie. empties chain). */
+int ipfwc_flush_entries(const ip_chainlabel chain)
+{
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_flush_entries;
+ return do_setsockopt(IP_FW_FLUSH, chain, sizeof(ip_chainlabel));
+}
+
+/* Zeroes the counters in a chain. */
+int ipfwc_zero_entries(const ip_chainlabel chain)
+{
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_zero_entries;
+ return do_setsockopt(IP_FW_ZERO, chain, sizeof(ip_chainlabel));
+}
+
+/* Creates a new chain. */
+int ipfwc_create_chain(const ip_chainlabel chain)
+{
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_create_chain;
+ return do_setsockopt(IP_FW_CREATECHAIN, chain, sizeof(ip_chainlabel));
+}
+
+/* Deletes a chain. */
+int ipfwc_delete_chain(const ip_chainlabel chain)
+{
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_delete_chain;
+ return do_setsockopt(IP_FW_DELETECHAIN, chain, sizeof(ip_chainlabel));
+}
+
+/* Sets the policy on a built-in chain. */
+int ipfwc_set_policy(const ip_chainlabel chain, const ip_chainlabel policy)
+{
+ struct ip_fwpolicy fwp;
+
+ if (!init && !ipfwc_init()) return 0;
+
+ ipfwc_fn = ipfwc_set_policy;
+ memcpy(fwp.fwp_policy, policy, sizeof(fwp.fwp_policy));
+ memcpy(fwp.fwp_label, chain, sizeof(fwp.fwp_label));
+ return do_setsockopt(IP_FW_POLICY, &fwp, sizeof(fwp));
+}
+
+/* Gets the names of all the chains. Returns single malloc()d region;
+ and array of ip_chainlabels. Fills in num_chains. Returns NULL on
+ error. */
+struct ipfwc_fwchain *ipfwc_get_chainnames(unsigned int *num_chains)
+{
+ int nread;
+ static unsigned int maxnum = 4;
+ static struct ipfwc_fwchain *chains = NULL;
+ FILE *fp;
+ __u32 pkthi, pktlo, bytehi, bytelo;
+
+ ipfwc_fn = ipfwc_get_chainnames;
+ if (!chains) {
+ chains = malloc(sizeof(struct ipfwc_fwchain) * maxnum);
+
+ if (!chains) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+
+ /* Read names from IP_FW_PROC_CHAIN_NAMES */
+ fp = fopen("/proc/net/"IP_FW_PROC_CHAIN_NAMES, "r");
+ if (!fp) {
+ /* Bad kernel version? */
+ if (errno == ENOENT) errno = 0;
+ return NULL;
+ }
+
+ *num_chains = 0;
+ while ((nread = fscanf(fp,"%s %s %u %u %u %u %u",
+ chains[*num_chains].label,
+ chains[*num_chains].policy,
+ &chains[*num_chains].refcnt,
+ &pkthi, &pktlo, &bytehi, &bytelo)) == 7) {
+ chains[*num_chains].packets = ((__u64)pkthi)<<32 | pktlo;
+ chains[*num_chains].bytes = ((__u64)bytehi)<<32 | bytelo;
+ (*num_chains)++;
+ if (*num_chains >= maxnum) {
+ maxnum *= 2;
+ chains = realloc(chains,
+ sizeof(struct ipfwc_fwchain)*maxnum);
+ if (!chains) {
+ fclose(fp);
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+ }
+
+ /* Bad kernel version? */
+ if (nread != -1) {
+ fclose(fp);
+ errno = 0;
+ return NULL;
+ }
+
+ return chains;
+}
+
+static const struct ipfwc_fwchain *
+find_chain(const ip_chainlabel label,
+ const struct ipfwc_fwchain *chains,
+ unsigned int num_chains)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_chains; i++) {
+ if (strcmp(label, chains[i].label) == 0)
+ return chains+i;
+ }
+ return NULL;
+}
+
+#define _IPFWC_FMT2(i) "%" #i "s "
+#define _IPFWC_FMT(i) _IPFWC_FMT2(i)
+#define IPFWC_CHAIN_FMT _IPFWC_FMT(IP_FW_MAX_LABEL_LENGTH)
+
+/* Take a snapshot of the rules. Returns internal pointer to array of
+ ipfwc_fwrules. Fills in num_rules. Returns NULL on error. */
+struct ipfwc_fwrule *ipfwc_get_rules(unsigned int *num_rules, int zero)
+{
+ FILE *fp;
+ __u32 pkthi, pktlo, bytehi, bytelo;
+ unsigned int num_chains;
+ struct ipfwc_fwchain *chains = ipfwc_get_chainnames(&num_chains);
+ static unsigned int maxnum = 4;
+ static struct ipfwc_fwrule *rules = NULL;
+ ip_chainlabel label;
+ int nread;
+ unsigned short tosand, tosxor;
+
+ ipfwc_fn = ipfwc_get_rules;
+ if (!rules) {
+ rules = malloc(sizeof(struct ipfwc_fwrule) * maxnum);
+ if (!rules) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+
+ fp = fopen("/proc/net/"IP_FW_PROC_CHAINS, zero ? "r+" : "r");
+ if (!fp) {
+ if (errno == ENOENT) errno = 0;
+ return NULL;
+ }
+
+ *num_rules = 0;
+ while ((nread = fscanf(fp,
+ IPFWC_CHAIN_FMT /* Chain name */
+ "%X/%X->%X/%X " /* IPs */
+ "%s " /* Interface */
+ "%hX %hX " /* flg & invflg */
+ "%hu " /* Protocol */
+ "%u %u %u %u " /* Counters */
+ "%hu-%hu %hu-%hu " /* Ports */
+ "A%hX X%hX " /* TOS masks */
+ "%hX " /* fw_redir */
+ "%u " /* fw_mark */
+ "%hu " /* output size */
+ "%s", /* Target */
+ label,
+ &rules[*num_rules].ipfw.ipfw.fw_src.s_addr,
+ &rules[*num_rules].ipfw.ipfw.fw_smsk.s_addr,
+ &rules[*num_rules].ipfw.ipfw.fw_dst.s_addr,
+ &rules[*num_rules].ipfw.ipfw.fw_dmsk.s_addr,
+ rules[*num_rules].ipfw.ipfw.fw_vianame,
+ &rules[*num_rules].ipfw.ipfw.fw_flg,
+ &rules[*num_rules].ipfw.ipfw.fw_invflg,
+ &rules[*num_rules].ipfw.ipfw.fw_proto,
+ &pkthi, &pktlo, &bytehi, &bytelo,
+ &rules[*num_rules].ipfw.ipfw.fw_spts[0],
+ &rules[*num_rules].ipfw.ipfw.fw_spts[1],
+ &rules[*num_rules].ipfw.ipfw.fw_dpts[0],
+ &rules[*num_rules].ipfw.ipfw.fw_dpts[1],
+ &tosand, &tosxor,
+ &rules[*num_rules].ipfw.ipfw.fw_redirpt,
+ &rules[*num_rules].ipfw.ipfw.fw_mark,
+ &rules[*num_rules].ipfw.ipfw.fw_outputsize,
+ rules[*num_rules].ipfw.label)) == 23) {
+ if (strcmp("-", rules[*num_rules].ipfw.label) == 0)
+ (rules[*num_rules].ipfw.label)[0] = '\0';
+ if (strcmp("-", rules[*num_rules].ipfw.ipfw.fw_vianame) == 0)
+ (rules[*num_rules].ipfw.ipfw.fw_vianame)[0] = '\0';
+ rules[*num_rules].ipfw.ipfw.fw_tosand = (unsigned char)tosand;
+ rules[*num_rules].ipfw.ipfw.fw_tosxor = (unsigned char)tosxor;
+
+ /* we always keep these addresses in network byte order */
+ rules[*num_rules].ipfw.ipfw.fw_src.s_addr
+ = htonl(rules[*num_rules].ipfw.ipfw.fw_src.s_addr);
+ rules[*num_rules].ipfw.ipfw.fw_smsk.s_addr
+ = htonl(rules[*num_rules].ipfw.ipfw.fw_smsk.s_addr);
+ rules[*num_rules].ipfw.ipfw.fw_dst.s_addr
+ = htonl(rules[*num_rules].ipfw.ipfw.fw_dst.s_addr);
+ rules[*num_rules].ipfw.ipfw.fw_dmsk.s_addr
+ = htonl(rules[*num_rules].ipfw.ipfw.fw_dmsk.s_addr);
+
+ rules[*num_rules].packets = ((__u64)pkthi)<<32 | pktlo;
+ rules[*num_rules].bytes = ((__u64)bytehi)<<32 | bytelo;
+
+ rules[*num_rules].chain
+ = find_chain(label, chains, num_chains);
+
+ (*num_rules)++;
+ if (*num_rules >= maxnum) {
+ maxnum *= 2;
+ rules = realloc(rules,
+ sizeof(struct ipfwc_fwrule)*maxnum);
+ if (!rules) {
+ fclose(fp);
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+ }
+
+ /* Bad kernel version? */
+ if (nread != -1) {
+ fclose(fp);
+ errno = 0;
+ return NULL;
+ }
+
+ return rules;
+}
+
+/* Get raw socket. */
+int ipfwc_get_raw_socket()
+{
+ return sockfd;
+}
+
+/* Translates errno numbers into more human-readable form than strerror.
+ * `ipfwc_fn' is a pointer to the function which returned the error. */
+const char *ipfwc_strerror(int err)
+{
+ unsigned int i;
+ static char message[200];
+ struct table_struct {
+ void *fn;
+ int err;
+ const char *message;
+ int support_warning;
+ } table [] =
+ { { ipfwc_insert_entry, ENOENT, "No target by that name", 1 },
+ { ipfwc_replace_entry, ENOENT, "No target by that name", 1 },
+ { ipfwc_append_entry, ENOENT, "No target by that name", 1 },
+ { NULL, ENOENT, "No chain by that name", 0 },
+ { NULL, 0, "Incompatible with this kernel", 0 },
+ { ipfwc_init, EPERM, "Permission denied (you must be root)", 0 },
+ { ipfwc_delete_chain, ENOTEMPTY, "Chain is not empty", 0 },
+ { ipfwc_create_chain, EEXIST, "Chain already exists", 0 },
+ /* EINVAL for CHECK probably means bad interface. */
+ { ipfwc_check_packet, EINVAL,
+ "bad arguments (does that interface exist?)", 0 },
+ /* EINVAL for DELETE probably means no matching rule */
+ { ipfwc_delete_entry, EINVAL,
+ "bad rule (does a matching rule exist in that chain?)", 0 },
+ { ipfwc_insert_entry, EINVAL,
+ "bad rule (does a matching rule exist in that chain?)", 0 },
+ { ipfwc_delete_num_entry, EINVAL,
+ "bad rule (does a matching rule exist in that chain?)", 0 },
+ { ipfwc_replace_entry, EINVAL,
+ "bad rule (does a matching rule exist in that chain?)", 0 }
+ };
+
+ for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) {
+ if ((!table[i].fn || table[i].fn == ipfwc_fn)
+ && table[i].err == err) {
+ strcpy(message, table[i].message);
+
+ if (table[i].support_warning)
+ switch (ipfwc_type) {
+ case IPFWC_MASQ:
+ strcat(message, " (Maybe this kernel"
+ " doesn't support"
+ " masquerading?)");
+ break;
+ case IPFWC_REDIRECT:
+ strcat(message, " (Maybe this kernel"
+ " doesn't support"
+ " transparent proxying?)");
+ break;
+ default:
+ }
+ return message;
+ }
+ }
+ return strerror(err);
+}
+
--- /dev/null
+#ifndef _LIBIPFWC_H
+#define _LIBIPFWC_H
+/* Library which manipulates firewall rules. Version 0.1. */
+
+/* This might not be the most efficient way of manipulating the rules,
+ * but I'll maintain this as long as possible... */
+
+/* (C)1998 Paul ``Rusty'' Russell - Placed under the GNU GPL (See
+ COPYING for details). */
+
+#include "ipfwc_kernel_headers.h"
+
+struct ipfwc_fwchain
+{
+ ip_chainlabel label;
+ unsigned int refcnt;
+ ip_chainlabel policy;
+ __u64 packets, bytes;
+};
+
+/* Gets the names of all the chains. Returns internal pointer to
+ array of ipfwc_fwchain. Fills in num_chains. You don't need to be
+ root. Returns NULL on error.*/
+struct ipfwc_fwchain *ipfwc_get_chainnames(unsigned int *num_chains);
+
+struct ipfwc_fwrule
+{
+ const struct ipfwc_fwchain *chain;
+ struct ip_fwuser ipfw;
+ __u64 packets, bytes;
+};
+
+/* Take a snapshot of the rules; if zero is set, clears counters.
+ Uses ipfwc_get_chainnames. Returns internal pointer to array of
+ ipfwc_fwrules. Fills in num_rules. You don't need to be
+ root, unless zero is set. Returns NULL on error. */
+struct ipfwc_fwrule *ipfwc_get_rules(unsigned int *num_rules, int zero);
+
+/* These functions return TRUE for OK or 0 and set errno. If errno ==
+ 0, it means there was a version error (ie. upgrade libipfwc). */
+/* Rule numbers start at 1 for the first rule. */
+
+/* Insert the entry `fw' in chain `chain' into position `rulenum'. */
+int ipfwc_insert_entry(const ip_chainlabel chain,
+ const struct ip_fwuser *fw,
+ unsigned int rulenum);
+
+/* Atomically replace rule `rulenum' in `chain' with `fw'. */
+int ipfwc_replace_entry(const ip_chainlabel chain,
+ const struct ip_fwuser *fw,
+ unsigned int rulenum);
+
+/* Append entry `fw' to chain `chain'. Equivalent to insert with
+ rulenum = length of chain. */
+int ipfwc_append_entry(const ip_chainlabel chain, const struct ip_fwuser *fw);
+
+/* Delete the first rule in `chain' which matches `fw'. */
+int ipfwc_delete_entry(const ip_chainlabel chain, const struct ip_fwuser *fw);
+
+/* Delete the rule in position `rulenum' in `chain'. */
+int ipfwc_delete_num_entry(const ip_chainlabel chain, unsigned int rulenum);
+
+/* Check the packet `fw' on chain `chain'. Returns the verdict, or
+ NULL and sets errno. */
+const char *ipfwc_check_packet(const ip_chainlabel chain, struct ip_fw *fw);
+
+/* Flushes the entries in the given chain (ie. empties chain). */
+int ipfwc_flush_entries(const ip_chainlabel chain);
+
+/* Zeroes the counters in a chain. */
+int ipfwc_zero_entries(const ip_chainlabel chain);
+
+/* Creates a new chain. */
+int ipfwc_create_chain(const ip_chainlabel chain);
+
+/* Deletes a chain. */
+int ipfwc_delete_chain(const ip_chainlabel chain);
+
+/* Sets the policy on a built-in chain. */
+int ipfwc_set_policy(const ip_chainlabel chain, const ip_chainlabel policy);
+
+/* Get raw socket. */
+int ipfwc_get_raw_socket();
+
+/* Translates errno numbers into more human-readable form than strerror. */
+const char *ipfwc_strerror(int err);
+#endif /* _LIBIPFWC_H */
+++ /dev/null
-# Makefile
-# Alexandre Cassen <Alexandre.Cassen@wanadoo.fr>
-
-EXEC= smtpsend
-CC= gcc
-#CFLAGS= -Wall -Wunused
-CFLAGS=
-DEFS= main.h smtpwrapper.h
-OBJECTS= main.o smtpwrapper.o utils.o
-INCLUDE= -I/usr/src/linux/include
-
-.c.o:
-# $(CC) -o $@ $(CFLAGS) $(INCLUDE) -c $*.c
- $(CC) -o $@ $(INCLUDE) -DDEBUG -c $*.c
-
-all: $(EXEC)
- strip $(EXEC)
- @echo ""
- @echo "Make complete"
-
-$(EXEC): $(OBJECTS) $(DEFS)
- $(CC) -o $(EXEC) $(CFLAGS) $(OBJECTS)
-
-clean:
- rm -f core *.o $(EXEC)
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: Main program structure.
- *
- * Version: $Id: keepalived.c,v 0.2.3 2001/01/01 $
- *
- * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
- *
- * Changes:
- * Alexandre Cassen : 2001/01/01 :
- * <+> Change the signalhandling.
- *
- * Alexandre Cassen : 2000/12/09 : Initial release
- *
- * 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.
- */
-
-#include "main.h"
-
-int main(int argc, char **argv)
-{
- printf(PROG" v"VERSION"\n");
-
- SMTP_SENDMAIL("172.31.47.40","25","keepalived@smsgw.cplusfrn.com","acassen@smsgw.cplusfrn.com","le sujet","Test de body",6);
-
- return 0;
-}
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: SMTP WRAPPER connect to a specified smtp server and send mail
- * using the smtp protocol according to the RFC 822. A non blocking
- * timeouted connection is used to handle smtp protocol.
- *
- * Version: $Id: smtpwrapper.c,v 0.2.6 2001/03/01 $
- *
- * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
- *
- * Changes:
- * Alexandre Cassen : 2001/03/01 : Initial release
- *
- *
- * 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.
- */
-
-#include "smtpwrapper.h"
-
-int send_to(register int sdesc, fd_set wfds, struct timeval tv, char *buffer)
-{
- select(sdesc+1,NULL,&wfds,NULL,&tv);
- if (!FD_ISSET(sdesc,&wfds)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Timeout writing data to smtp server\n");
-#endif
- return(SOCKET_ERROR);
- }
-
- if (send(sdesc,buffer,strlen(buffer),0) == -1) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Can not send data to remote smtp server\n");
-#endif
- return(SOCKET_ERROR);
- }
-
- return(SOCKET_SUCCESS);
-}
-
-int read_to(register int sdesc, fd_set rfds, struct timeval tv, char *buffer)
-{
- int rcv_buffer_size=0;
- long total_length=0;
- char *buffertmp;
-
- buffertmp=(char *)malloc(BUFFER_LENGTH);
- memset(buffertmp,0,BUFFER_LENGTH);
-
- select(sdesc+1,&rfds,NULL,NULL,&tv);
- if (!FD_ISSET(sdesc,&rfds)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Timeout receiving data from smtp server\n");
-#endif
- free(buffertmp);
- return(SOCKET_ERROR);
- }
-
- while((rcv_buffer_size = read(sdesc,buffertmp,BUFFER_LENGTH)) != 0) {
- if ( rcv_buffer_size == -1 ) {
- if(errno == EAGAIN) goto end;
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Can not recieve data from remote smtp server\n");
-#endif
- free(buffertmp);
- return(SOCKET_ERROR);
- }
- memcpy(buffer+total_length,buffertmp,rcv_buffer_size);
- memset(buffertmp,0,BUFFER_LENGTH);
- total_length += rcv_buffer_size;
- }
-
-end:
- free(buffertmp);
- return(SOCKET_SUCCESS);
-}
-
-int smtp_cmd(register int sdesc,fd_set rfds,fd_set wfds,struct timeval tv,char *smtpcmd,char *retcode)
-{
- char *buffer;
- char *smtpcode;
-
- buffer=(char *)malloc(BUFFER_LENGTH);
- smtpcode=(char *)malloc(SMTP_ERROR_CODE_LENGTH);
-
- /* Sending SMTP command to remote smtp server */
- if (!send_to(sdesc,wfds,tv,smtpcmd)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending EHLO.\n");
-#endif
- free(buffer);
- free(smtpcode);
- return(SOCKET_ERROR);
- }
-
- /* Processing SMTP server reply */
- memset(buffer,0,BUFFER_LENGTH);
- if(!read_to(sdesc,rfds,tv,buffer)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error receiving data from smtp server.\n");
-#endif
- free(buffer);
- free(smtpcode);
- return(SOCKET_ERROR);
- }
- /* Look for response code */
- memset(smtpcode,0,SMTP_ERROR_CODE_LENGTH);
- memcpy(smtpcode,buffer,SMTP_ERROR_CODE_LENGTH-1);
- if(strcmp(smtpcode,retcode) != 0) {
-#ifdef DEBUG
- logmessage(buffer);
-#endif
- free(buffer);
- free(smtpcode);
- return(SOCKET_ERROR);
- }
-
- free(buffer);
- free(smtpcode);
- return(SOCKET_SUCCESS);
-}
-
-int SMTP_SENDMAIL(char *IP_DST, char *PORT_DST, char *from, char *to,char *subject,char *body,int ctimeout)
-{
- register int sdesc;
- int long_inet;
- struct hostent *ip_serv;
- struct sockaddr_in adr_serv;
- struct linger li = { 0 };
- char *debugmsg;
- char *buffer;
- char *smtpcode;
- char *smtpcmd;
- struct timeval tv;
- fd_set rfds, wfds;
- int rc, flags;
- int arglen;
-
- debugmsg=(char *)malloc(LOGBUFFER_LENGTH);
- buffer=(char *)malloc(BUFFER_LENGTH);
- smtpcode=(char *)malloc(SMTP_ERROR_CODE_LENGTH);
- smtpcmd=(char *)malloc(SMTP_CMD_LENGTH);
- memset(buffer,0,BUFFER_LENGTH);
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- memset(smtpcode,0,SMTP_ERROR_CODE_LENGTH);
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
-
- if ( (sdesc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ) {
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Can not bind remote address %s:%s\n",IP_DST,PORT_DST);
- logmessage(debugmsg);
-#endif
- free(debugmsg);
- free(buffer);
- return(SOCKET_ERROR);
- }
-
- /* free the tcp port after closing the socket descriptor */
- li.l_onoff=1;
- li.l_linger=0;
- setsockopt(sdesc,SOL_SOCKET,SO_LINGER,(char *)&li,sizeof(struct linger));
-
- long_inet = sizeof(struct sockaddr_in);
-
- if ( (ip_serv=gethostbyname(IP_DST)) == NULL) {
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Can not resolve remote host %s\n",IP_DST);
- logmessage(debugmsg);
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- memset(&adr_serv,0,long_inet);
- adr_serv.sin_family=ip_serv->h_addrtype;
- bcopy(ip_serv->h_addr, &adr_serv.sin_addr.s_addr,ip_serv->h_length);
- adr_serv.sin_port=htons(atoi(PORT_DST));
-
- /* Set read/write socket timeout */
- flags=fcntl(sdesc, F_GETFL);
- fcntl(sdesc, F_SETFL, flags | O_NONBLOCK);
-
- /* Connect the remote host */
- if ( (rc=connect(sdesc, (struct sockaddr *)&adr_serv, long_inet)) == -1) {
- switch (errno) {
- case ETIMEDOUT:
- case EINTR:
- case EHOSTUNREACH:
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Connection timeout to %s:%s\n",IP_DST,PORT_DST);
- logmessage(debugmsg);
-#endif
- break;
- case ECONNREFUSED:
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Connection refused to %s:%s\n",IP_DST,PORT_DST);
- logmessage(debugmsg);
-#endif
- break;
- case ENETUNREACH:
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Network unreachable to %s:%s\n",IP_DST,PORT_DST);
- logmessage(debugmsg);
-#endif
- break;
- case EINPROGRESS: // NONBLOCK socket connection in progress
- goto next;
- default:
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Network error [%s] to %s:%s\n",strerror(errno),IP_DST,PORT_DST);
- logmessage(debugmsg);
-#endif
- }
-
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
-next:
- /* Timeout settings */
- tv.tv_sec=ctimeout;
- tv.tv_usec=0;
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_SET(sdesc,&rfds);
- FD_SET(sdesc,&wfds);
-
- rc = select(sdesc+1,&rfds,NULL,NULL,&tv);
- if (!FD_ISSET(sdesc,&rfds)) {
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Timeout reading data to %s:%s\n",IP_DST,PORT_DST);
- logmessage(debugmsg);
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- if (rc < 0) {
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Select returned descriptor error to %s:%s\n",IP_DST,PORT_DST);
- logmessage(debugmsg);
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- rc = 0;
- arglen=sizeof(int);
- if (getsockopt(sdesc,SOL_SOCKET,SO_ERROR,&rc,&arglen) < 0)
- rc = errno;
-
- if (rc) {
-#ifdef DEBUG
- memset(debugmsg,0,LOGBUFFER_LENGTH);
- sprintf(debugmsg,"SMTP_SENDMAIL : Connection failed to %s:%s (%s)\n",IP_DST,PORT_DST,strerror(rc));
- logmessage(debugmsg);
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Proceed the SMTP server reply */
- if(!read_to(sdesc,rfds,tv,buffer)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error receiving data from smtp server.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Look for connect code */
- memset(smtpcode,0,SMTP_ERROR_CODE_LENGTH);
- memcpy(smtpcode,buffer,SMTP_ERROR_CODE_LENGTH-1);
- if(strcmp(smtpcode,SMTP_CONNECT) != 0) {
-#ifdef DEBUG
- logmessage("Can not connect remote smtp server.\n");
-#endif
- }
-
- /* Sending host identification */
- memset(buffer,0,BUFFER_LENGTH);
- if(gethostname(buffer,500)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error resolving local hostname\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Sending EHLO command to remote smtp server */
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
- sprintf(smtpcmd,"EHLO %s\n",buffer);
- if(!smtp_cmd(sdesc,wfds,rfds,tv,smtpcmd,SMTP_EHLO)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending EHLO.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Sending MAIL FROM command to remote smtp server */
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
- sprintf(smtpcmd,"MAIL FROM:%s\n",from);
- if(!smtp_cmd(sdesc,wfds,rfds,tv,smtpcmd,SMTP_MAIL_FROM)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending MAIL FROM.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Sending RCPT TO command to remote smtp server */
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
- sprintf(smtpcmd,"RCPT TO:%s\n",to);
- if(!smtp_cmd(sdesc,wfds,rfds,tv,smtpcmd,SMTP_RCPT_TO)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending RCPT TO.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Sending DATA command to remote smtp server */
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
- sprintf(smtpcmd,"DATA\n");
- if(!smtp_cmd(sdesc,wfds,rfds,tv,smtpcmd,SMTP_DATA)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending DATA.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Sending smtp header to remote smtp server */
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
- sprintf(smtpcmd,"Subject: %s\nX-Mailer: Keepalived SmtpWrapper\n\n",subject);
- if(!send_to(sdesc,wfds,tv,smtpcmd)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending smtp header.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Sending smtp body to remote smtp server */
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
- sprintf(smtpcmd,"\n\n%s\n\n",body);
- if(!send_to(sdesc,wfds,tv,smtpcmd)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending smtp body.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Sending DATA command to remote smtp server */
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
- sprintf(smtpcmd,"\n.\n");
- if(!smtp_cmd(sdesc,wfds,rfds,tv,smtpcmd,SMTP_DOT)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending trailing DOT.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- /* Sending quit to remote smtp server */
- memset(smtpcmd,0,SMTP_CMD_LENGTH);
- sprintf(smtpcmd,"QUIT\n",body);
- if(!send_to(sdesc,wfds,tv,smtpcmd)) {
-#ifdef DEBUG
- logmessage("SMTP_SENDMAIL : Error sending smtp quit.\n");
-#endif
- free(debugmsg);
- free(buffer);
- close(sdesc);
- return(SOCKET_ERROR);
- }
-
- close(sdesc);
- free(debugmsg);
- free(buffer);
- return(SOCKET_SUCCESS);
-}
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: smtpwrapper.c include file.
- *
- * Version: $Id: smtpwrapper.h,v 0.2.6 2001/03/01 $
- *
- * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
- *
- * Changes:
- * Alexandre Cassen : Initial release
- *
- * 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.
- */
-
-#ifndef CFREADER_H
-#define CFREADER_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define SOCKET_ERROR 0
-#define SOCKET_SUCCESS 1
-#define SOCKET_TIMEOUT 3
-
-#define SMTP_CONNECT "220"
-#define SMTP_EHLO "250"
-#define SMTP_MAIL_FROM "250"
-#define SMTP_RCPT_TO "250"
-#define SMTP_DATA "354"
-#define SMTP_DOT "250"
-
-
-#define LOGBUFFER_LENGTH 100
-#define BUFFER_LENGTH 1024
-#define SMTP_ERROR_CODE_LENGTH 4
-#define SMTP_CMD_LENGTH 500
-
-#endif
+++ /dev/null
-/*
- * Soft: Keepalived is a failover program for the LVS project
- * <www.linuxvirtualserver.org>. It monitor & manipulate
- * a loadbalanced server pool using multi-layer checks.
- *
- * Part: General program utils.
- *
- * Version: $Id: utils.c,v 0.2.1 2000/12/09 $
- *
- * Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
- *
- * Changes:
- * Alexandre Cassen : Initial release
- *
- * 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.
- */
-
-void print_buffer(int count, char *buff)
-{
- int i,j,c;
- int printnext=1;
-
- if(count) {
- if(count%16)
- c=count+(16-count%16);
- else c=count;
- } else
- c=count;
-
- for(i=0;i<c;i++) {
- if(printnext) {
- printnext--;
- printf("%.4x ",i&0xffff);
- }
- if(i<count)
- printf("%3.2x",buff[i]&0xff);
- else
- printf(" ");
- if(!((i+1)%8)) {
- if((i+1)%16)
- printf(" -");
- else {
- printf(" ");
- for(j=i-15;j<=i;j++)
- if(j<count) {
- if( (buff[j]&0xff) >= 0x20 && (buff[j]&0xff)<=0x7e)
- printf("%c",buff[j]&0xff);
- else printf(".");
- } else printf(" ");
- printf("\n"); printnext=1;
- }
- }
- }
-}
-
-void logmessage(char *msg)
-{
- printf("%s",msg);
-}
* server. This check implement the tcp half open connection
* check.
*
- * Version: $Id: tcpcheck.c,v 0.2.5 2001/02/16 $
+ * Version: $Id: tcpcheck.c,v 0.2.7 2001/03/27 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
+ * Alexandre Cassen : 2001/03/27 :
+ * <+> Close the socket descriptor missing !
+ * causing a prematurely daemon daemon hangup. (oops)
+ *
* Alexandre Cassen : 2001/02/16 :
* <-> Suppress the whole RAW_SOCKET tcpcheck level initial implementation.
* <+> Replace the RAW_SOCKET initial implementation by a vanilla tcpcheck.
return(SOCKET_ERROR);
}
+ close(sdesc);
free(debugmsg);
return(SOCKET_SUCCESS);
}
#define SOCKET_SUCCESS 1
#define SOCKET_TIMEOUT 3
+
#define LOGBUFFER_LENGTH 100
+/* prototypes */
+//int TCP_CHECK(const char *IP_DST, const char *PORT_DST);
+
#endif
*
* Part: General program utils.
*
- * Version: $Id: utils.c,v 0.2.6 2001/03/01 $
+ * Version: $Id: utils.c,v 0.2.1 2000/12/09 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
- * Alexandre Cassen : 2001/03/01 :
- * <+> Adding daemonpid var to stock running keepalived daemon pid.
- *
- * Alexandre Cassen : 2000/12/09 : Initial release
+ * Alexandre Cassen : Initial release
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*
* Part: utils.c include file.
*
- * Version: $Id: utils.h,v 0.2.6 2001/03/09 $
+ * Version: $Id: utils.h,v 0.2.1 2000/12/09 $
*
* Author: Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
*
* Changes:
- * Alexandre Cassen : 2001/03/01 :
- * <+> Adding global daemon pid var.
- *
- * Alexandre Cassen : 2000/12/09 : Initial release
+ * Alexandre Cassen : Initial release
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License