int reload_radvd(void) { FILE *fp; int ipv6_type, i_dhcp6s_mode, i_adv_per; char *adv_prefix, *adv_rdnss, *lan_addr6_prefix; char addr6s[INET6_ADDRSTRLEN], rdns6s[INET6_ADDRSTRLEN], wan_ifname[16] = {0}; ipv6_type = get_ipv6_type(); if (ipv6_type == IPV6_DISABLED) return 1; if (is_lan_radv_on() != 1) return 1; i_dhcp6s_mode = get_lan_dhcp6s_mode(); i_adv_per = 60; adv_prefix = "::/64"; adv_rdnss = get_lan_addr6_host(rdns6s); if (!adv_rdnss) adv_rdnss = nvram_safe_get("wan0_dns6"); if (ipv6_type == IPV6_6TO4) { get_wan_ifname(wan_ifname); sprintf(addr6s, "0:0:0:%d::/%d", 1, 64); adv_prefix = addr6s; } else { lan_addr6_prefix = get_lan_addr6_prefix(addr6s); if (lan_addr6_prefix) adv_prefix = lan_addr6_prefix; } fp = fopen("/etc/radvd.conf", "w"); if (!fp) return -1; fprintf(fp, "interface %s {\n" " IgnoreIfMissing on;\n" " AdvSendAdvert on;\n" // (RA=ON) " AdvHomeAgentFlag off;\n" " AdvManagedFlag %s;\n" " AdvOtherConfigFlag %s;\n" " AdvDefaultLifetime %d;\n" " MaxRtrAdvInterval %d;\n", IFNAME_BR, (i_dhcp6s_mode > 1) ? "on" : "off", // (M=ON/OFF) (i_dhcp6s_mode > 0) ? "on" : "off", // (O=ON/OFF) 1800, i_adv_per ); fprintf(fp, " prefix %s {\n" " AdvOnLink on;\n" " AdvAutonomous %s;\n", adv_prefix, (i_dhcp6s_mode != 2) ? "on" : "off" // (Stateful only) ); if (ipv6_type == IPV6_6TO4) { fprintf(fp, " AdvValidLifetime %d;\n" " AdvPreferredLifetime %d;\n" " Base6to4Interface %s;\n", 600, 240, wan_ifname ); } fprintf(fp, " };\n"); if (*adv_rdnss) fprintf(fp, " RDNSS %s {};\n", adv_rdnss); fprintf(fp, "};\n"); fclose(fp); if (pids("radvd")) return doSystem("killall %s %s", "-SIGHUP", "radvd"); return eval("/usr/sbin/radvd"); }
/* Tc */ int start_iQos(void) { int i; char *buf, *g, *p; unsigned int rate; unsigned int ceil; unsigned int ibw, obw, bw; unsigned int mtu; FILE *f; int x; int inuse; char s[256]; int first; char burst_root[32]; char burst_leaf[32]; char *protocol; // judge interface by get_wan_ifname // add Qos iptable rules in mangle table, // move it to firewall - mangle_setting // add_iQosRules(get_wan_ifname(0)); // iptables start //wireless_tc(); /* Wireless tc */ if (!nvram_match("qos_enable", "1")) return -1; ibw = strtoul(nvram_safe_get("qos_ibw"), NULL, 10); obw = strtoul(nvram_safe_get("qos_obw"), NULL, 10); if(ibw==0||obw==0) return -1; if ((f = fopen(qosfn, "w")) == NULL) return -2; fprintf(stderr, "[qos] tc START!\n"); /* qos_burst */ i = atoi(nvram_safe_get("qos_burst0")); if (i > 0) sprintf(burst_root, "burst %dk", i); else burst_root[0] = 0; i = atoi(nvram_safe_get("qos_burst1")); if (i > 0) sprintf(burst_leaf, "burst %dk", i); else burst_leaf[0] = 0; /* Egress OBW -- set the HTB shaper (Classful Qdisc) * the BW is set here for each class */ mtu = strtoul(nvram_safe_get("wan_mtu"), NULL, 10); bw = obw; /* WAN */ fprintf(f, "#!/bin/sh\n" "#LAN/WAN\n" "I=%s\n" "SFQ=\"sfq perturb 10\"\n" "TQA=\"tc qdisc add dev $I\"\n" "TCA=\"tc class add dev $I\"\n" "TFA=\"tc filter add dev $I\"\n" "case \"$1\" in\n" "start)\n" "#LAN/WAN\n" "\ttc qdisc del dev $I root 2>/dev/null\n" "\t$TQA root handle 1: htb default %u\n" "# upload 1:1\n" "\t$TCA parent 1: classid 1:1 htb rate %ukbit ceil %ukbit %s\n", get_wan_ifname(0), // judge WAN interface (atoi(nvram_safe_get("qos_default")) + 1) * 10, bw, bw, burst_root); /* LAN protocol: 802.1q */ #ifndef RTCONFIG_RALINK // TODO: it is only for the case, eth0 as wan, vlanx as lan protocol = strdup("802.1q"); fprintf(f, "# download 1:2\n" "\t$TCA parent 1: classid 1:2 htb rate 1000000kbit ceil 1000000kbit burst 10000 cburst 10000\n" "# 1:60 ALL Download\n" "\t$TCA parent 1:2 classid 1:60 htb rate 1000000kbit ceil 1000000kbit burst 10000 cburst 10000 prio 6\n" "\t$TQA parent 1:60 handle 60: pfifo\n" "\t$TFA parent 1: prio 60 protocol %s handle 6 fw flowid 1:60\n", protocol ); #endif inuse = atoi(nvram_safe_get("qos_inuse")); g = buf = strdup(nvram_safe_get("qos_orates")); for (i = 0; i < 5; ++i) { // 0~4 , 0:highest, 4:lowest if ((!g) || ((p = strsep(&g, ",")) == NULL)) break; if ((inuse & (1 << i)) == 0){ fprintf(stderr, "[qos] egress %d doesn't create, inuse=%d\n", i, inuse ); continue; } else fprintf(stderr, "[qos] egress %d creates\n", i); if ((sscanf(p, "%u-%u", &rate, &ceil) != 2) || (rate < 1)) continue; if (ceil > 0) sprintf(s, "ceil %ukbit ", calc(bw, ceil)); else s[0] = 0; x = (i + 1) * 10; fprintf(f, "# egress %d: %u-%u%%\n" "\t$TCA parent 1:1 classid 1:%d htb rate %ukbit %s %s prio %d quantum %u\n" "\t$TQA parent 1:%d handle %d: $SFQ\n" "\t$TFA parent 1: prio %d protocol ip handle %d fw flowid 1:%d\n", i, rate, ceil, x, calc(bw, rate), s, burst_leaf, (i >= 6) ? 7 : (i + 1), mtu, x, x, x, i + 1, x); } free(buf); /* 10000 = ACK 00100 = RST 00010 = SYN 00001 = FIN */ if (nvram_match("qos_ack", "on")) { fprintf(f, "\n" "\t$TFA parent 1: prio 14 protocol ip u32 " "match ip protocol 6 0xff " // TCP "match u8 0x05 0x0f at 0 " // IP header length "match u16 0x0000 0xffc0 at 2 " // total length (0-63) "match u8 0x10 0xff at 33 " // ACK only "flowid 1:10\n"); } if (nvram_match("qos_syn", "on")) { fprintf(f, "\n" "\t$TFA parent 1: prio 15 protocol ip u32 " "match ip protocol 6 0xff " // TCP "match u8 0x05 0x0f at 0 " // IP header length "match u16 0x0000 0xffc0 at 2 " // total length (0-63) "match u8 0x02 0x02 at 33 " // SYN,* "flowid 1:10\n"); } if (nvram_match("qos_fin", "on")) { fprintf(f, "\n" "\t$TFA parent 1: prio 17 protocol ip u32 " "match ip protocol 6 0xff " // TCP "match u8 0x05 0x0f at 0 " // IP header length "match u16 0x0000 0xffc0 at 2 " // total length (0-63) "match u8 0x01 0x01 at 33 " // FIN,* "flowid 1:10\n"); } if (nvram_match("qos_rst", "on")) { fprintf(f, "\n" "\t$TFA parent 1: prio 19 protocol ip u32 " "match ip protocol 6 0xff " // TCP "match u8 0x05 0x0f at 0 " // IP header length "match u16 0x0000 0xffc0 at 2 " // total length (0-63) "match u8 0x04 0x04 at 33 " // RST,* "flowid 1:10\n"); } if (nvram_match("qos_icmp", "on")) { fputs("\n\t$TFA parent 1: prio 13 protocol ip u32 match ip protocol 1 0xff flowid 1:10\n", f); } // ingress first = 1; bw = ibw; if (bw > 0) { g = buf = strdup(nvram_safe_get("qos_irates")); for (i = 0; i < 5; ++i) { // 0~4 , 0:highest, 4:lowest if ((!g) || ((p = strsep(&g, ",")) == NULL)) break; if ((inuse & (1 << i)) == 0) continue; if ((rate = atoi(p)) < 1) continue; // 0 = off if (first) { first = 0; fprintf(f, "\n" "\ttc qdisc del dev $I ingress 2>/dev/null\n" "\t$TQA handle ffff: ingress\n"); } // rate in kb/s unsigned int u = calc(bw, rate); // burst rate unsigned int v = u / 25; if (v < 50) v = 50; x = i + 1; fprintf(f, "# ingress %d: %u%%\n" "\t$TFA parent ffff: prio %d protocol ip handle %d" " fw police rate %ukbit burst %ukbit drop flowid ffff:%d\n", i, rate, x, x, u, v, x); } } free(buf); fputs( "\t;;\n" "stop)\n" "\ttc qdisc del dev $I root 2>/dev/null\n" "\ttc qdisc del dev $I ingress 2>/dev/null\n" "\t;;\n" "*)\n" "\ttc -s -d class ls dev $I\n" "\techo\n" "\ttc -s -d qdisc ls dev $I\n" "esac\n", f); fclose(f); chmod(qosfn, 0700); eval((char *)qosfn, "start"); fprintf(stderr,"[qos] tc done!\n"); }
static int start_bandwidth_limiter(void) { FILE *f = NULL; char *buf, *g, *p; char *enable, *addr, *dlc, *upc, *prio; int class = 0; int s[6]; // strip mac address int addr_type; char addr_new[30]; if ((f = fopen(qosfn, "w")) == NULL) return -2; fprintf(f, "#!/bin/sh\n" "WAN=%s\n" "tc qdisc del dev $WAN root 2>/dev/null\n" "tc qdisc del dev $WAN ingress 2>/dev/null\n" "tc qdisc del dev br0 root 2>/dev/null\n" "tc qdisc del dev br0 ingress 2>/dev/null\n" "\n" "TQAU=\"tc qdisc add dev $WAN\"\n" "TCAU=\"tc class add dev $WAN\"\n" "TFAU=\"tc filter add dev $WAN\"\n" "SFQ=\"sfq perturb 10\"\n" "TQA=\"tc qdisc add dev br0\"\n" "TCA=\"tc class add dev br0\"\n" "TFA=\"tc filter add dev br0\"\n" "\n" "$TQA root handle 1: htb\n" "$TCA parent 1: classid 1:1 htb rate 1024000kbit\n" "\n" "$TQAU root handle 2: htb\n" "$TCAU parent 2: classid 2:1 htb rate 1024000kbit\n" , get_wan_ifname(0) ); /* ASUSWRT qos_bw_rulelist : enable>addr>DL-Ceil>UL-Ceil>prio enable : enable or disable this rule addr : (source) IP or MAC or IP-range DL-Ceil : the max download bandwidth UL-Ceil : the max upload bandwidth prio : priority for client */ g = buf = strdup(nvram_safe_get("qos_bw_rulelist")); while (g) { if ((p = strsep(&g, "<")) == NULL) break; if ((vstrsep(p, ">", &enable, &addr, &dlc, &upc, &prio)) != 5) continue; if (!strcmp(enable, "0")) continue; address_checker(&addr_type, addr, addr_new); class = atoi(prio) + 10; if (addr_type == TYPE_MAC) { sscanf(addr_new, "%02X:%02X:%02X:%02X:%02X:%02X",&s[0],&s[1],&s[2],&s[3],&s[4],&s[5]); fprintf(f, "\n" "$TCA parent 1:1 classid 1:%d htb rate %skbit ceil %skbit prio %s\n" "$TQA parent 1:%d handle %d: $SFQ\n" "$TFA parent 1: protocol ip prio %s u32 match u16 0x0800 0xFFFF at -2 match u32 0x%02X%02X%02X%02X 0xFFFFFFFF at -12 match u16 0x%02X%02X 0xFFFF at -14 flowid 1:%d" "\n" "$TCAU parent 2:1 classid 2:%d htb rate %skbit ceil %skbit prio %s\n" "$TQAU parent 2:%d handle %d: $SFQ\n" "$TFAU parent 2: prio %s protocol ip handle %d fw flowid 2:%d\n" , class, dlc, dlc, prio , class, class , prio, s[2], s[3], s[4], s[5], s[0], s[1], class , class, upc, upc, prio , class, class , prio, class, class ); } else if (addr_type == TYPE_IP || addr_type == TYPE_IPRANGE)
// used for various testing static int rctest_main(int argc, char *argv[]) { int on; if (argc < 3) { _dprintf("test what?\n"); } else if (strcmp(argv[1], "rc_service")==0) { notify_rc(argv[2]); } else if(strcmp(argv[1], "get_phy_status")==0) { int mask; mask = atoi(argv[2]); TRACE_PT("debug for phy_status %x\n", get_phy_status(mask)); } else if(strcmp(argv[1], "get_phy_speed")==0) { int mask; mask = atoi(argv[2]); TRACE_PT("debug for phy_speed %x\n", get_phy_speed(mask)); } else if(strcmp(argv[1], "set_phy_ctrl")==0) { int mask, ctrl; mask = atoi(argv[2]); ctrl = atoi(argv[3]); TRACE_PT("debug for phy_speed %x\n", set_phy_ctrl(mask, ctrl)); } else if(strcmp(argv[1], "handle_notifications")==0) { handle_notifications(); } else if(strcmp(argv[1], "check_action")==0) { _dprintf("check: %d\n", check_action()); } else if(strcmp(argv[1], "nvramhex")==0) { int i; char *nv; nv = nvram_safe_get(argv[2]); _dprintf("nvram %s(%d): ", nv, strlen(nv)); for(i=0;i<strlen(nv);i++) { _dprintf(" %x", (unsigned char)*(nv+i)); } _dprintf("\n"); } else { on = atoi(argv[2]); _dprintf("%s %d\n", argv[1], on); if (strcmp(argv[1], "vlan") == 0) { if(on) start_vlan(); else stop_vlan(); } else if (strcmp(argv[1], "lan") == 0) { if(on) start_lan(); else stop_lan(); } else if (strcmp(argv[1], "wl") == 0) { if(on) { start_wl(); lanaccess_wl(); } } else if (strcmp(argv[1], "wan") == 0) { if(on) start_wan(); else stop_wan(); } else if (strcmp(argv[1], "firewall") == 0) { //if(on) start_firewall(); //else stop_firewall(); } else if (strcmp(argv[1], "watchdog") == 0) { if(on) start_watchdog(); else stop_watchdog(); } #ifdef RTCONFIG_FANCTRL else if (strcmp(argv[1], "phy_tempsense") == 0) { if(on) start_phy_tempsense(); else stop_phy_tempsense(); } #endif #ifdef RTCONFIG_BCMWL6 #ifdef RTCONFIG_PROXYSTA else if (strcmp(argv[1], "psta_monitor") == 0) { if(on) start_psta_monitor(); else stop_psta_monitor(); } #endif #endif else if (strcmp(argv[1], "qos") == 0) {//qos test if(on){ #ifdef RTCONFIG_RALINK if (module_loaded("hw_nat")) { modprobe_r("hw_nat"); sleep(1); #if 0 system("echo 0 > /proc/sys/net/ipv4/conf/default/force_igmp_version"); system("echo 0 > /proc/sys/net/ipv4/conf/all/force_igmp_version"); #endif } #endif add_iQosRules(get_wan_ifname(0)); start_iQos(); } else { #ifdef RTCONFIG_RALINK if (nvram_get_int("hwnat") && /* TODO: consider RTCONFIG_DUALWAN case */ // !nvram_match("wan0_proto", "l2tp") && // !nvram_match("wan0_proto", "pptp") && // !(nvram_get_int("fw_pt_l2tp") || nvram_get_int("fw_pt_ipsec") && // (nvram_match("wl0_radio", "0") || nvram_get_int("wl0_mrate_x")) && // (nvram_match("wl1_radio", "0") || nvram_get_int("wl1_mrate_x")) && !module_loaded("hw_nat")) { #if 0 system("echo 2 > /proc/sys/net/ipv4/conf/default/force_igmp_version"); system("echo 2 > /proc/sys/net/ipv4/conf/all/force_igmp_version"); #endif modprobe("hw_nat"); sleep(1); } #endif stop_iQos(); del_iQosRules(); } } #ifdef RTCONFIG_WEBDAV else if (strcmp(argv[1], "webdav") == 0) { if(on) start_webdav(); } #endif else if (strcmp(argv[1], "gpiow") == 0) { if(argc>=4) set_gpio(atoi(argv[2]), atoi(argv[3])); } else if (strcmp(argv[1], "gpior") == 0) { _dprintf("%d\n", get_gpio(atoi(argv[2]))); } else if (strcmp(argv[1], "gpiod") == 0) { if(argc>=4) gpio_dir(atoi(argv[2]), atoi(argv[3])); } else if (strcmp(argv[1], "init_switch") == 0) { init_switch(on); } else if (strcmp(argv[1], "set_action") == 0) { set_action(on); } else if (strcmp(argv[1], "pwr_usb") == 0) { set_pwr_usb(atoi(argv[2])); _dprintf("done.\n"); } else { printf("what?\n"); } } return 0; }
// used for various testing static int rctest_main(int argc, char *argv[]) { int on; if (argc < 2) { _dprintf("test what?\n"); } else if (strcmp(argv[1], "rc_service")==0) { notify_rc(argv[2]); } else if(strcmp(argv[1], "get_phy_status")==0) { int mask; mask = atoi(argv[2]); TRACE_PT("debug for phy_status %x\n", get_phy_status(mask)); } else if(strcmp(argv[1], "get_phy_speed")==0) { int mask; mask = atoi(argv[2]); TRACE_PT("debug for phy_speed %x\n", get_phy_speed(mask)); } else if(strcmp(argv[1], "set_phy_ctrl")==0) { int mask, ctrl; mask = atoi(argv[2]); ctrl = atoi(argv[3]); TRACE_PT("debug for phy_speed %x\n", set_phy_ctrl(mask, ctrl)); } else if(strcmp(argv[1], "handle_notifications")==0) { handle_notifications(); } else if(strcmp(argv[1], "check_action")==0) { _dprintf("check: %d\n", check_action()); } else if(strcmp(argv[1], "nvramhex")==0) { int i; char *nv; nv = nvram_safe_get(argv[2]); _dprintf("nvram %s(%d): ", nv, strlen(nv)); for(i=0;i<strlen(nv);i++) { _dprintf(" %x", (unsigned char)*(nv+i)); } _dprintf("\n"); } else { on = atoi(argv[2]); _dprintf("%s %d\n", argv[1], on); if (strcmp(argv[1], "vlan") == 0) { if(on) start_vlan(); else stop_vlan(); } else if (strcmp(argv[1], "lan") == 0) { if(on) start_lan(); else stop_lan(); } else if (strcmp(argv[1], "wl") == 0) { if(on) { start_wl(); lanaccess_wl(); } } else if (strcmp(argv[1], "wan") == 0) { if(on) start_wan(); else stop_wan(); } else if (strcmp(argv[1], "wan_port") == 0) { if(on) start_wan_port(); else stop_wan_port(); } else if (strcmp(argv[1], "firewall") == 0) { //if(on) start_firewall(); //else stop_firewall(); } else if (strcmp(argv[1], "watchdog") == 0) { if(on) start_watchdog(); else stop_watchdog(); } #if ! (defined(RTCONFIG_QCA) || defined(RTCONFIG_RALINK)) else if (strcmp(argv[1], "watchdog02") == 0) { if(on) start_watchdog02(); else stop_watchdog02(); } #endif /* ! (RTCONFIG_QCA || RTCONFIG_RALINK) */ else if (strcmp(argv[1], "sw_devled") == 0) { if(on) start_sw_devled(); else stop_sw_devled(); } #ifdef RTCONFIG_FANCTRL else if (strcmp(argv[1], "phy_tempsense") == 0) { if(on) start_phy_tempsense(); else stop_phy_tempsense(); } #endif #ifdef RTCONFIG_BCMWL6 #ifdef RTCONFIG_PROXYSTA else if (strcmp(argv[1], "psta_monitor") == 0) { if(on) start_psta_monitor(); else stop_psta_monitor(); } #endif #endif #ifdef RTCONFIG_IPERF else if (strcmp(argv[1], "monitor") == 0) { if(on) start_monitor(); else stop_monitor(); } #endif else if (strcmp(argv[1], "qos") == 0) {//qos test if(on){ #ifdef RTCONFIG_RALINK if (module_loaded("hw_nat")) { modprobe_r("hw_nat"); sleep(1); #if 0 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "0", 0, 0); f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "0", 0, 0); #endif } #endif add_iQosRules(get_wan_ifname(wan_primary_ifunit())); #ifdef RTCONFIG_BWDPI if(nvram_get_int("qos_type") == 1) { start_dpi_engine_service(); // force to rebuild firewall to avoid some loopback issue if (nvram_match("fw_nat_loopback", "2")) start_firewall(wan_primary_ifunit(), 0); } else #endif start_iQos(); } else { #ifdef RTCONFIG_RALINK if (nvram_get_int("hwnat") && /* TODO: consider RTCONFIG_DUALWAN case */ // !nvram_match("wan0_proto", "l2tp") && // !nvram_match("wan0_proto", "pptp") && // !(nvram_get_int("fw_pt_l2tp") || nvram_get_int("fw_pt_ipsec") && // (nvram_match("wl0_radio", "0") || nvram_get_int("wl0_mrate_x")) && // (nvram_match("wl1_radio", "0") || nvram_get_int("wl1_mrate_x")) && !module_loaded("hw_nat")) { #if 0 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0); f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0); #endif #if defined(RTN14U) || defined(RTAC52U) || defined(RTAC51U) || defined(RTN11P) || defined(RTN300) || defined(RTN54U) || defined(RTAC1200HP) || defined(RTN56UB1) || defined(RTAC54U) || defined(RTN56UB2) if (!(!nvram_match("switch_wantag", "none")&&!nvram_match("switch_wantag", ""))) #endif { modprobe("hw_nat"); sleep(1); } } #endif #ifdef RTCONFIG_BWDPI if(nvram_get_int("qos_type") == 1){ stop_dpi_engine_service(1); } else #endif stop_iQos(); del_iQosRules(); } } #ifdef RTCONFIG_WEBDAV else if (strcmp(argv[1], "webdav") == 0) { if(on) start_webdav(); } #endif #ifdef RTCONFIG_TUNNEL else if (strcmp(argv[1], "mastiff") == 0) { if(on) start_mastiff(); } #endif else if (strcmp(argv[1], "gpiow") == 0) { if(argc>=4) set_gpio(atoi(argv[2]), atoi(argv[3])); } else if (strcmp(argv[1], "gpior") == 0) { printf("%d\n", get_gpio(atoi(argv[2]))); } else if (strcmp(argv[1], "gpiod") == 0) { if(argc>=4) gpio_dir(atoi(argv[2]), atoi(argv[3])); } else if (strcmp(argv[1], "init_switch") == 0) { init_switch(); } else if (strcmp(argv[1], "set_action") == 0) { set_action(on); } else if (strcmp(argv[1], "pwr_usb") == 0) { set_pwr_usb(atoi(argv[2])); _dprintf("done.\n"); } else if (strcmp(argv[1], "enc_chk") == 0) { unsigned char enc_buf[ENC_WORDS_LEN]; unsigned char dec_buf[DATA_WORDS_LEN + 1]; _dprintf("get enc str:[%s]\n", enc_str(argv[2], (char *) enc_buf)); _dprintf("get dec str:[%s]\n", dec_str((char *) enc_buf, (char *) dec_buf)); _dprintf("done(%d)\n", strcmp(argv[2], (const char *) dec_buf)); } #ifdef RTCONFIG_BCMFA else if (strcmp(argv[1], "fa_rev") == 0) { _dprintf("(%d) done.\n", get_fa_rev()); } else if (strcmp(argv[1], "fa_dump") == 0) { _dprintf("(%d) done.\n", get_fa_dump()); } #endif else { printf("what?\n"); } } return 0; }