📄 vrrpd.c
字号:
return 1; } /* check the authentication if it is a passwd */ if( hd->auth_type != VRRP_AUTH_PASS ){ char *pw = (char *)ip + ntohs(ip->tot_len) -sizeof(vif->auth_data); if( memcmp( pw, vif->auth_data, sizeof(vif->auth_data)) ){ VRRP_LOG(("receive an invalid passwd!")); return 1; } } /* MUST verify that the VRID is valid on the receiving interface */ if( vsrv->vrid != hd->vrid ){ return 1; } /* MAY verify that the IP address(es) associated with the VRID are ** valid */ /* WORK: currently we don't */ /* MUST verify that the Adver Interval in the packet is the same as ** the locally configured for this virtual router */ if( vsrv->adver_int/VRRP_TIMER_HZ != hd->adver_int ){ VRRP_LOG(("advertissement interval mismatch mine=%d rcved=%d" , vsrv->adver_int, hd->adver_int )); return 1; } return 0;}/**************************************************************** NAME : vrrp_build_dlt 00/02/02 14:39:18 AIM : REMARK : rfc2338.7.3****************************************************************/static void vrrp_build_dlt( vrrp_rt *vsrv, char *buffer, int buflen ){ /* hardcoded for ethernet */ struct ether_header * eth = (struct ether_header *)buffer; /* destination address --rfc1122.6.4*/ eth->ether_dhost[0] = 0x01; eth->ether_dhost[1] = 0x00; eth->ether_dhost[2] = 0x5E; eth->ether_dhost[3] = (INADDR_VRRP_GROUP >> 16) & 0x7F; eth->ether_dhost[4] = (INADDR_VRRP_GROUP >> 8) & 0xFF; eth->ether_dhost[5] = INADDR_VRRP_GROUP & 0xFF; /* source address --rfc2338.7.3 */ memcpy( eth->ether_shost, vrrp_hwaddr, sizeof(vrrp_hwaddr)); /* type */ eth->ether_type = htons( ETHERTYPE_IP );}/**************************************************************** NAME : vrrp_build_ip 00/02/02 14:39:18 AIM : build a ip packet REMARK :****************************************************************/static void vrrp_build_ip( vrrp_rt *vsrv, char *buffer, int buflen ){ struct iphdr * ip = (struct iphdr *)(buffer); ip->ihl = 5; ip->version = 4; ip->tos = 0; ip->tot_len = ip->ihl*4 + vrrp_hd_len( vsrv ); ip->tot_len = htons(ip->tot_len); ip->id = ++ip_id; ip->frag_off = 0; ip->ttl = VRRP_IP_TTL; ip->protocol = IPPROTO_VRRP; ip->saddr = htonl(vsrv->vif.ipaddr); ip->daddr = htonl(INADDR_VRRP_GROUP); /* checksum must be done last */ ip->check = in_csum( (u_short*)ip, ip->ihl*4, 0 );}/**************************************************************** NAME : vrrp_build_vrrp 00/02/02 14:39:18 AIM : REMARK :****************************************************************/static int vrrp_build_vrrp( vrrp_rt *vsrv, int prio, char *buffer, int buflen ){ int i; vrrp_if *vif = &vsrv->vif; vrrp_pkt *hd = (vrrp_pkt *)buffer; uint32_t *iparr = (uint32_t *)((char *)hd+sizeof(*hd)); hd->vers_type = (VRRP_VERSION<<4) | VRRP_PKT_ADVERT; hd->vrid = vsrv->vrid; hd->priority = prio; hd->naddr = vsrv->naddr; hd->auth_type = vsrv->vif.auth_type; hd->adver_int = vsrv->adver_int/VRRP_TIMER_HZ; /* copy the ip addresses */ for( i = 0; i < vsrv->naddr; i++ ){ iparr[i] = htonl( vsrv->vaddr[i].addr ); } hd->chksum = in_csum( (u_short*)hd, vrrp_hd_len(vsrv), 0); /* copy the passwd if the authentication is VRRP_AH_PASS */ if( vif->auth_type == VRRP_AUTH_PASS ){ char *pw = (char *)hd+sizeof(*hd)+vsrv->naddr*4; memcpy( pw, vif->auth_data, sizeof(vif->auth_data)); } return(0);}/**************************************************************** NAME : vrrp_set_ptk 00/02/02 13:33:32 AIM : build a advertissement packet REMARK :****************************************************************/static void vrrp_build_pkt( vrrp_rt *vsrv, int prio, char *buffer, int buflen ){// printf("dltlen=%d iplen=%d", vrrp_dlt_len(vsrv), vrrp_iphdr_len(vsrv) ); /* build the ethernet header */ vrrp_build_dlt( vsrv, buffer, buflen ); buffer += vrrp_dlt_len(vsrv); buflen -= vrrp_dlt_len(vsrv); /* build the ip header */ vrrp_build_ip( vsrv, buffer, buflen ); buffer += vrrp_iphdr_len(vsrv); buflen -= vrrp_iphdr_len(vsrv); /* build the vrrp header */ vrrp_build_vrrp( vsrv, prio, buffer, buflen );}/**************************************************************** NAME : vrrp_send_pkt 00/02/06 16:37:10 AIM : REMARK :****************************************************************/static int vrrp_send_pkt( vrrp_rt *vsrv, char *buffer, int buflen ){ struct sockaddr from; int len; int fd = socket(PF_PACKET, SOCK_PACKET, 0x300); /* 0x300 is magic */// WORK: if( fd < 0 ){ perror( "socket" ); return -1; } /* build the address */ memset( &from, 0 , sizeof(from)); strcpy( from.sa_data, vsrv->vif.ifname ); /* send the data */ len = sendto( fd, buffer, buflen, 0, &from, sizeof(from) );//printf("len=%d\n",len); close( fd ); return len;}/**************************************************************** NAME : vrrp_send_adv 00/02/06 16:31:24 AIM : REMARK :****************************************************************/static int vrrp_send_adv( vrrp_rt *vsrv, int prio ){ int buflen, ret; char * buffer;#if 0 /* just for debug */ struct in_addr in; in.s_addr = htonl(vsrv->vif.ipaddr); printf("send an advertissement on %s\n",inet_ntoa(in) );#endif /* alloc the memory */ buflen = vrrp_dlt_len(vsrv) + vrrp_iphdr_len(vsrv) + vrrp_hd_len(vsrv); buffer = calloc( buflen, 1 ); assert( buffer ); /* build the packet */ vrrp_build_pkt( vsrv, prio, buffer, buflen ); /* send it */ ret = vrrp_send_pkt( vsrv, buffer, buflen ); /* build the memory */ free( buffer ); return ret;}/**************************************************************** NAME : usage 00/02/06 08:50:28 AIM : display the usage REMARK :****************************************************************/static void usage( void ){ fprintf( stderr, "vrrpd version %s\n", VRRPD_VERSION ); fprintf( stderr, "Usage: vrrpd -i ifname -v vrid [-f piddir] [-s] [-a auth] [-p prio] [-nh] ipaddr\n" ); fprintf( stderr, " -h : display this short inlined help\n" ); fprintf( stderr, " -n : Dont handle the virtual mac address\n" ); fprintf( stderr, " -i ifname: the interface name to run on\n" ); fprintf( stderr, " -v vrid : the id of the virtual server [1-255]\n" ); fprintf( stderr, " -s : Switch the preemption mode (%s by default)\n" , VRRP_PREEMPT_DFL? "Enabled" : "Disabled" ); fprintf( stderr, " -a auth : (not yet implemented) set the authentification type\n" ); fprintf( stderr, " auth=(none|pass/hexkey|ah/hexkey) hexkey=0x[0-9a-fA-F]+\n"); fprintf( stderr, " -p prio : Set the priority of this host in the virtual server (dfl: %d)\n" , VRRP_PRIO_DFL ); fprintf( stderr, " -f piddir: specify the directory where the pid file is stored (dfl: %s)\n" , VRRP_PIDDIR_DFL ); fprintf( stderr, " -d delay : Set the advertisement interval (in sec) (dfl: %d)\n" , VRRP_ADVER_DFL ); fprintf( stderr, " ipaddr : the ip address(es) of the virtual server\n" );}/**************************************************************** NAME : parse_authopt 00/09/26 22:01:17 AIM : REMARK : parse the authentication option from the user****************************************************************/static int parse_authopt(vrrp_rt *vsrv, char *str){ int len = strlen(str); vrrp_if *vif = &vsrv->vif; vif->auth_type = VRRP_AUTH_NONE; /* epxlicitly no authentication */ if( !strcmp(str,"none") ) return 0; /* below the min len */ if( len < 5 ) return -1; /* check the type of authentication */ if( !strncmp(str, "ah/0x", 5 ) ){ vif->auth_type = VRRP_AUTH_AH; return -1; /* WORK: not yet implemented */ }else if( !strncmp(str, "pw/0x", 5 ) ){ int i,j; vif->auth_type = VRRP_AUTH_PASS; memset( vif->auth_data, 0, sizeof(vif->auth_data) ); /* parse the key */ for( i=5,j=0; j < sizeof(vif->auth_data)*2 && i<len ;i++,j++ ){ /* sanity check */ if( !isxdigit(str[i]) ) return -1; str[i] = toupper(str[i]); if( str[i] >= 'A' ) str[i] -= 'A' - 10; else str[i] -= '0'; vif->auth_data[j/2] |= str[i] << (j&1 ? 0 : 4 );//WORK: printf(" j=%d c=%d 0x%x\n",j,str[i],vif->auth_data[j/2]); } if( i != len ) return -1; }else{ return -1; } return(0);}/**************************************************************** NAME : parse_cmdline 00/02/06 09:09:11 AIM : REMARK :****************************************************************/static int parse_cmdline( vrrp_rt *vsrv, int argc, char *argv[] ){ vrrp_if *vif = &vsrv->vif; int c; while( 1 ){ c = getopt( argc, argv, "f:si:v:a:p:d:hn" ); /* if the parsing is completed, exit */ if( c == EOF ) break; switch( c ){ case 'n': vsrv->no_vmac = 1; break; case 's': vsrv->preempt = !vsrv->preempt; break; case 'f': snprintf( PidDir, sizeof(PidDir), "%s", optarg ); break; case 'i': vif->ifname = strdup( optarg ); /* get the ip address */ vif->ipaddr = ifname_to_ip( optarg ); if( !vif->ipaddr ){ fprintf( stderr, "no interface found!\n" ); goto err; } /* get the hwaddr */ if( hwaddr_get( vif->ifname, vif->hwaddr , sizeof(vif->hwaddr)) ){ fprintf( stderr, "Can't read the hwaddr on this interface!\n" ); goto err; }// printf("ifname=%s 0x%x\n",vsrv->vif.ifname,vsrv->vif.ipaddr); break; case 'v': vsrv->vrid = atoi( optarg ); if( VRRP_IS_BAD_VID(vsrv->vrid) ){ fprintf( stderr, "bad vrid!\n" ); goto err; } vrrp_hwaddr[0] = 0x00; vrrp_hwaddr[1] = 0x00; vrrp_hwaddr[2] = 0x5E; vrrp_hwaddr[3] = 0x00; vrrp_hwaddr[4] = 0x01; vrrp_hwaddr[5] = vsrv->vrid; break; case 'a': if( parse_authopt( vsrv, optarg ) ){ fprintf( stderr, "Invalid authentication key!\n" ); goto err; } break; case 'p': vsrv->priority = atoi( optarg ); if( VRRP_IS_BAD_PRIORITY(vsrv->priority) ){ fprintf( stderr, "bad priority!\n" ); goto err; } break; case 'd': vsrv->adver_int = atoi( optarg ); if( VRRP_IS_BAD_ADVERT_INT(vsrv->adver_int) ){ fprintf( stderr, "bad advert_int!\n" ); goto err; } vsrv->adver_int *= VRRP_TIMER_HZ; break; case 'h': usage(); exit( 1 ); break; case ':': /* missing parameter */ case '?': /* unknown option */ default: goto err; } } return optind;err:; usage(); return -1;}/**************************************************************** NAME : cfg_add_ipaddr 00/02/06 09:24:08 AIM : REMARK :****************************************************************/static void cfg_add_ipaddr( vrrp_rt *vsrv, uint32_t ipaddr ){ vsrv->naddr++; /* alloc the room */ if( vsrv->vaddr ){ vsrv->vaddr = realloc( vsrv->vaddr , vsrv->naddr*sizeof(*vsrv->vaddr) ); } else { vsrv->vaddr = malloc( sizeof(*vsrv->vaddr) ); } assert( vsrv->vaddr ); /* store the data */ vsrv->vaddr[vsrv->naddr-1].addr = ipaddr; vsrv->vaddr[vsrv->naddr-1].deletable = 0;}/**************************************************************** NAME : init_virtual_srv 00/02/06 09:18:02 AIM : REMARK :****************************************************************/static void init_virtual_srv( vrrp_rt *vsrv ){ memset( vsrv, 0, sizeof(*vsrv) ); vsrv->state = VRRP_STATE_INIT; vsrv->priority = VRRP_PRIO_DFL; vsrv->adver_int = VRRP_ADVER_DFL*VRRP_TIMER_HZ; vsrv->preempt = VRRP_PREEMPT_DFL;}/**************************************************************** NAME : chk_min_cfg 00/02/06 17:07:45 AIM : TRUE if the minimal configuration isnt done REMARK :****************************************************************/static int chk_min_cfg( vrrp_rt *vsrv )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -