/// The << operator. std::ostream &operator<<(std::ostream &ostr, const ComplexVector &v) { std::ios::fmtflags fflags(ostr.flags()); ostr << std::scientific << std::setprecision(6); for (size_t j = 0; j < v.size(); ++j) { auto value = v.get(j); ostr << std::setw(28) << value.real() << "+" << value.imag() << "j"; } ostr.flags(fflags); return ostr; }
int relayd_open_rtnl_socket(void) { #ifdef SOCK_CLOEXEC int sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); #else int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); sock = fflags(sock, O_CLOEXEC); #endif // Connect to the kernel netlink interface struct sockaddr_nl nl = {.nl_family = AF_NETLINK}; if (connect(sock, (struct sockaddr*)&nl, sizeof(nl))) { syslog(LOG_ERR, "Failed to connect to kernel rtnetlink: %s", strerror(errno)); return -1; } return sock; }
int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout) { client_options = options; dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_timeout; #ifdef SOCK_CLOEXEC sock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); #else sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); sock = fflags(sock, O_CLOEXEC); #endif if (sock < 0) return -1; // Detect interface struct ifreq ifr; strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) return -1; ifindex = ifr.ifr_ifindex; // Create client DUID size_t client_id_len; odhcp6c_get_state(STATE_CLIENT_ID, &client_id_len); if (client_id_len == 0) { uint8_t duid[14] = {0, DHCPV6_OPT_CLIENTID, 0, 10, 0, DHCPV6_DUID_LLADDR, 0, 1}; if (ioctl(sock, SIOCGIFHWADDR, &ifr) >= 0) memcpy(&duid[8], ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); uint8_t zero[ETHER_ADDR_LEN] = {0, 0, 0, 0, 0, 0}; struct ifreq ifs[100], *ifp, *ifend; struct ifconf ifc; ifc.ifc_req = ifs; ifc.ifc_len = sizeof(ifs); if (!memcmp(&duid[8], zero, ETHER_ADDR_LEN) && ioctl(sock, SIOCGIFCONF, &ifc) >= 0) { // If our interface doesn't have an address... ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); for (ifp = ifc.ifc_req; ifp < ifend && !memcmp(&duid[8], zero, ETHER_ADDR_LEN); ifp++) { memcpy(ifr.ifr_name, ifp->ifr_name, sizeof(ifr.ifr_name)); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) continue; memcpy(&duid[8], ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); } } odhcp6c_add_state(STATE_CLIENT_ID, duid, sizeof(duid)); } // Create ORO if (!(client_options & DHCPV6_STRICT_OPTIONS)) { uint16_t oro[] = { htons(DHCPV6_OPT_SIP_SERVER_D), htons(DHCPV6_OPT_SIP_SERVER_A), htons(DHCPV6_OPT_DNS_SERVERS), htons(DHCPV6_OPT_DNS_DOMAIN), htons(DHCPV6_OPT_SNTP_SERVERS), htons(DHCPV6_OPT_NTP_SERVER), htons(DHCPV6_OPT_AFTR_NAME), htons(DHCPV6_OPT_PD_EXCLUDE), htons(DHCPV6_OPT_SOL_MAX_RT), htons(DHCPV6_OPT_INF_MAX_RT), #ifdef EXT_CER_ID htons(DHCPV6_OPT_CER_ID), #endif htons(DHCPV6_OPT_S46_CONT_MAPE), htons(DHCPV6_OPT_S46_CONT_MAPT), htons(DHCPV6_OPT_S46_CONT_LW), }; odhcp6c_add_state(STATE_ORO, oro, sizeof(oro)); } // Configure IPv6-options int val = 1; setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)); setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)); struct sockaddr_in6 client_addr = { .sin6_family = AF_INET6, .sin6_port = htons(DHCPV6_CLIENT_PORT), .sin6_flowinfo = 0 }; if (bind(sock, (struct sockaddr*)&client_addr, sizeof(client_addr)) < 0) return -1; return 0; } enum { IOV_HDR=0, IOV_ORO, IOV_ORO_REFRESH, IOV_CL_ID, IOV_SRV_ID, IOV_VENDOR_CLASS_HDR, IOV_VENDOR_CLASS, IOV_USER_CLASS_HDR, IOV_USER_CLASS, IOV_RECONF_ACCEPT, IOV_FQDN, IOV_HDR_IA_NA, IOV_IA_NA, IOV_IA_PD, IOV_TOTAL }; int dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd) { int mode = DHCPV6_UNKNOWN; na_mode = na; pd_mode = pd; if (na_mode == IA_MODE_NONE && pd_mode == IA_MODE_NONE) mode = DHCPV6_STATELESS; else if (na_mode == IA_MODE_FORCE || pd_mode == IA_MODE_FORCE) mode = DHCPV6_STATEFUL; return mode; }
/* control multiple files */ int main(int argc, char *argv[]) { int ch; #ifdef TIMING struct timeval t1, t2; (void)gettimeofday(&t1, NULL); #endif prgname = argv[0]; while ((ch = getopt(argc, argv, "OT:VW:X:Z:f:gkm:psvwx:")) != -1) { switch (ch) { #if !defined(MULTIPASS) || defined(PASS1) case 'X': /* pass1 debugging */ while (*optarg) switch (*optarg++) { case 'b': ++bdebug; break; /* buildtree */ case 'd': ++ddebug; break; /* declarations */ case 'e': ++edebug; break; /* pass1 exit */ case 'i': ++idebug; break; /* initializations */ case 'n': ++ndebug; break; /* node allocation */ case 'o': ++odebug; break; /* optim */ case 'p': ++pdebug; break; /* prototype */ case 's': ++sdebug; break; /* inline */ case 't': ++tdebug; break; /* type match */ case 'x': ++xdebug; break; /* MD code */ default: fprintf(stderr, "unknown -X flag '%c'\n", optarg[-1]); exit(1); } break; #endif #if !defined(MULTIPASS) || defined(PASS2) case 'Z': /* pass2 debugging */ while (*optarg) switch (*optarg++) { case 'b': /* basic block and SSA building */ ++b2debug; break; case 'c': /* code printout */ ++c2debug; break; case 'e': /* print tree upon pass2 enter */ ++e2debug; break; case 'f': /* instruction matching */ ++f2debug; break; case 'g': /* print flow graphs */ ++g2debug; break; case 'n': /* node allocation */ ++ndebug; break; case 'o': /* instruction generator */ ++o2debug; break; case 'r': /* register alloc/graph coloring */ ++r2debug; break; case 's': /* shape matching */ ++s2debug; break; case 't': /* type matching */ ++t2debug; break; case 'u': /* Sethi-Ullman debugging */ ++u2debug; break; case 'x': /* target specific */ ++x2debug; break; default: fprintf(stderr, "unknown -Z flag '%c'\n", optarg[-1]); exit(1); } break; #endif case 'f': /* Language */ fflags(optarg); break; case 'g': /* Debugging */ ++gflag; break; case 'k': /* PIC code */ ++kflag; break; case 'm': /* Target-specific */ mflags(optarg); break; case 'p': /* Profiling */ ++pflag; break; case 's': /* Statistics */ ++sflag; break; case 'W': /* Enable different warnings */ Wflags(optarg); break; case 'x': /* Different settings */ xopt(optarg); break; case 'v': printf("ccom: %s\n", VERSSTR); break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc > 0 && strcmp(argv[0], "-") != 0) { if (freopen(argv[0], "r", stdin) == NULL) { fprintf(stderr, "open input file '%s':", argv[0]); perror(NULL); exit(1); } } if (argc > 1 && strcmp(argv[1], "-") != 0) { if (freopen(argv[1], "w", stdout) == NULL) { fprintf(stderr, "open output file '%s':", argv[1]); perror(NULL); exit(1); } } mkdope(); signal(SIGSEGV, segvcatch); #ifdef SIGBUS signal(SIGBUS, segvcatch); #endif fregs = FREGS; /* number of free registers */ lineno = 1; #ifdef GCC_COMPAT gcc_init(); #endif /* starts past any of the above */ reached = 1; bjobcode(); #ifndef TARGET_VALIST { NODE *p = block(NAME, NIL, NIL, PTR|CHAR, NULL, 0); struct symtab *sp = lookup(addname("__builtin_va_list"), 0); p->n_sp = sp; defid(p, TYPEDEF); nfree(p); } #endif complinit(); #ifdef STABS if (gflag) { stabs_file(argc ? argv[0] : ""); stabs_init(); } #endif if (sspflag) sspinit(); (void) yyparse(); yyaccpt(); if (!nerrors) lcommprint(); #ifdef STABS if (gflag) stabs_efile(argc ? argv[0] : ""); #endif ejobcode( nerrors ? 1 : 0 ); #ifdef TIMING (void)gettimeofday(&t2, NULL); t2.tv_sec -= t1.tv_sec; t2.tv_usec -= t1.tv_usec; if (t2.tv_usec < 0) { t2.tv_usec += 1000000; t2.tv_sec -= 1; } fprintf(stderr, "ccom total time: %ld s %ld us\n", t2.tv_sec, t2.tv_usec); #endif if (sflag) prtstats(); return(nerrors?1:0); }
int main(int argc, char* const argv[]) { memset(&config, 0, sizeof(config)); const char *pidfile = "/var/run/6relayd.pid"; bool daemonize = false; int verbosity = 0; int c; while ((c = getopt(argc, argv, "ASR:D:Nsucn::l:a:rt:m:oi:p:dvh")) != -1) { switch (c) { case 'A': config.enable_router_discovery_relay = true; config.enable_dhcpv6_relay = true; config.enable_ndp_relay = true; config.send_router_solicitation = true; config.enable_route_learning = true; break; case 'S': config.enable_router_discovery_relay = true; config.enable_router_discovery_server = true; config.enable_dhcpv6_relay = true; config.enable_dhcpv6_server = true; break; case 'R': config.enable_router_discovery_relay = true; if (!strcmp(optarg, "server")) config.enable_router_discovery_server = true; else if (strcmp(optarg, "relay")) return print_usage(argv[0]); break; case 'D': config.enable_dhcpv6_relay = true; if (!strcmp(optarg, "server")) config.enable_dhcpv6_server = true; else if (strcmp(optarg, "relay")) return print_usage(argv[0]); break; case 'N': config.enable_ndp_relay = true; break; case 's': config.send_router_solicitation = true; break; case 'u': config.always_announce_default_router = true; break; case 'c': config.deprecate_ula_if_public_avail = true; break; case 'n': config.always_rewrite_dns = true; if (optarg) inet_pton(AF_INET6, optarg, &config.dnsaddr); break; case 'l': config.dhcpv6_statefile = strtok(optarg, ","); if (config.dhcpv6_statefile) config.dhcpv6_cb = strtok(NULL, ","); break; case 'a': config.dhcpv6_lease = realloc(config.dhcpv6_lease, sizeof(char*) * ++config.dhcpv6_lease_len); config.dhcpv6_lease[config.dhcpv6_lease_len - 1] = optarg; break; case 'r': config.enable_route_learning = true; break; case 't': config.static_ndp = realloc(config.static_ndp, sizeof(char*) * ++config.static_ndp_len); config.static_ndp[config.static_ndp_len - 1] = optarg; break; case 'm': config.ra_managed_mode = atoi(optarg); break; case 'o': config.ra_not_onlink = true; break; case 'i': if (!strcmp(optarg, "low")) config.ra_preference = -1; else if (!strcmp(optarg, "high")) config.ra_preference = 1; break; case 'p': pidfile = optarg; break; case 'd': daemonize = true; break; case 'v': verbosity++; break; default: return print_usage(argv[0]); } } openlog("6relayd", LOG_PERROR | LOG_PID, LOG_DAEMON); if (verbosity == 0) setlogmask(LOG_UPTO(LOG_WARNING)); else if (verbosity == 1) setlogmask(LOG_UPTO(LOG_INFO)); if (argc - optind < 1) return print_usage(argv[0]); if (getuid() != 0) { syslog(LOG_ERR, "Must be run as root. stopped."); return 2; } #if defined(__NR_epoll_create1) && defined(EPOLL_CLOEXEC) epoll = epoll_create1(EPOLL_CLOEXEC); #else epoll = epoll_create(32); epoll = fflags(epoll, O_CLOEXEC); #endif if (epoll < 0) { syslog(LOG_ERR, "Unable to open epoll: %s", strerror(errno)); return 2; } #ifdef SOCK_CLOEXEC ioctl_sock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); #else ioctl_sock = socket(AF_INET6, SOCK_DGRAM, 0); ioctl_sock = fflags(ioctl_sock, O_CLOEXEC); #endif if ((rtnl_socket = relayd_open_rtnl_socket()) < 0) { syslog(LOG_ERR, "Unable to open socket: %s", strerror(errno)); return 2; } if (open_interface(&config.master, argv[optind++], false)) return 3; config.slavecount = argc - optind; config.slaves = calloc(config.slavecount, sizeof(*config.slaves)); for (size_t i = 0; i < config.slavecount; ++i) { const char *name = argv[optind + i]; bool external = (name[0] == '~'); if (external) ++name; if (open_interface(&config.slaves[i], name, external)) return 3; } if ((urandom_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC)) < 0) return 4; struct sigaction sa = {.sa_handler = SIG_IGN}; sigaction(SIGUSR1, &sa, NULL); if (init_router_discovery_relay(&config)) return 4; if (init_dhcpv6_relay(&config)) return 4; if (init_ndp_proxy(&config)) return 4; if (epoll_registered == 0) { syslog(LOG_WARNING, "No relays enabled or no slave " "interfaces specified. stopped."); return 5; } if (daemonize) { openlog("6relayd", LOG_PID, LOG_DAEMON); // Disable LOG_PERROR if (daemon(0, 0)) { syslog(LOG_ERR, "Failed to daemonize: %s", strerror(errno)); return 6; } FILE *fp = fopen(pidfile, "w"); if (fp) { fprintf(fp, "%i\n", getpid()); fclose(fp); } } signal(SIGTERM, set_stop); signal(SIGHUP, set_stop); signal(SIGINT, set_stop); signal(SIGCHLD, wait_child); // Main loop while (!do_stop) { struct epoll_event ev[16]; int len = epoll_wait(epoll, ev, 16, -1); for (int i = 0; i < len; ++i) { struct relayd_event *event = ev[i].data.ptr; if (event->handle_event) event->handle_event(event); else if (event->handle_dgram) relayd_receive_packets(event); } } syslog(LOG_WARNING, "Termination requested by signal."); deinit_ndp_proxy(); deinit_router_discovery_relay(); free(config.slaves); close(urandom_fd); return 0; }
/* control multiple files */ int main(int argc, char *argv[]) { int ch; prgname = argv[0]; while ((ch = getopt(argc, argv, "OT:VW:X:Z:f:gklm:psvwx:")) != -1) switch (ch) { #if !defined(MULTIPASS) || defined(PASS1) case 'X': while (*optarg) switch (*optarg++) { case 'd': ++ddebug; break; /* declarations */ case 'i': ++idebug; break; /* initializations */ case 'b': ++bdebug; break; case 't': ++tdebug; break; case 'e': ++edebug; break; /* pass1 exit */ case 'x': ++xdebug; break; /* MD code */ case 's': ++sdebug; break; case 'n': ++nflag; break; case 'o': ++oflag; break; case 'p': ++pdebug; break; /* prototype */ default: fprintf(stderr, "unknown X flag '%c'\n", optarg[-1]); exit(1); } #endif break; #if !defined(MULTIPASS) || defined(PASST) case 'T': while (*optarg) switch (*optarg++) { case 'i': ++iTflag; break; case 'o': ++oTflag; break; case 'n': ++nflag; break; default: fprintf(stderr, "unknown T flag '%c'\n", optarg[-1]); exit(1); } #endif break; #if !defined(MULTIPASS) || defined(PASS2) case 'Z': while (*optarg) switch (*optarg++) { case 'f': /* instruction matching */ ++f2debug; break; case 'e': /* print tree upon pass2 enter */ ++e2debug; break; case 'o': ++odebug; break; case 'r': /* register alloc/graph coloring */ ++rdebug; break; case 'b': /* basic block and SSA building */ ++b2debug; break; case 'c': /* code printout */ ++c2debug; break; case 't': ++t2debug; break; case 's': /* shape matching */ ++s2debug; break; case 'u': /* Sethi-Ullman debugging */ ++udebug; break; case 'x': ++x2debug; break; case 'n': ++nflag; break; default: fprintf(stderr, "unknown Z flag '%c'\n", optarg[-1]); exit(1); } #endif break; case 'f': /* Language */ fflags(optarg); break; case 'g': /* Debugging */ gflag = 1; break; case 'k': /* PIC code */ ++kflag; break; case 'l': /* Linenos */ ++lflag; break; case 'm': /* Target-specific */ mflags(optarg); break; case 'p': /* Profiling */ pflag = 1; break; case 's': /* Statistics */ ++sflag; break; case 'W': /* Enable different warnings */ Wflags(optarg); break; case 'x': /* Different optimizations */ if (strcmp(optarg, "ssa") == 0) xssaflag++; else if (strcmp(optarg, "tailcall") == 0) xtailcallflag++; else if (strcmp(optarg, "temps") == 0) xtemps++; else if (strcmp(optarg, "deljumps") == 0) xdeljumps++; else usage(); break; case 'v': printf("ccom: %s\n", VERSSTR); break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc > 0 && strcmp(argv[0], "-") != 0) { if (freopen(argv[0], "r", stdin) == NULL) { fprintf(stderr, "open input file '%s':", argv[0]); perror(NULL); exit(1); } } if (argc > 1 && strcmp(argv[1], "-") != 0) { if (freopen(argv[1], "w", stdout) == NULL) { fprintf(stderr, "open output file '%s':", argv[1]); perror(NULL); exit(1); } } mkdope(); signal(SIGSEGV, segvcatch); fregs = FREGS; /* number of free registers */ lineno = 1; #ifdef GCC_COMPAT gcc_init(); #endif /* dimension table initialization */ btdims[VOID].suesize = 0; btdims[BOOL].suesize = SZBOOL; btdims[CHAR].suesize = SZCHAR; btdims[INT].suesize = SZINT; btdims[FLOAT].suesize = SZFLOAT; btdims[DOUBLE].suesize = SZDOUBLE; btdims[LDOUBLE].suesize = SZLDOUBLE; btdims[LONG].suesize = SZLONG; btdims[LONGLONG].suesize = SZLONGLONG; btdims[SHORT].suesize = SZSHORT; btdims[UCHAR].suesize = SZCHAR; btdims[USHORT].suesize = SZSHORT; btdims[UNSIGNED].suesize = SZINT; btdims[ULONG].suesize = SZLONG; btdims[ULONGLONG].suesize = SZLONGLONG; btdims[FCOMPLEX].suesize = SZFLOAT * 2; btdims[COMPLEX].suesize = SZDOUBLE * 2; btdims[LCOMPLEX].suesize = SZLDOUBLE * 2; /* starts past any of the above */ reached = 1; bjobcode(); #ifdef STABS if (gflag) { stabs_file(argc ? argv[0] : ""); stabs_init(); } #endif if (sspflag) sspinit(); (void) yyparse(); yyaccpt(); if (!nerrors) lcommprint(); ejobcode( nerrors ? 1 : 0 ); if (sflag) prtstats(); return(nerrors?1:0); }