/* Remove a realserver IPVS rule */ static int clear_service_rs(list vs_group, virtual_server * vs, list l) { element e; real_server *rs; char rsip[16], vsip[16]; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); if (ISALIVE(rs)) { if (!ipvs_cmd(LVS_CMD_DEL_DEST , vs_group , vs , rs)) return 0; UNSET_ALIVE(rs); if (!vs->omega) continue; /* In Omega mode we call VS and RS down notifiers * all the way down the exit, as necessary. */ if (rs->notify_down) { log_message(LOG_INFO, "Executing [%s] for service [%s:%d]" " in VS [%s:%d]" , rs->notify_down , inet_ntoa2(SVR_IP(rs), rsip) , ntohs(SVR_PORT(rs)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); notify_exec(rs->notify_down); } /* Sooner or later VS will lose the quorum (if any). However, * we don't push in a sorry server then, hence the regression * is intended. */ if (vs->quorum_state == UP && vs->quorum_down && weigh_live_realservers(vs) < vs->quorum - vs->hysteresis) { vs->quorum_state = DOWN; log_message(LOG_INFO, "Executing [%s] for VS [%s:%d]" , vs->quorum_down , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); notify_exec(vs->quorum_down); } } #ifdef _KRNL_2_2_ /* if we have a /32 mask, we create one nat rules per * realserver. */ if (vs->nat_mask == HOST_NETMASK) if (!ipfw_cmd(IP_FW_CMD_DEL, vs, rs)) return 0; #endif } return 1; }
/** * Converts a LibNIDS address tuple to a string. * @param addr Address tuple * @return static string */ char *addr_to_str(struct tuple4 addr) { static char buf[256]; char *ptr = buf; int len = sizeof(buf); snprintf(ptr, len, "%s:%d ", inet_ntoa2(addr.saddr), addr.source); len -= strlen(ptr); ptr += strlen(ptr); snprintf(ptr, len, "%s:%d", inet_ntoa2(addr.daddr), addr.dest); return buf; }
/* Store new weight in real_server struct and then update kernel. */ void update_svr_wgt(int weight, virtual_server * vs, real_server * rs) { char rsip[16], vsip[16]; if (weight != rs->weight) { log_message(LOG_INFO, "Changing weight from %d to %d for %s service [%s:%d]" " of VS [%s:%d]" , rs->weight , weight , ISALIVE(rs) ? "active" : "inactive" , inet_ntoa2(SVR_IP(rs), rsip) , ntohs(SVR_PORT(rs)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); rs->weight = weight; /* * Have weight change take effect now only if rs is alive. * If not, it will take effect later when it becomes alive. */ if (ISALIVE(rs)) ipvs_cmd(LVS_CMD_EDIT_DEST, check_data->vs_group, vs, rs); } }
/* manipulate add/remove rs according to alive state */ void perform_svr_state(int alive, virtual_server * vs, real_server * rs) { char rsip[16], vsip[16]; /* * | ISALIVE(rs) | alive | context * | 0 | 0 | first check failed under alpha mode, unreachable here * | 0 | 1 | RS went up, add it to the pool * | 1 | 0 | RS went down, remove it from the pool * | 1 | 1 | first check succeeded w/o alpha mode, unreachable here */ if (!ISALIVE(rs) && alive) { /* adding a server to the vs pool, if sorry server is flagged alive, * we remove it from the vs pool. */ if (vs->s_svr) { if (ISALIVE(vs->s_svr) && (vs->quorum_state == UP || (weigh_live_realservers(vs) + rs->weight >= vs->quorum + vs->hysteresis))) { log_message(LOG_INFO, "Removing sorry server [%s:%d] from VS [%s:%d]", inet_ntoa2(SVR_IP(vs->s_svr), rsip) , ntohs(SVR_PORT(vs->s_svr)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); ipvs_cmd(LVS_CMD_DEL_DEST , check_data->vs_group , vs , vs->s_svr); vs->s_svr->alive = 0; #ifdef _KRNL_2_2_ ipfw_cmd(IP_FW_CMD_DEL, vs, vs->s_svr); #endif } } log_message(LOG_INFO, "%s service [%s:%d] to VS [%s:%d]", (rs->inhibit) ? "Enabling" : "Adding" , inet_ntoa2(SVR_IP(rs), rsip) , ntohs(SVR_PORT(rs)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, rs); rs->alive = alive; if (rs->notify_up) { log_message(LOG_INFO, "Executing [%s] for service [%s:%d]" " in VS [%s:%d]" , rs->notify_up , inet_ntoa2(SVR_IP(rs), rsip) , ntohs(SVR_PORT(rs)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); notify_exec(rs->notify_up); } /* If we have just gained quorum, it's time to consider notify_up. */ if (vs->quorum_state == DOWN && weigh_live_realservers(vs) >= vs->quorum + vs->hysteresis) { vs->quorum_state = UP; log_message(LOG_INFO, "Gained quorum %lu+%lu=%lu <= %u for VS [%s:%d]" , vs->quorum , vs->hysteresis , vs->quorum + vs->hysteresis , weigh_live_realservers(vs) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); if (vs->quorum_up) { log_message(LOG_INFO, "Executing [%s] for VS [%s:%d]" , vs->quorum_up , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); notify_exec(vs->quorum_up); } } #ifdef _KRNL_2_2_ if (vs->nat_mask == HOST_NETMASK) ipfw_cmd(IP_FW_CMD_ADD, vs, rs); #endif return; } if (ISALIVE(rs) && !alive) { log_message(LOG_INFO, "%s service [%s:%d] from VS [%s:%d]", (rs->inhibit) ? "Disabling" : "Removing" , inet_ntoa2(SVR_IP(rs), rsip) , ntohs(SVR_PORT(rs)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); /* server is down, it is removed from the LVS realserver pool */ ipvs_cmd(LVS_CMD_DEL_DEST, check_data->vs_group, vs, rs); rs->alive = alive; if (rs->notify_down) { log_message(LOG_INFO, "Executing [%s] for service [%s:%d]" " in VS [%s:%d]" , rs->notify_down , inet_ntoa2(SVR_IP(rs), rsip) , ntohs(SVR_PORT(rs)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); notify_exec(rs->notify_down); } #ifdef _KRNL_2_2_ if (vs->nat_mask == HOST_NETMASK) ipfw_cmd(IP_FW_CMD_DEL, vs, rs); #endif /* If we have just lost quorum for the VS, we need to consider * VS notify_down and sorry_server cases */ if (vs->quorum_state == UP && weigh_live_realservers(vs) < vs->quorum - vs->hysteresis) { vs->quorum_state = DOWN; log_message(LOG_INFO, "Lost quorum %lu-%lu=%lu > %u for VS [%s:%d]" , vs->quorum , vs->hysteresis , vs->quorum - vs->hysteresis , weigh_live_realservers(vs) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); if (vs->quorum_down) { log_message(LOG_INFO, "Executing [%s] for VS [%s:%d]" , vs->quorum_down , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); notify_exec(vs->quorum_down); } if (vs->s_svr) { log_message(LOG_INFO, "Adding sorry server [%s:%d] to VS [%s:%d]", inet_ntoa2(SVR_IP(vs->s_svr), rsip) , ntohs(SVR_PORT(vs->s_svr)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); /* the sorry server is now up in the pool, we flag it alive */ ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, vs->s_svr); vs->s_svr->alive = 1; #ifdef _KRNL_2_2_ ipfw_cmd(IP_FW_CMD_ADD, vs, vs->s_svr); #endif } } } }
static int init_device() { /* subnet mask */ bpf_u_int32 maskcodep; char *maskcode; /* ip address */ bpf_u_int32 netip; char *ip; /*error buffer*/ char errbuff[PCAP_ERRBUF_SIZE]; int i,cho;/* cho for user to choose a Network InterfaceCard */ pcap_if_t *d;/* temp variable */ /* list all the device on the computer */ if(pcap_findalldevs(&alldevs,errbuff)==-1) { printf("%s\n",errbuff); return ERROR; } for(d=alldevs,i=1;d;d=d->next,i++) { printf("%d. %s:\n",i,d->name); if(pcap_lookupnet(d->name,&netip,&maskcodep,errbuff)==-1) { printf("%s\n",errbuff); continue; } ip = inet_ntoa2(netip); maskcode = inet_ntoa2(maskcodep); printf("\tip : %s\n\tmaskcode: %s\n",ip,maskcode); } /* make a choice */ printf("which one?\n"); scanf("%d",&cho); for(i=0,dev=alldevs;i<cho-1;i++,dev=dev->next); printf("device %s selected\n",dev->name); memcpy(dev_name,dev->name,strlen(dev->name)+1); /* get device basic infomation */ struct ifreq ifr; int sock; if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("socket"); return ERROR; } strcpy(ifr.ifr_name, dev->name); // get Mac address if(ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) { printf("ioctl"); return ERROR; } memcpy(Local_mac, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); printf("ether dst %02x:%02x:%02x:%02x:%02x:%02x and ether proto 0x888e\n",Local_mac[0], Local_mac[1],Local_mac[2], Local_mac[3],Local_mac[4], Local_mac[5]); /* open device */ if((handle=pcap_open_live(dev->name,1518,1,1000,errbuff))==NULL) { printf("open device %s failed\n",dev->name); return ERROR; } pcap_freealldevs(alldevs); return DONE; }