⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 system.c

📁 BCAST Implementation for NS2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Add/modify a kernel routing table entry. * Multipath is not supported, so just use the first path * found in the routing table entry. * If there is no next hop pointer, it means that there * is either a) and unresolved next hop or b) and entry * whose interface has been deleted, but the router-LSA * not yet reoriginated. In either case, just delete * the routing table entry. */void LinuxOspfd::rtadd(InAddr net, InMask mask, MPath *mpp, 		     MPath *ompp, bool reject){    if (directs.find(net, mask))	return;    if (!mpp) {	rtdel(net, mask, ompp);	return;    }    if (ompp)	rtdel(net, mask, ompp);    rtentry_prepare(net, mask, mpp);    // Reject route?     if (reject)	m.rt_flags |=  RTF_REJECT;    else	m.rt_flags |= (RTF_UP | RTF_GATEWAY);    // Add through ioctl    if (-1 == ioctl(udpfd, SIOCADDRT, (char *)&m)) {        if (errno == EEXIST) {	    ioctl(udpfd, SIOCDELRT, (char *)&m);	    if (-1 != ioctl(udpfd, SIOCADDRT, (char *)&m))	        return;	}	syslog(LOG_ERR, "SIOCADDRT: %m");    }}/* Delete a kernel routing table entry. */void LinuxOspfd::rtdel(InAddr net, InMask mask, MPath *ompp){    if (directs.find(net, mask))	return;    rtentry_prepare(net, mask, ompp);    // Delete through ioctl    if (-1 == ioctl(udpfd, SIOCDELRT, (char *)&m))	syslog(LOG_ERR, "SIOCDELRT: %m");}/* Uploading remnant routing table entries is not supported * on older Linux versions. */void LinuxOspfd::upload_remnants(){}#else/* On Linux 2.2, add and delete routing table entries * via the rtnetlink interface. Note that we are setting * rtm_protocol to 89. The Linux kernel doesn't do anything * special with the value, but it allows us to delete entries * freely without worrying that we will bash some other * routing daemon's entries. We should register the rtm_protocol * value with the Linux guys. */void LinuxOspfd::rtadd(InAddr net, InMask mask, MPath *mpp, 		     MPath *ompp, bool reject){    nlmsghdr *nlm;    rtmsg *rtm;    rtattr *rta_dest;    rtattr *rta_gw;    int size;    int prefix_length;    if (directs.find(net, mask) || !mpp) {	rtdel(net, mask, ompp);	return;    }    // Change mask to prefix length    for (prefix_length = 32; prefix_length > 0; prefix_length--) {	if ((mask & (1 << (32-prefix_length))) != 0)	    break;    }    // Calculate size of routing message    size = NLMSG_SPACE(sizeof(*rtm)); // Routing message itself    if (prefix_length > 0)	size += RTA_SPACE(4);	// For destination    if (!reject)	size += RTA_SPACE(4);	// For next hop    // Allocate routing table message, and find place for    // individual data items    nlm = (nlmsghdr *) new char[size];    nlm->nlmsg_len = size;    nlm->nlmsg_type = RTM_NEWROUTE;    nlm->nlmsg_flags = NLM_F_REQUEST|NLM_F_REPLACE|NLM_F_CREATE;    nlm->nlmsg_seq = nlm_seq++;    nlm->nlmsg_pid = 0;    rtm = (rtmsg *) NLMSG_DATA(nlm);    rtm->rtm_family = AF_INET;    rtm->rtm_dst_len = prefix_length;    rtm->rtm_src_len = 0;    rtm->rtm_tos = 0;    rtm->rtm_table = 0;    rtm->rtm_protocol = PROT_OSPF;    rtm->rtm_scope = RT_SCOPE_UNIVERSE;    rtm->rtm_type = RTN_UNICAST;    rtm->rtm_flags = 0;    if (prefix_length > 0) {        uns32 swnet;	int attrlen;	rta_dest = (rtattr *) RTM_RTA(rtm);	rta_dest->rta_len = attrlen = RTA_SPACE(4);	rta_dest->rta_type = RTA_DST;	swnet = hton32(net);	memcpy(RTA_DATA(rta_dest), &swnet, sizeof(swnet));	rta_gw = (rtattr *) RTA_NEXT(rta_dest, attrlen);    }    else	rta_gw = (rtattr *) RTM_RTA(rtm);    // Reject route?     if (reject) {	rtm->rtm_scope = RT_SCOPE_HOST;	rtm->rtm_type = RTN_UNREACHABLE;    }    else {	InAddr gw;	BSDPhyInt *phyp=0;	int phyint;	gw = hton32(mpp->NHs[0].gw);	if ((phyint = mpp->NHs[0].phyint) != -1)	    phyp = (BSDPhyInt *)phyints.find(phyint, 0);	if (phyp && (phyp->flags & IFF_POINTOPOINT) != 0){	    // Fill in gw attribute	    rta_gw->rta_len = RTA_SPACE(sizeof(phyint));	    rta_gw->rta_type = RTA_OIF;	    memcpy(RTA_DATA(rta_gw), &phyint, sizeof(phyint));	}	else {	    // Fill in gw attribute	    rta_gw->rta_len = RTA_SPACE(4);	    rta_gw->rta_type = RTA_GATEWAY;	    memcpy(RTA_DATA(rta_gw), &gw, sizeof(gw));	}    }    // Add through routing socket send    if (-1 == send(rtsock, nlm, size, 0))	syslog(LOG_ERR, "add route through routing socket: %m");    delete [] ((char *)nlm);}void LinuxOspfd::rtdel(InAddr net, InMask mask, MPath *){    nlmsghdr *nlm;    rtmsg *rtm;    rtattr *rta_dest;    int size;    int prefix_length;    // Change mask to prefix length    for (prefix_length = 32; prefix_length > 0; prefix_length--) {	if ((mask & (1 << (32-prefix_length))) != 0)	    break;    }    // Calculate size of routing message    size = NLMSG_SPACE(sizeof(*rtm)); // Routing message itself    if (prefix_length > 0)	size += RTA_SPACE(4);	// For destination    // Allocate routing table message, and find place for    // individual data items    nlm = (nlmsghdr *) new char[size];    nlm->nlmsg_len = size;    nlm->nlmsg_type = RTM_DELROUTE;    nlm->nlmsg_flags = NLM_F_REQUEST;    nlm->nlmsg_seq = nlm_seq++;    nlm->nlmsg_pid = 0;    rtm = (rtmsg *) NLMSG_DATA(nlm);    rtm->rtm_family = AF_INET;    rtm->rtm_dst_len = prefix_length;    rtm->rtm_src_len = 0;    rtm->rtm_tos = 0;    rtm->rtm_table = 0;    rtm->rtm_protocol = PROT_OSPF;    rtm->rtm_scope = RT_SCOPE_UNIVERSE;    rtm->rtm_type = RTN_UNICAST;    rtm->rtm_flags = 0;    if (prefix_length > 0) {        uns32 swnet;	int attrlen;	rta_dest = (rtattr *) RTM_RTA(rtm);	rta_dest->rta_len = attrlen = RTA_SPACE(4);	rta_dest->rta_type = RTA_DST;	swnet = hton32(net);	memcpy(RTA_DATA(rta_dest), &swnet, sizeof(swnet));    }    // Delete through routing socket send    if (-1 == send(rtsock, nlm, size, 0))	syslog(LOG_ERR, "del route through routing socket: %m");    delete [] ((char *)nlm);}/* Request the kernel to upload the current set of routing * table entries that it has. */void LinuxOspfd::upload_remnants(){    nlmsghdr *nlm;    rtmsg *rtm;    int size;    // Set state to dumping    dumping_remnants = true;    // Calculate size of netlink message    size = NLMSG_SPACE(sizeof(*rtm)); // Only a routing message    // Allocate netlink message    nlm = (nlmsghdr *) new char[size];    nlm->nlmsg_len = size;    nlm->nlmsg_type = RTM_GETROUTE;    nlm->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;    nlm->nlmsg_seq = nlm_seq++;    nlm->nlmsg_pid = 0;    rtm = (rtmsg *) NLMSG_DATA(nlm);    rtm->rtm_family = AF_INET;    rtm->rtm_dst_len = 0;    rtm->rtm_src_len = 0;    rtm->rtm_tos = 0;    rtm->rtm_table = 0;    rtm->rtm_protocol = PROT_OSPF;    rtm->rtm_scope = RT_SCOPE_UNIVERSE;    rtm->rtm_type = RTN_UNICAST;    rtm->rtm_flags = 0;    // Send to routing socket    if (-1 == send(rtsock, nlm, size, 0))	syslog(LOG_ERR, "routing table dump: %m");    delete [] ((char *)nlm);}#endif/* Add a multicast routing table entry to the kernel. */void LinuxOspfd::add_mcache(InAddr src, InAddr grp, MCache *e){    mfcctl mfe;    int i;    // Initially set to drop matching packets    mfe.mfcc_origin.s_addr = hton32(src);    mfe.mfcc_mcastgrp.s_addr = hton32(grp);    mfe.mfcc_parent = 0;    for (i = 0; i < MAXVIFS; i++)        mfe.mfcc_ttls[i] = 255;    // Now fill in with MOSPF information    if (e) {        BSDPhyInt *phyp;        if (e->n_upstream && (phyp=(BSDPhyInt *)phyints.find(*e->up_phys, 0)))	    mfe.mfcc_parent = phyp->vifno;	for (i = 0; i < e->n_downstream; i++) {	    if (e->down_str[i].nbr_addr != 0)  	        // NBMA multicast not supported by Linux	        continue;	    if (!(phyp = (BSDPhyInt *)phyints.find(e->down_str[i].phyint, 0)))	        continue;	    if (phyp->vifno == 0)	        continue;	    // Linux ignores TTL 0, so bump to 1 in that case	    if ((mfe.mfcc_ttls[phyp->vifno] = e->down_str[i].ttl) == 0)	        mfe.mfcc_ttls[phyp->vifno] = 1;	}    }    if (setsockopt(igmpfd, IPPROTO_IP, MRT_ADD_MFC, &mfe, sizeof(mfe)) == -1)        syslog(LOG_ERR, "MRT_ADD_MFC failed: %m");}/* Delete a multicast routing table entry from the kernel. */void LinuxOspfd::del_mcache(InAddr src, InAddr grp){    mfcctl mfe;    mfe.mfcc_origin.s_addr = hton32(src);    mfe.mfcc_mcastgrp.s_addr = hton32(grp);    if (setsockopt(igmpfd, IPPROTO_IP, MRT_DEL_MFC, &mfe, sizeof(mfe)) == -1)        syslog(LOG_ERR, "MRT_DEL_MFC failed: %m");}/* Return the printable name of a physical interface. */char *LinuxOspfd::phyname(int phyint){    BSDPhyInt *phyp;    phyp = (BSDPhyInt *)phyints.find(phyint, 0);    return(phyp ? (char *) phyp->phyname : 0);}/* Print an OSPF logging message into the * log file. */void LinuxOspfd::sys_spflog(int msgno, char *msgbuf){    time_t t;    tm *tp;    t = time(0);    tp = localtime(&t);    fprintf(logstr, "%02d:%02d:%02d OSPF.%03d: %s\n",	    tp->tm_hour, tp->tm_min, tp->tm_sec, msgno, msgbuf);    fflush(logstr);}/* Exit the ospfd program, printing a diagnostic message in * the process. */void LinuxOspfd::halt(int code, char *string){    syslog(LOG_ERR, "Exiting: %s, code %d", string, code);    if (code !=  0)	abort();    else if (changing_routerid)        change_complete = true;    else        exit(0);}/* Store the hitless restart parameters in the file * /etc/ospfd.restart. These are regular TCL commands, which * will get read again when the ospfd restarts. */const char *ospfd_rst_file = "/etc/ospfd.restart";void LinuxOspfd::store_hitless_parms(int grace_period, int n, MD5Seq *sns){    FILE *f;    extern rtid_t new_router_id;    in_addr addr;    if (!(f = fopen(ospfd_rst_file, "w"))) {        syslog(LOG_ERR, "Can't open %s for writing: %m", ospfd_rst_file);	return;    }    fprintf(f, "grace_period %d\n", grace_period);    addr.s_addr = hton32(new_router_id);    fprintf(f, "routerid %s\n", inet_ntoa(addr));    for (int i = 0; i < n; i++) {        if (sns[i].if_addr != 0) {	    addr.s_addr = hton32(sns[i].if_addr);	    fprintf(f, "interface %s 1\n", inet_ntoa(addr));	}	else	    fprintf(f, "interface %s 1\n", phyname(sns[i].phyint));	fprintf(f, "md5_seqno %d\n", sns[i].seqno);    }    fclose(f);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -