int icmp6_init(void) { struct icmp6_filter filter; pthread_mutexattr_t mattrs; int val; icmp6_sock.fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); if (icmp6_sock.fd < 0) { syslog(LOG_ERR, "Unable to open ICMPv6 socket! " "Do you have root permissions?"); return icmp6_sock.fd; } val = 1; if (setsockopt(icmp6_sock.fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)) < 0) return -1; if (setsockopt(icmp6_sock.fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &val, sizeof(val)) < 0) return -1; ICMP6_FILTER_SETBLOCKALL(&filter); ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &filter); if (is_ha()) { ICMP6_FILTER_SETPASS(MIP_PREFIX_SOLICIT, &filter); ICMP6_FILTER_SETPASS(MIP_HA_DISCOVERY_REQUEST, &filter); ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); } if (is_mn()) { ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter); ICMP6_FILTER_SETPASS(MIP_PREFIX_ADVERT, &filter); ICMP6_FILTER_SETPASS(MIP_HA_DISCOVERY_REPLY, &filter); ICMP6_FILTER_SETPASS(ICMP6_PARAM_PROB, &filter); } if (setsockopt(icmp6_sock.fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(struct icmp6_filter)) < 0) return -1; val = 2; if (setsockopt(icmp6_sock.fd, IPPROTO_RAW, IPV6_CHECKSUM, &val, sizeof(val)) < 0) return -1; /* create ICMP listener thread */ pthread_mutexattr_init(&mattrs); pthread_mutexattr_settype(&mattrs, PTHREAD_MUTEX_FAST_NP); if (pthread_mutex_init(&icmp6_sock.send_mutex, &mattrs) || pthread_rwlock_init(&handler_lock, NULL) || pthread_create(&icmp6_listener, NULL, icmp6_listen, NULL)) return -1; return 0; }
void conf_show(struct mip6_config *c) { int i; /* Common options */ dbg("config_file = %s\n", c->config_file); #ifdef ENABLE_VT dbg("vt_hostname = %s\n", c->vt_hostname); dbg("vt_service = %s\n", c->vt_service); #endif dbg("mip6_entity = %u\n", c->mip6_entity); dbg("debug_level = %u\n", c->debug_level); dbg("debug_log_file = %s\n", (c->debug_log_file ? c->debug_log_file : "stderr")); if (c->pmgr.so_path) dbg("PolicyModulePath = %s\n", c->pmgr.so_path); dbg("DefaultBindingAclPolicy = %u\n", c->DefaultBindingAclPolicy); dbg("NonVolatileBindingCache = %s\n", CONF_BOOL_STR(c->NonVolatileBindingCache)); /* IPsec options */ dbg("KeyMngMobCapability = %s\n", CONF_BOOL_STR(c->KeyMngMobCapability)); dbg("UseMnHaIPsec = %s\n", CONF_BOOL_STR(c->UseMnHaIPsec)); /* MN options */ dbg("MnMaxHaBindingLife = %u\n", c->MnMaxHaBindingLife); dbg("MnMaxCnBindingLife = %u\n", c->MnMaxCnBindingLife); dbg("MnRouterProbes = %u\n", c->MnRouterProbes); dbg("MnRouterProbeTimeout = %f\n", tstodsec(c->MnRouterProbeTimeout_ts)); dbg("InitialBindackTimeoutFirstReg = %f\n", tstodsec(c->InitialBindackTimeoutFirstReg_ts)); dbg("InitialBindackTimeoutReReg = %f\n", tstodsec(c->InitialBindackTimeoutReReg_ts)); if (c->MoveModulePath) dbg("MoveModulePath = %s\n", c->MoveModulePath); dbg("UseCnBuAck = %s\n", CONF_BOOL_STR(c->CnBuAck)); dbg("DoRouteOptimizationMN = %s\n", CONF_BOOL_STR(c->DoRouteOptimizationMN)); dbg("MnUseAllInterfaces = %s\n", CONF_BOOL_STR(c->MnUseAllInterfaces)); dbg("MnDiscardHaParamProb = %s\n", CONF_BOOL_STR(c->MnDiscardHaParamProb)); dbg("SendMobPfxSols = %s\n", CONF_BOOL_STR(c->SendMobPfxSols)); dbg("OptimisticHandoff = %s\n", CONF_BOOL_STR(c->OptimisticHandoff)); dbg("MobRtrUseExplicitMode = %s\n", CONF_BOOL_STR(c->MobRtrUseExplicitMode)); /* HA options */ dbg("SendMobPfxAdvs = %s\n", CONF_BOOL_STR(c->SendMobPfxAdvs)); dbg("SendUnsolMobPfxAdvs = %s\n", CONF_BOOL_STR(c->SendUnsolMobPfxAdvs)); dbg("MaxMobPfxAdvInterval = %u\n", c->MaxMobPfxAdvInterval); dbg("MinMobPfxAdvInterval = %u\n", c->MinMobPfxAdvInterval); dbg("HaMaxBindingLife = %u\n", c->HaMaxBindingLife); dbg("HaAcceptMobRtr = %s\n", CONF_BOOL_STR(c->HaAcceptMobRtr)); /* CN options */ dbg("DoRouteOptimizationCN = %s\n", CONF_BOOL_STR(c->DoRouteOptimizationCN)); /* PMIP options */ dbg("RFC5213TimestampBasedApproachInUse = %s\n",CONF_BOOL_STR(c->RFC5213TimestampBasedApproachInUse)); dbg("RFC5213MobileNodeGeneratedTimestampInUse = %s\n",CONF_BOOL_STR(c->RFC5213MobileNodeGeneratedTimestampInUse)); dbg("RFC5213FixedMAGLinkLocalAddressOnAllAccessLinks = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->RFC5213FixedMAGLinkLocalAddressOnAllAccessLinks)); dbg("RFC5213FixedMAGLinkLayerAddressOnAllAccessLinks = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->RFC5213FixedMAGLinkLayerAddressOnAllAccessLinks)); /* PMIP LMA options */ dbg("RFC5213MinDelayBeforeBCEDelete = %u.%9u seconds\n",c->RFC5213MinDelayBeforeBCEDelete.tv_sec,c->RFC5213MinDelayBeforeBCEDelete.tv_nsec); dbg("RFC5213MaxDelayBeforeNewBCEAssign = %u.%9u seconds\n",c->RFC5213MaxDelayBeforeNewBCEAssign.tv_sec,c->RFC5213MaxDelayBeforeNewBCEAssign.tv_nsec); dbg("RFC5213TimestampValidityWindow = %u.%9u seconds\n",c->RFC5213TimestampValidityWindow.tv_sec,c->RFC5213TimestampValidityWindow.tv_nsec); /* PMIP MAG options */ dbg("RFC5213EnableMAGLocalRouting = %s\n", CONF_BOOL_STR(c->RFC5213EnableMAGLocalRouting)); dbg("AllLmaMulticastAddress = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->AllLmaMulticastAddress)); dbg("LmaAddress = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->LmaAddress)); if (is_ha()) { for (i = 0; i < c->NumMags; i++) { dbg("MAG %d: \n", i); dbg(" MagAddressIngress = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->MagAddressIngress[i])); dbg(" MagAddressEgress = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->MagAddressEgress[i])); } } if (is_mag()) { dbg("MagAddressIngress = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->MagAddressIngress[0])); dbg("MagAddressEgress = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->MagAddressEgress[0])); dbg("MagDeviceIngress = %s\n", (c->MagDeviceIngress ? c->MagDeviceIngress : "No device")); dbg("MagDeviceEgress = %s\n", (c->MagDeviceEgress ? c->MagDeviceEgress : "No device")); dbg("PBULifeTime = %u.%9u seconds\n",c->PBULifeTime.tv_sec,c->PBULifeTime.tv_nsec); dbg("RetransmissionTimeOut = %u.%9u seconds\n",c->RetransmissionTimeOut.tv_sec,c->RetransmissionTimeOut.tv_nsec); dbg("RadiusClientConfigFile = %s\n", (c->RadiusClientConfigFile ? c->RadiusClientConfigFile : "No Config file")); dbg("RadiusPassword = %s\n", (c->RadiusPassword ? c->RadiusPassword : "******")); dbg("PcapSyslogAssociationGrepString = %s\n", (c->PcapSyslogAssociationGrepString ? c->PcapSyslogAssociationGrepString : "No syslog association grep string")); dbg("PcapSyslogDeAssociationGrepString = %s\n", (c->PcapSyslogDeAssociationGrepString ? c->PcapSyslogDeAssociationGrepString : "No syslog de-association grep string")); } dbg("OurAddress = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->OurAddress)); dbg("HomeNetworkPrefix = %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(&c->HomeNetworkPrefix)); dbg("MaxMessageRetransmissions = %u\n", c->MaxMessageRetransmissions); dbg("TunnelingEnabled = %s\n", CONF_BOOL_STR(c->TunnelingEnabled)); dbg("DynamicTunnelingEnabled = %s\n", CONF_BOOL_STR(c->DynamicTunnelingEnabled)); dbg("MaxDelayBeforeDynamicTunnelingDelete = %u.%9u seconds\n",c->MaxDelayBeforeDynamicTunnelingDelete.tv_sec,c->MaxDelayBeforeDynamicTunnelingDelete.tv_nsec); }
int main(int argc, char **argv) { pthread_t sigth; sigset_t sigblock; int logflags = 0; int ret = 1; debug_init(); sigemptyset(&sigblock); sigaddset(&sigblock, SIGHUP); sigaddset(&sigblock, SIGINT); sigaddset(&sigblock, SIGTERM); #ifdef ENABLE_VT sigaddset(&sigblock, SIGPIPE); #endif pthread_sigmask(SIG_BLOCK, &sigblock, NULL); if (conf_parse(&conf, argc, argv)) return 1; if (conf.debug_level > 0) logflags = LOG_PERROR; openlog(basename(argv[0]), LOG_PID|logflags, LOG_DAEMON); syslog(LOG_INFO, "%s v%s started (%s)", PACKAGE_NAME, PACKAGE_VERSION, entity_string[conf.mip6_entity]); #ifdef ENABLE_VT if (vt_init() < 0) goto vt_failed; #endif /* if not debugging, detach from tty */ if (conf.debug_level == 0) daemon_start(1); else { /* if debugging with debug log file, detach from tty */ if (conf.debug_log_file) { daemon_start(1); ret = debug_open(conf.debug_log_file); if (ret < 0) { fprintf(stderr, "can't init debug log:%s\n", strerror(-ret)); goto debug_failed; } dbg("%s started in debug mode\n", PACKAGE_NAME); } else { dbg("%s started in debug mode, not detaching from terminal\n", PACKAGE_NAME); } conf_show(&conf); } srandom(time(NULL)); if (rr_cn_init() < 0) goto rr_cn_failed; if (policy_init() < 0) goto policy_failed; if (taskqueue_init() < 0) goto taskqueue_failed; if (bcache_init() < 0) goto bcache_failed; if (mh_init() < 0) goto mh_failed; if (icmp6_init() < 0) goto icmp6_failed; if (xfrm_init() < 0) goto xfrm_failed; cn_init(); if ((is_ha() || is_mn()) && tunnelctl_init() < 0) goto tunnelctl_failed; if (is_ha() && ha_init() < 0) goto ha_failed; if (is_mn() && mn_init() < 0) goto mn_failed; #ifdef ENABLE_VT if (vt_start(conf.vt_hostname, conf.vt_service) < 0) goto vt_start_failed; #endif if (pthread_create(&sigth, NULL, sigh, NULL)) goto sigth_failed; pthread_join(sigth, NULL); ret = 0; sigth_failed: #ifdef ENABLE_VT vt_fini(); vt_start_failed: #endif if (is_mn()) mn_cleanup(); mn_failed: if (is_ha()) ha_cleanup(); ha_failed: if (is_ha() || is_mn()) tunnelctl_cleanup(); tunnelctl_failed: cn_cleanup(); xfrm_cleanup(); xfrm_failed: icmp6_cleanup(); icmp6_failed: mh_cleanup(); mh_failed: bcache_cleanup(); bcache_failed: taskqueue_destroy(); taskqueue_failed: policy_cleanup(); policy_failed: rr_cn_failed: debug_close(); debug_failed: #ifdef ENABLE_VT vt_failed: #endif syslog(LOG_INFO, "%s v%s stopped (%s)", PACKAGE_NAME, PACKAGE_VERSION, entity_string[conf.mip6_entity]); closelog(); return ret; }
//--------------------------------------------------------------------------------------------------------------------- void pmip_timer_bce_expired_handler(struct tq_elem *tqe) { int mutex_return_code; mutex_return_code = pthread_rwlock_wrlock(&pmip_lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_wrlock(&pmip_lock) %s\n", strerror(mutex_return_code)); } printf("-------------------------------------\n"); if (!task_interrupted()) { pmip_entry_t *e = tq_data(tqe, pmip_entry_t, tqe); mutex_return_code = pthread_rwlock_wrlock(&e->lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_wrlock(&e->lock) %s\n", strerror(mutex_return_code)); } dbg("Retransmissions counter : %d\n", e->n_rets_counter); if (e->n_rets_counter == 0) { dbg("Retransmissions counter expired\n"); free_iov_data((struct iovec *) &e->mh_vec, e->iovlen); if (is_mag()) { //++e->seqno_out; dbg("Calling deregistration\n"); mag_dereg(e, 1); pmipcache_release_entry(e); pmip_bce_delete(e); return; } //Delete existing route for the deleted MN if (is_ha()) { lma_dereg(e, 0, 0); pmipcache_release_entry(e); pmip_bce_delete(e); return; } mutex_return_code = pthread_rwlock_unlock(&pmip_lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&pmip_lock) %s\n", strerror(mutex_return_code)); } return; } if (is_mag()) { dbg("Send NS for Neighbour Reachability for:%x:%x:%x:%x:%x:%x:%x:%x iif=%d\n", NIP6ADDR(&e->mn_hw_address), e->link); //Create NS for Reachability test! //ndisc_send_ns(e->link, &conf.MagAddressIngress[0], solicited_mcast(&e->mn_suffix), get_mn_addr(e)); ndisc_send_ns(e->link, get_mn_addr(e)); struct timespec expires; clock_gettime(CLOCK_REALTIME, &e->add_time); tsadd(e->add_time, conf.RetransmissionTimeOut, expires); // Add a new task for deletion of entry if No Na is received. add_task_abs(&expires, &e->tqe, pmip_timer_bce_expired_handler); dbg("Start the Timer for Retransmission/Deletion ....\n"); //Decrements the Retransmissions counter. e->n_rets_counter--; mutex_return_code = pthread_rwlock_unlock(&e->lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&e->lock) %s\n", strerror(mutex_return_code)); } } if (is_ha()) { lma_dereg(e, 0, 0); pmipcache_release_entry(e); pmip_bce_delete(e); return; } } mutex_return_code = pthread_rwlock_unlock(&pmip_lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&pmip_lock) %s\n", strerror(mutex_return_code)); } }