/*
* 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: VRRP implementation of VRRPv2 as specified in rfc2338.
* VRRP is a protocol which elect a master server on a LAN. If the
* master fails, a backup server takes over.
* The original implementation has been made by jerome etienne.
*
* Version: $Id: vrrp.c,v 1.1.15 2007/09/15 04:07:41 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* 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.
*
* 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.
*
* Copyright (C) 2001-2007 Alexandre Cassen, <acassen@freebox.fr>
*/
/* local include */
#include <ctype.h>
#include <sys/uio.h>
#include "vrrp_arp.h"
#include "vrrp_scheduler.h"
#include "vrrp_notify.h"
#include "ipvswrapper.h"
#include "vrrp.h"
#include "vrrp_data.h"
#include "vrrp_sync.h"
#include "vrrp_index.h"
#include "memory.h"
#include "list.h"
#include "main.h"
#include "utils.h"
#include "notify.h"
/* add/remove Virtual IP addresses */
static int
vrrp_handle_ipaddress(vrrp_rt * vrrp, int cmd, int type)
{
if (debug & 32)
syslog(LOG_INFO, "VRRP_Instance(%s) %s protocol %s", vrrp->iname,
(cmd == IPADDRESS_ADD) ? "setting" : "removing",
(type == VRRP_VIP_TYPE) ? "VIPs." : "E-VIPs.");
netlink_iplist_ipv4((type == VRRP_VIP_TYPE) ? vrrp->vip : vrrp->evip
, cmd);
return 1;
}
/* add/remove Virtual routes */
static int
vrrp_handle_iproutes(vrrp_rt * vrrp, int cmd)
{
if (debug & 32)
syslog(LOG_INFO, "VRRP_Instance(%s) %s protocol Virtual Routes",
vrrp->iname,
(cmd == IPROUTE_ADD) ? "setting" : "removing");
netlink_rtlist_ipv4(vrrp->vroutes, cmd);
return 1;
}
/* IP header length */
static int
vrrp_iphdr_len(vrrp_rt * vrrp)
{
return sizeof (struct iphdr);
}
/* IPSEC AH header length */
int
vrrp_ipsecah_len(void)
{
return sizeof (ipsec_ah);
}
/* VRRP header length */
static int
vrrp_hd_len(vrrp_rt * vrrp)
{
int len = sizeof (vrrp_pkt) + VRRP_AUTH_LEN;
return (!LIST_ISEMPTY(vrrp->vip)) ?
len + LIST_SIZE(vrrp->vip) * sizeof (uint32_t) : len;
}
/*
* IPSEC AH incoming packet check.
* return 0 for a valid pkt, != 0 otherwise.
*/
static int
vrrp_in_chk_ipsecah(vrrp_rt * vrrp, char *buffer)
{
struct iphdr *ip = (struct iphdr *) (buffer);
ipsec_ah *ah = (ipsec_ah *) ((char *) ip + (ip->ihl << 2));
unsigned char *digest;
uint32_t backup_auth_data[3];
/* first verify that the SPI value is equal to src IP */
if (ah->spi != ip->saddr) {
syslog(LOG_INFO,
"IPSEC AH : invalid IPSEC SPI value. %d and expect %d",
ip->saddr, ah->spi);
return 1;
}
/*
* then proceed with the sequence number to prevent against replay attack.
* For inbound processing, we increment seq_number counter to audit
* sender counter.
*/
vrrp->ipsecah_counter->seq_number++;
if (ntohl(ah->seq_number) >= vrrp->ipsecah_counter->seq_number || vrrp->sync) {
vrrp->ipsecah_counter->seq_number = ntohl(ah->seq_number);
} else {
syslog(LOG_INFO,
"VRRP_Instance(%s) IPSEC-AH : sequence number %d"
" already proceeded. Packet dropped. Local(%d)", vrrp->iname
, ntohl(ah->seq_number), vrrp->ipsecah_counter->seq_number);
return 1;
}
/*
* then compute a ICV to compare with the one present in AH pkt.
* alloc a temp memory space to stock the ip mutable fields
*/
digest = (unsigned char *) MALLOC(16 * sizeof (unsigned char *));
/* zero the ip mutable fields */
ip->tos = 0;
ip->frag_off = 0;
ip->check = 0;
memcpy(backup_auth_data, ah->auth_data, sizeof (ah->auth_data));
memset(ah->auth_data, 0, sizeof (ah->auth_data));
/* Compute the ICV */
hmac_md5(buffer,
vrrp_iphdr_len(vrrp) + vrrp_ipsecah_len() + vrrp_hd_len(vrrp)
, vrrp->auth_data, sizeof (vrrp->auth_data)
, digest);
if (memcmp(backup_auth_data, digest, HMAC_MD5_TRUNC) != 0) {
syslog(LOG_INFO, "VRRP_Instance(%s) IPSEC-AH : invalid"
" IPSEC HMAC-MD5 value. Due to fields mutation"
" or bad password !", vrrp->iname);
return 1;
}
FREE(digest);
return 0;
}
/* check if ipaddr is present in VIP buffer */
static int
vrrp_in_chk_vips(vrrp_rt * vrrp, uint32_t ipaddr, unsigned char *buffer)
{
int i;
uint32_t ipbuf;
for (i = 0; i < LIST_SIZE(vrrp->vip); i++) {
bcopy(buffer + i * sizeof (uint32_t), &ipbuf,
sizeof (uint32_t));
if (ipaddr == ipbuf)
return 1;
}
return 0;
}
/*
* VRRP incoming packet check.
* return 0 if the pkt is valid, != 0 otherwise.
*/
static int
vrrp_in_chk(vrrp_rt * vrrp, char *buffer)
{
struct iphdr *ip = (struct iphdr *) (buffer);
int ihl = ip->ihl << 2;
ipsec_ah *ah;
vrrp_pkt *hd;
unsigned char *vips;
ip_address *ipaddress;
element e;
if (vrrp->auth_type == VRRP_AUTH_AH) {
ah = (ipsec_ah *) (buffer + sizeof (struct iphdr));
hd = (vrrp_pkt *) (buffer + ihl + vrrp_ipsecah_len());
} else {
hd = (vrrp_pkt *) (buffer + ihl);
}
/* pointer to vrrp vips pkt zone */
vips = (unsigned char *) ((char *) hd + sizeof (vrrp_pkt));
/* MUST verify that the IP TTL is 255 */
if (ip->ttl != VRRP_IP_TTL) {
syslog(LOG_INFO, "invalid ttl. %d and expect %d", ip->ttl,
VRRP_IP_TTL);
return VRRP_PACKET_KO;
}
/* MUST verify the VRRP version */
if ((hd->vers_type >> 4) != VRRP_VERSION) {
syslog(LOG_INFO, "invalid version. %d and expect %d",
(hd->vers_type >> 4), VRRP_VERSION);
return VRRP_PACKET_KO;
}
/*
* MUST verify that the received packet length is greater than or
* equal to the VRRP header
*/
if ((ntohs(ip->tot_len) - ihl) <= sizeof (vrrp_pkt)) {
syslog(LOG_INFO,
"ip payload too short. %d and expect at least %d",
ntohs(ip->tot_len) - ihl, sizeof (vrrp_pkt));
return VRRP_PACKET_KO;
}
/* MUST verify the VRRP checksum */
if (in_csum((u_short *) hd,
sizeof(vrrp_pkt) + VRRP_AUTH_LEN + hd->naddr * sizeof(uint32_t), 0)) {
syslog(LOG_INFO, "Invalid vrrp checksum");
return VRRP_PACKET_KO;
}
/*
* MUST perform authentication specified by Auth Type
* check the authentication type
*/
if (vrrp->auth_type != hd->auth_type) {
syslog(LOG_INFO, "receive a %d auth, expecting %d!",
vrrp->auth_type, hd->auth_type);
return VRRP_PACKET_KO;
}
/* check the authentication if it is a passwd */
if (hd->auth_type == VRRP_AUTH_PASS) {
char *pw = (char *) ip + ntohs(ip->tot_len)
- sizeof (vrrp->auth_data);
if (memcmp(pw, vrrp->auth_data, sizeof(vrrp->auth_data)) != 0) {
syslog(LOG_INFO, "receive an invalid passwd!");
return VRRP_PACKET_KO;
}
}
/* MUST verify that the VRID is valid on the receiving interface */
if (vrrp->vrid != hd->vrid) {
syslog(LOG_INFO,
"received VRID mismatch. Received %d, Expected %d",
hd->vrid, vrrp->vrid);
return VRRP_PACKET_DROP;
}
if (!LIST_ISEMPTY(vrrp->vip)) {
/*
* MAY verify that the IP address(es) associated with the
* VRID are valid
*/
if (hd->naddr != LIST_SIZE(vrrp->vip)) {
syslog(LOG_INFO,
"receive an invalid ip number count associated with VRID!");
return VRRP_PACKET_KO;
}
for (e = LIST_HEAD(vrrp->vip); e; ELEMENT_NEXT(e)) {
ipaddress = ELEMENT_DATA(e);
if (!vrrp_in_chk_vips(vrrp, ipaddress->addr, vips)) {
syslog(LOG_INFO, "ip address associated with VRID"
" not present in received packet : %d",
没有合适的资源?快使用搜索试试~ 我知道了~
keepalived-1.1.15.tar.gz
需积分: 13 18 下载量 183 浏览量
2009-01-16
19:32:14
上传
评论
收藏 222KB GZ 举报
温馨提示
共167个文件
h:53个
c:52个
in:13个
keepalived-1.1.15.tar.gz负载均衡,免费
资源推荐
资源详情
资源评论
收起资源包目录
keepalived-1.1.15.tar.gz (167个子文件)
genhash.1 1KB
keepalived.conf.5 14KB
keepalived.8 2KB
AUTHOR 41B
AUTHOR 39B
vrrp.c 29KB
vrrp_scheduler.c 27KB
check_http.c 26KB
check_smtp.c 24KB
ipvswrapper.c 19KB
scheduler.c 17KB
vrrp_netlink.c 16KB
smtp.c 15KB
ipwrapper.c 14KB
libipfwc.c 14KB
vrrp_parser.c 12KB
vrrp_data.c 12KB
vrrp_if.c 11KB
memory.c 9KB
parser.c 9KB
check_data.c 9KB
libipvs.c 8KB
main.c 8KB
check_ssl.c 8KB
http.c 7KB
check_misc.c 7KB
check_parser.c 7KB
vrrp_sync.c 7KB
vrrp_daemon.c 6KB
vrrp_iproute.c 6KB
check_daemon.c 6KB
vrrp_ipaddress.c 6KB
layer4.c 6KB
libipvs.c 5KB
main.c 5KB
check_tcp.c 5KB
vrrp_notify.c 5KB
vrrp_track.c 5KB
utils.c 5KB
layer4.c 5KB
ssl.c 5KB
check_api.c 5KB
global_data.c 4KB
signals.c 4KB
list.c 4KB
vrrp_arp.c 3KB
vector.c 3KB
vrrp_ipsecah.c 3KB
timer.c 3KB
vrrp_index.c 3KB
global_parser.c 3KB
html.c 3KB
ipfwwrapper.c 2KB
pidfile.c 2KB
notify.c 2KB
daemon.c 2KB
sock.c 2KB
ChangeLog 80KB
ChangeLog 639B
keepalived.conf 3KB
configure 159KB
CONTRIBUTORS 830B
COPYING 18KB
COPYING 18KB
keepalived.conf.fwmark 433B
vrrp.h 8KB
ipfwc_kernel_headers.h 5KB
check_data.h 5KB
vrrp_if.h 4KB
scheduler.h 4KB
libipvs.h 4KB
ipvswrapper.h 3KB
libipfwc.h 3KB
check_http.h 3KB
check_api.h 3KB
vrrp_track.h 3KB
smtp.h 3KB
parser.h 3KB
vrrp_data.h 3KB
ipwrapper.h 2KB
vrrp_ipaddress.h 2KB
memory.h 2KB
vrrp_ipsecah.h 2KB
vrrp_netlink.h 2KB
vrrp_iproute.h 2KB
list.h 2KB
vrrp_arp.h 2KB
main.h 2KB
http.h 2KB
check_smtp.h 2KB
vrrp_scheduler.h 2KB
utils.h 2KB
global_data.h 2KB
timer.h 2KB
vrrp_sync.h 2KB
vector.h 2KB
layer4.h 2KB
libipvs.h 2KB
main.h 2KB
layer4.h 2KB
共 167 条
- 1
- 2
资源评论
ly_nye
- 粉丝: 1
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功