int main(int argc, char **argv) { struct sockaddr sa; char host[128]; struct aftype *ap; struct hwtype *hw; struct ifreq ifr; int goterr = 0, didnetmask = 0; char **spp; int fd; #if HAVE_AFINET6 extern struct aftype inet6_aftype; struct sockaddr_in6 sa6; struct in6_ifreq ifr6; unsigned long prefix_len; char *cp; #endif #if I18N bindtextdomain("net-tools", "/usr/share/locale"); textdomain("net-tools"); #endif /* Create a channel to the NET kernel. */ if ((skfd = sockets_open(0)) < 0) { perror("socket"); exit(1); } /* Find any options. */ argc--; argv++; while (argc && *argv[0] == '-') { if (!strcmp(*argv, "-a")) opt_a = 1; if (!strcmp(*argv, "-v")) opt_v = 1; if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") || !strcmp(*argv, "--version")) version(); if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") || !strcmp(*argv, "-help") || !strcmp(*argv, "--help")) usage(); argv++; argc--; } /* Do we have to show the current setup? */ if (argc == 0) { int err = if_print((char *) NULL); (void) close(skfd); exit(err < 0); } /* No. Fetch the interface name. */ spp = argv; safe_strncpy(ifr.ifr_name, *spp++, IFNAMSIZ); if (*spp == (char *) NULL) { int err = if_print(ifr.ifr_name); (void) close(skfd); exit(err < 0); } /* The next argument is either an address family name, or an option. */ if ((ap = get_aftype(*spp)) == NULL) ap = get_aftype(DFLT_AF); else { /* XXX: should print the current setup if no args left, but only for this family */ spp++; addr_family = ap->af; } if (sockets_open(addr_family) < 0) { perror("family socket"); exit(1); } /* Process the remaining arguments. */ while (*spp != (char *) NULL) { if (!strcmp(*spp, "arp")) { goterr |= clr_flag(ifr.ifr_name, IFF_NOARP); spp++; continue; } if (!strcmp(*spp, "-arp")) { goterr |= set_flag(ifr.ifr_name, IFF_NOARP); spp++; continue; } #ifdef IFF_PORTSEL if (!strcmp(*spp, "media") || !strcmp(*spp, "port")) { if (*++spp == NULL) usage(); if (!strcasecmp(*spp, "auto")) { goterr |= set_flag(ifr.ifr_name, IFF_AUTOMEDIA); } else { int i, j, newport; char *endp; newport = strtol(*spp, &endp, 10); if (*endp != 0) { newport = -1; for (i = 0; if_port_text[i][0] && newport == -1; i++) { for (j = 0; if_port_text[i][j]; j++) { if (!strcasecmp(*spp, if_port_text[i][j])) { newport = i; break; } } } } spp++; if (newport == -1) { fprintf(stderr, _("Unknown media type.\n")); goterr = 1; } else { if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { goterr = 1; continue; } ifr.ifr_map.port = newport; if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { perror("SIOCSIFMAP"); goterr = 1; } } } continue; } #endif if (!strcmp(*spp, "trailers")) { goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS); spp++; continue; } if (!strcmp(*spp, "-trailers")) { goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS); spp++; continue; } if (!strcmp(*spp, "promisc")) { goterr |= set_flag(ifr.ifr_name, IFF_PROMISC); spp++; continue; } if (!strcmp(*spp, "-promisc")) { goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC); spp++; continue; } if (!strcmp(*spp, "multicast")) { goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST); spp++; continue; } if (!strcmp(*spp, "-multicast")) { goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST); spp++; continue; } if (!strcmp(*spp, "allmulti")) { goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI); spp++; continue; } if (!strcmp(*spp, "-allmulti")) { goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI); spp++; continue; } if (!strcmp(*spp, "up")) { goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); spp++; continue; } if (!strcmp(*spp, "down")) { goterr |= clr_flag(ifr.ifr_name, IFF_UP); spp++; continue; } #ifdef HAVE_DYNAMIC if (!strcmp(*spp, "dynamic")) { goterr |= set_flag(ifr.ifr_name, IFF_DYNAMIC); spp++; continue; } if (!strcmp(*spp, "-dynamic")) { goterr |= clr_flag(ifr.ifr_name, IFF_DYNAMIC); spp++; continue; } #endif if (!strcmp(*spp, "metric")) { if (*++spp == NULL) usage(); ifr.ifr_metric = atoi(*spp); if (ioctl(skfd, SIOCSIFMETRIC, &ifr) < 0) { fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "mtu")) { if (*++spp == NULL) usage(); ifr.ifr_mtu = atoi(*spp); if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) { fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #ifdef SIOCSKEEPALIVE if (!strcmp(*spp, "keepalive")) { if (*++spp == NULL) usage(); ifr.ifr_data = (caddr_t) atoi(*spp); if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) { fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif #ifdef SIOCSOUTFILL if (!strcmp(*spp, "outfill")) { if (*++spp == NULL) usage(); ifr.ifr_data = (caddr_t) atoi(*spp); if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) { fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif if (!strcmp(*spp, "-broadcast")) { goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST); spp++; continue; } if (!strcmp(*spp, "broadcast")) { if (*++spp != NULL) { safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { ap->herror(host); goterr = 1; spp++; continue; } memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFBRDADDR: %s\n", strerror(errno)); goterr = 1; } spp++; } goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST); continue; } if (!strcmp(*spp, "dstaddr")) { if (*++spp == NULL) usage(); safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { ap->herror(host); goterr = 1; spp++; continue; } memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFDSTADDR: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "netmask")) { if (*++spp == NULL || didnetmask) usage(); safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { ap->herror(host); goterr = 1; spp++; continue; } didnetmask++; goterr = set_netmask(ap->fd, &ifr, &sa); spp++; continue; } #ifdef HAVE_TXQUEUELEN if (!strcmp(*spp, "txqueuelen")) { if (*++spp == NULL) usage(); ifr.ifr_qlen = strtoul(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFTXQLEN, &ifr) < 0) { fprintf(stderr, "SIOCSIFTXQLEN: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif if (!strcmp(*spp, "mem_start")) { if (*++spp == NULL) usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { goterr = 1; continue; } ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "io_addr")) { if (*++spp == NULL) usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { goterr = 1; continue; } ifr.ifr_map.base_addr = strtol(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "irq")) { if (*++spp == NULL) usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { goterr = 1; continue; } ifr.ifr_map.irq = atoi(*spp); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "-pointopoint")) { goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT); spp++; continue; } if (!strcmp(*spp, "pointopoint")) { if (*(spp + 1) != NULL) { spp++; safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa)) { ap->herror(host); goterr = 1; spp++; continue; } memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFDSTADDR: %s\n", strerror(errno)); goterr = 1; } } goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT); spp++; continue; }; if (!strcmp(*spp, "hw")) { if (*++spp == NULL) usage(); if ((hw = get_hwtype(*spp)) == NULL) usage(); if (*++spp == NULL) usage(); safe_strncpy(host, *spp, (sizeof host)); if (hw->input(host, &sa) < 0) { fprintf(stderr, _("%s: invalid %s address.\n"), host, hw->name); goterr = 1; spp++; continue; } memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFHWADDR: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #if HAVE_AFINET6 if (!strcmp(*spp, "add")) { if (*++spp == NULL) usage(); if ((cp = strchr(*spp, '/'))) { prefix_len = atol(cp + 1); if ((prefix_len < 0) || (prefix_len > 128)) usage(); *cp = 0; } else { prefix_len = 0; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { inet6_aftype.herror(host); goterr = 1; spp++; continue; } memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr)); fd = get_socket_for_af(AF_INET6); if (fd < 0) { fprintf(stderr, _("No support for INET6 on this system.\n")); goterr = 1; spp++; continue; } if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); goterr = 1; spp++; continue; } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) { perror("SIOCSIFADDR"); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "del")) { if (*++spp == NULL) usage(); if ((cp = strchr(*spp, '/'))) { prefix_len = atol(cp + 1); if ((prefix_len < 0) || (prefix_len > 128)) usage(); *cp = 0; } else { prefix_len = 0; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { inet6_aftype.herror(host); goterr = 1; spp++; continue; } memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr)); fd = get_socket_for_af(AF_INET6); if (fd < 0) { fprintf(stderr, _("No support for INET6 on this system.\n")); goterr = 1; spp++; continue; } if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); goterr = 1; spp++; continue; } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; #ifdef SIOCDIFADDR if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) { fprintf(stderr, "SIOCDIFADDR: %s\n", strerror(errno)); goterr = 1; } #else fprintf(stderr, _("Address deletion not supported on this system.\n")); #endif spp++; continue; } if (!strcmp(*spp, "tunnel")) { if (*++spp == NULL) usage(); if ((cp = strchr(*spp, '/'))) { prefix_len = atol(cp + 1); if ((prefix_len < 0) || (prefix_len > 128)) usage(); *cp = 0; } else { prefix_len = 0; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { inet6_aftype.herror(host); goterr = 1; spp++; continue; } memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr)); fd = get_socket_for_af(AF_INET6); if (fd < 0) { fprintf(stderr, _("No support for INET6 on this system.\n")); goterr = 1; spp++; continue; } if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); goterr = 1; spp++; continue; } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) { fprintf(stderr, "SIOCSIFDSTADDR: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif /* If the next argument is a valid hostname, assume OK. */ safe_strncpy(host, *spp, (sizeof host)); /* FIXME: sa is too small for INET6 addresses, inet6 should use that too, broadcast is unexpected */ if (ap->getmask) { switch (ap->getmask(host, &sa, NULL)) { case -1: usage(); break; case 1: if (didnetmask) usage(); goterr = set_netmask(skfd, &ifr, &sa); didnetmask++; break; } } if (ap->input(0, host, &sa) < 0) { ap->herror(host); usage(); } memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr)); { int r = 0; /* to shut gcc up */ switch (ap->af) { #if HAVE_AFINET case AF_INET: fd = get_socket_for_af(AF_INET); if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); exit(1); } r = ioctl(fd, SIOCSIFADDR, &ifr); break; #endif #if HAVE_AFECONET case AF_ECONET: fd = get_socket_for_af(AF_ECONET); if (fd < 0) { fprintf(stderr, _("No support for ECONET on this system.\n")); exit(1); } r = ioctl(fd, SIOCSIFADDR, &ifr); break; #endif default: fprintf(stderr, _("Don't know how to set addresses for family %d.\n"), ap->af); exit(1); } if (r < 0) { perror("SIOCSIFADDR"); goterr = 1; } } /* * Don't do the set_flag() if the address is an alias with a - at the * end, since it's deleted already! - Roman * * Should really use regex.h here, not sure though how well it'll go * with the cross-platform support etc. */ { char *ptr; short int found_colon = 0; for (ptr = ifr.ifr_name; *ptr; ptr++ ) if (*ptr == ':') found_colon++; if (!(found_colon && *(ptr - 1) == '-')) goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); } spp++; } return (goterr); }
int load_font_textures () { #ifndef NEW_TEXTURES int poor_man_save=poor_man; int use_mipmaps_save=use_mipmaps; #endif /* NEW_TEXTURES */ size_t i = 0; char *glob_pattern; #ifdef WINDOWS struct _finddata_t c_file; long hFile; #else //WINDOWS int ret; glob_t glob_res; size_t j; #endif //WINDOWS char file[60] = ""; char str[60] = ""; if (fonts[0] == NULL || fonts[1] == NULL || fonts[2] == NULL || fonts[3]==NULL ) { for (i = 0; i < FONTS_ARRAY_SIZE; i++) { if (fonts[i] != NULL) free (fonts[i]); fonts[i] = NULL; } if ( !init_fonts () ) return 0; } #ifndef NEW_TEXTURES poor_man=0; use_mipmaps=0; #endif /* NEW_TEXTURES */ #ifdef NEW_TEXTURES fonts[0]->texture_id = load_texture_cached("textures/font.dds", tt_font); #else /* NEW_TEXTURES */ fonts[0]->texture_id = load_texture_cache("./textures/font.bmp", 0); #endif /* NEW_TEXTURES */ i = 1; // Force the selection of the base font. add_multi_option("chat_font", "Type 1"); add_multi_option("name_font", "Type 1"); // Find what font's exist and load them glob_pattern = malloc(strlen(datadir)+sizeof(texture_dir)+10+1); //+10 = font*.bmp* #ifdef NEW_TEXTURES sprintf(glob_pattern, "%s%sfont*.dds", datadir, texture_dir); #else /* NEW_TEXTURES */ sprintf(glob_pattern, "%s%sfont*.bmp*", datadir, texture_dir); #endif /* NEW_TEXTURES */ #ifdef WINDOWS if( (hFile = _findfirst( glob_pattern, &c_file )) == -1L ){ free(glob_pattern); return 0; } do { int len; safe_strncpy(file, c_file.name, sizeof(file)); #else //!WINDOWS ret = glob(glob_pattern, 0, NULL, &glob_res); if(ret != 0) { LOG_ERROR("Unable to find any font textures\n"); free(glob_pattern); return 0; } j = 0; while (j < glob_res.gl_pathc && i < FONTS_ARRAY_SIZE) { int len; safe_strncpy(file, glob_res.gl_pathv[j]+sizeof(texture_dir)-1+strlen(datadir), sizeof(file)); #endif //WINDOWS len= strlen(file); #ifdef NEW_TEXTURES if (((len + sizeof(texture_dir) - 1) < sizeof(str)) && !strncasecmp(file, "font", 4) && has_suffix(file, len, ".dds", 4)) { safe_snprintf(str, sizeof(str), "./textures/%s", file); //Use a relative path here, load_texture_cache_deferred() is using the path wrappers. file[len - 4] = 0; fonts[i]->texture_id = load_texture_cached(str, tt_font); #else /* NEW_TEXTURES */ if (len+sizeof(texture_dir)-1 < sizeof(str) && !strncasecmp(file, "font", 4) && (has_suffix(file, len, ".bmp", 4) || has_suffix(file, len, ".bmp.gz", 7)) && (!has_suffix(file, len, "_alpha.bmp", 10)) && (!has_suffix(file, len, "_alpha.bmp.gz", 13))) { // Get the filename, remove the .bmp and add _alpha.bmp to a copy, then replace the .bmp safe_snprintf(str, sizeof(str), "./textures/%s", file); //Use a relative path here, load_texture_cache_deferred() is using the path wrappers. if(has_suffix(file, len, ".bmp.gz", 7)){ file[len - 7]= 0; } else { file[len - 4]= 0; } fonts[i]->texture_id = load_texture_cache_deferred(str, 0); #endif /* NEW_TEXTURES */ safe_snprintf(font_names[i], sizeof(font_names[i]), "Type %i - %s", i + 1, file); add_multi_option("chat_font", font_names[i]); add_multi_option("name_font", font_names[i]); i++; } #ifndef WINDOWS j++; #endif //WINDOWS } #ifdef WINDOWS while ( _findnext( hFile, &c_file ) == 0 ); _findclose( hFile ); #else //!WINDOWS globfree(&glob_res); #endif //WINDOWS free(glob_pattern); #ifndef NEW_TEXTURES poor_man=poor_man_save; use_mipmaps=use_mipmaps_save; #endif /* NEW_TEXTURES */ //set the default font cur_font_num = 0; font_text = fonts[0]->texture_id; return 1; } int set_font_parameters (int num) { int i; // error checking if(num < 0 || num >= FONTS_ARRAY_SIZE) { return -1; } // allocate space if needed if(fonts[num] == NULL) { fonts[num]=(font_info *)calloc(1, sizeof(font_info)); if(fonts[num] == NULL) { LOG_ERROR(cant_load_font); return -1; } } //watch the highest font if(num >= max_fonts) { max_fonts=num+1; } // set default font info my_strcp (fonts[num]->name, "default"); fonts[num]->spacing=0; // load font information // TODO: write this and remove the hack! if(num!=1||num!=2)for(i=0; i<FONTS_ARRAY_SIZE*FONT_CHARS_PER_LINE; i++) fonts[num]->widths[i]=12; if(num==1){ static int widths[]={ 4,2,7,11,8,12,12,2,7,7,9,10,3,8, 2,10,10,10,8,8,10,7,9,9,9,9,3,3, 10,10,10,9,12,12,9,10,10,9,9,10,9,8, 7,11,8,11,10,11,9,11,11,9,10,9,12,12, 12,12,10,6,10,6,10,12,3,11,9,9,9,9, 8,9,9,4,6,10,4,11,9,10,9,9,8,8, 8,9,10,12,10,10,9,8,2,8,10,8,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, }; memcpy(fonts[num]->widths, widths, sizeof(widths)); fonts[num]->spacing=4; } if(num==2){ static int widths[]={ 8, 8, 8, 10, 8, 10, 10, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 8, 12, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 10, 8, 10, 10, 8, 10, 8, 8, 8, 10, 10, 10, 8, 10, 10, 8, 8, 8, 12, 12, 12, 10, 10, 12, 10, 12, 12, 12, }; memcpy(fonts[num]->widths, widths, sizeof(widths)); fonts[num]->spacing=2; } //and return return num; } int set_font(int num) { if(num >= 0 && num < max_fonts && fonts[num] && fonts[num]->texture_id >= 0) { cur_font_num=num; font_text=fonts[cur_font_num]->texture_id; } return cur_font_num; }
void add_to_netq(unsigned long ip, unsigned short port, int rating, int replace) { if (rating > 100) rating=100; if (rating < 0) rating=0; if (ip == ((unsigned long) -1) || ip == 0L) { return; } struct in_addr in; in.s_addr=ip; char *t=inet_ntoa(in); if (!port) port=CONFIG_port_DEFAULT; if (t && ip != ((unsigned long) -1) && ip) { char host[256]; safe_strncpy(host,t,sizeof(host)); if (is_accessable_addr(ip) && allowIP(ip)) { sprintf(host+strlen(host),":%d",port); int x; int nh=g_lvnetcons.GetCount(); int bestpos=-1; int lastrat=-1; for (x = 0; x < nh; x ++) { char text[256]; text[0]=0; g_lvnetcons.GetText(x,2,text,sizeof(text)); int rat=atoi(text); if (rating > rat && bestpos < 0) bestpos=x; text[0]=0; g_lvnetcons.GetText(x,1,text,sizeof(text)); if (!stricmp(text,host)) { if (g_lvnetcons.GetParam(x)) return; char rat[32]; g_lvnetcons.GetText(x,2,rat,sizeof(rat)); int irat=atoi(rat); if (irat < rating) { if (irat < 50) rating = irat+1; else rating=irat; }; if (!replace && rating < lastrat) { sprintf(rat,"%d",rating); g_lvnetcons.SetItemText(x,2,rat); return; }; g_lvnetcons.DeleteItem(x--); nh--; break; }; lastrat=rat; }; if (bestpos < 0) bestpos=nh; char buf[32]; sprintf(buf,"%d",rating); g_lvnetcons.InsertItem(bestpos,"",0); g_lvnetcons.SetItemText(bestpos,1,host); g_lvnetcons.SetItemText(bestpos,2,buf); }; }; }
int ExecuteMacro(char *argv, int namelength) { RXSTRING rxRc; RXSTRING rxArg[2]; int rxArgCount = 0; char pszName[CCHMAXPATH]; char *rxArgStr; short sRc; long rc; if (namelength >= sizeof(pszName)) return 1; /* FIXME HBB 20010121: 3rd argument doesn't make sense. Either * this should be sizeof(pszName), or it shouldn't use * safe_strncpy(), here */ safe_strncpy(pszName, argv, namelength + 1); rxArgStr = &argv[namelength]; RXSTRPTR(rxRc) = NULL; #if 0 /* C-like calling of function: program name is first parameter. In REXX you would have to use Parse Arg param0, param1 to get the program name in param0 and the arguments in param1. Some versions before gnuplot 3.7pl1 used a similar approach but passed program name and arguments in a single string: (==> Parse Arg param0 param1) */ MAKERXSTRING(rxArg[0], pszName, strlen(pszName)); rxArgCount++; if (*rxArgStr) { MAKERXSTRING(rxArg[1], rxArgStr, strlen(rxArgStr)); rxArgCount++; } #else /* REXX standard calling (gnuplot 3.7pl1 and above): The program name is not supplied and so all actual arguments are in a single string: Parse Arg param We even handle blanks like cmd.exe when calling REXX programs. */ if (*rxArgStr) { MAKERXSTRING(rxArg[0], rxArgStr, strlen(rxArgStr)); rxArgCount++; } #endif CallFromRexx = TRUE; rc = RexxStart( rxArgCount, rxArg, pszName, NULL, "GNUPLOT", RXCOMMAND, NULL, &sRc, &rxRc); CallFromRexx = FALSE; /* am: a word WRT errors codes: the negative ones don't seem to have symbolic names, you can get them from the OREXX reference, they're not in REXX Programming Guide - no idea where to retrieve them from a Warp 3 reference ?? The positive ones are somehow referenced in REXXPG */ if (rc < 0) { /* REXX error */ } else if (rc > 0) { /* Interpreter couldn't be started */ if (rc == -4) /* run was cancelled, but don't give error message */ rc = 0; } else if (rc==0) { /* all was fine */ } /* We don't we try to use rxRc ? BTW, don't use free() instead since it's allocated inside RexxStart() and not in our executable using the EMX libraries */ if (RXSTRPTR(rxRc)) /* I guess it's NULL if something major went wrong, NULL strings are usually not part of the REXX language ... */ DosFreeMem(rxRc.strptr); return rc; }
int ifconfig_main(int argc, char **argv) { struct ifreq ifr; struct sockaddr_in sai; #ifdef CONFIG_FEATURE_IPV6 struct sockaddr_in6 sai6; #endif #ifdef CONFIG_FEATURE_IFCONFIG_HW struct sockaddr sa; #endif const struct arg1opt *a1op; const struct options *op; int sockfd; /* socket fd we use to manipulate stuff with */ int goterr; int selector; #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS unsigned int mask; unsigned int did_flags; unsigned int sai_hostname, sai_netmask; #else unsigned char mask; unsigned char did_flags; #endif char *p; char host[128]; goterr = 0; did_flags = 0; #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS sai_hostname = 0; sai_netmask = 0; #endif /* skip argv[0] */ ++argv; --argc; #ifdef CONFIG_FEATURE_IFCONFIG_STATUS if ((argc > 0) && (((*argv)[0] == '-') && ((*argv)[1] == 'a') && !(*argv)[2])) { interface_opt_a = 1; --argc; ++argv; } #endif if (argc <= 1) { #ifdef CONFIG_FEATURE_IFCONFIG_STATUS return display_interfaces(argc ? *argv : NULL); #else bb_error_msg_and_die ("ifconfig was not compiled with interface status display support."); #endif } /* Create a channel to the NET kernel. */ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { bb_perror_msg_and_die("socket"); } /* get interface name */ safe_strncpy(ifr.ifr_name, *argv, IFNAMSIZ); /* Process the remaining arguments. */ while (*++argv != (char *) NULL) { p = *argv; mask = N_MASK; if (*p == '-') { /* If the arg starts with '-'... */ ++p; /* advance past it and */ mask = M_MASK; /* set the appropriate mask. */ } for (op = OptArray; op->name; op++) { /* Find table entry. */ if (strcmp(p, op->name) == 0) { /* If name matches... */ if ((mask &= op->flags)) { /* set the mask and go. */ goto FOUND_ARG;; } /* If we get here, there was a valid arg with an */ /* invalid '-' prefix. */ ++goterr; goto LOOP; } } /* We fell through, so treat as possible hostname. */ a1op = Arg1Opt + (sizeof(Arg1Opt) / sizeof(Arg1Opt[0])) - 1; mask = op->arg_flags; goto HOSTNAME; FOUND_ARG: if (mask & ARG_MASK) { mask = op->arg_flags; a1op = Arg1Opt + (op - OptArray); if (mask & A_NETMASK & did_flags) { bb_show_usage(); } if (*++argv == NULL) { if (mask & A_ARG_REQ) { bb_show_usage(); } else { --argv; mask &= A_SET_AFTER; /* just for broadcast */ } } else { /* got an arg so process it */ HOSTNAME: did_flags |= (mask & (A_NETMASK|A_HOSTNAME)); if (mask & A_CAST_HOST_COPY) { #ifdef CONFIG_FEATURE_IFCONFIG_HW if (mask & A_CAST_RESOLVE) { #endif #ifdef CONFIG_FEATURE_IPV6 char *prefix; int prefix_len = 0; #endif safe_strncpy(host, *argv, (sizeof host)); #ifdef CONFIG_FEATURE_IPV6 if ((prefix = strchr(host, '/'))) { prefix_len = atol(prefix + 1); if ((prefix_len < 0) || (prefix_len > 128)) { ++goterr; goto LOOP; } *prefix = 0; } #endif sai.sin_family = AF_INET; sai.sin_port = 0; if (!strcmp(host, bb_INET_default)) { /* Default is special, meaning 0.0.0.0. */ sai.sin_addr.s_addr = INADDR_ANY; #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS } else if (((host[0] == '+') && !host[1]) && (mask & A_BROADCAST) && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME)) { /* + is special, meaning broadcast is derived. */ sai.sin_addr.s_addr = (~sai_netmask) | (sai_hostname & sai_netmask); #endif #ifdef CONFIG_FEATURE_IPV6 } else if (inet_pton(AF_INET6, host, &sai6.sin6_addr) > 0) { int sockfd6; struct in6_ifreq ifr6; memcpy((char *) &ifr6.ifr6_addr, (char *) &sai6.sin6_addr, sizeof(struct in6_addr)); /* Create a channel to the NET kernel. */ if ((sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { bb_perror_msg_and_die("socket6"); } if (ioctl(sockfd6, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); ++goterr; continue; } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (ioctl(sockfd6, a1op->selector, &ifr6) < 0) { perror(a1op->name); ++goterr; } continue; #endif } else if (inet_aton(host, &sai.sin_addr) == 0) { /* It's not a dotted quad. */ ++goterr; continue; } #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS if (mask & A_HOSTNAME) { sai_hostname = sai.sin_addr.s_addr; } if (mask & A_NETMASK) { sai_netmask = sai.sin_addr.s_addr; } #endif p = (char *) &sai; #ifdef CONFIG_FEATURE_IFCONFIG_HW } else { /* A_CAST_HOST_COPY_IN_ETHER */ /* This is the "hw" arg case. */ if (strcmp("ether", *argv) || (*++argv == NULL)) { bb_show_usage(); } safe_strncpy(host, *argv, (sizeof host)); if (in_ether(host, &sa)) { bb_error_msg("invalid hw-addr %s", host); ++goterr; continue; } p = (char *) &sa; } #endif memcpy((((char *) (&ifr)) + a1op->ifr_offset), p, sizeof(struct sockaddr)); } else { unsigned int i = strtoul(*argv, NULL, 0); p = ((char *) (&ifr)) + a1op->ifr_offset; #ifdef CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ if (mask & A_MAP_TYPE) { if (ioctl(sockfd, SIOCGIFMAP, &ifr) < 0) { ++goterr; continue; } if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) { *((unsigned char *) p) = i; } else if (mask & A_MAP_USHORT) { *((unsigned short *) p) = i; } else { *((unsigned long *) p) = i; } } else #endif if (mask & A_CAST_CHAR_PTR) { *((caddr_t *) p) = (caddr_t) i; } else { /* A_CAST_INT */ *((int *) p) = i; } } if (ioctl(sockfd, a1op->selector, &ifr) < 0) { perror(a1op->name); ++goterr; continue; } #ifdef QUESTIONABLE_ALIAS_CASE if (mask & A_COLON_CHK) { /* * Don't do the set_flag() if the address is an alias with * a - at the end, since it's deleted already! - Roman * * Should really use regex.h here, not sure though how well * it'll go with the cross-platform support etc. */ char *ptr; short int found_colon = 0; for (ptr = ifr.ifr_name; *ptr; ptr++) { if (*ptr == ':') { found_colon++; } } if (found_colon && *(ptr - 1) == '-') { continue; } } #endif } if (!(mask & A_SET_AFTER)) { continue; } mask = N_SET; } if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { perror("SIOCGIFFLAGS"); ++goterr; } else { selector = op->selector; if (mask & SET_MASK) { ifr.ifr_flags |= selector; } else { ifr.ifr_flags &= ~selector; } if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { perror("SIOCSIFFLAGS"); ++goterr; } } LOOP: continue; } /* end of while-loop */ return goterr; }
static void func_label(char *buf, int size, const procps_status_t *ps) { safe_strncpy(buf, ps->context ? ps->context : "unknown", size+1); }
static int INET_setroute(int action, int options, char **args) { struct rtentry rt; char target[128], gateway[128] = "NONE"; const char *netmask = bb_INET_default; int xflag, isnet; int skfd; xflag = 0; if (*args == NULL) bb_show_usage(); if (strcmp(*args, "-net") == 0) { xflag = 1; args++; } else if (strcmp(*args, "-host") == 0) { xflag = 2; args++; } if (*args == NULL) bb_show_usage(); safe_strncpy(target, *args++, (sizeof target)); /* Clean out the RTREQ structure. */ memset((char *) &rt, 0, sizeof(struct rtentry)); if ((isnet = INET_resolve(target, (struct sockaddr_in *) &rt.rt_dst, xflag != 1)) < 0) { bb_error_msg(_("can't resolve %s"), target); return EXIT_FAILURE; /* XXX change to E_something */ } switch (xflag) { case 1: isnet = 1; break; case 2: isnet = 0; break; default: break; } /* Fill in the other fields. */ rt.rt_flags = (RTF_UP | RTF_HOST); if (isnet) rt.rt_flags &= ~RTF_HOST; while (*args) { if (strcmp(*args, "metric") == 0) { int metric; args++; if (!*args || !isdigit(**args)) bb_show_usage(); metric = atoi(*args); #if HAVE_NEW_ADDRT rt.rt_metric = metric + 1; #else ENOSUPP("inet_setroute", "NEW_ADDRT (metric)"); /* XXX Fixme */ #endif args++; continue; } if (strcmp(*args, "netmask") == 0) { struct sockaddr mask; args++; if (!*args || mask_in_addr(rt)) bb_show_usage(); netmask = *args; if ((isnet = INET_resolve(netmask, (struct sockaddr_in *) &mask, 0)) < 0) { bb_error_msg(_("can't resolve netmask %s"), netmask); return E_LOOKUP; } rt.rt_genmask = full_mask(mask); args++; continue; } if (strcmp(*args, "gw") == 0 || strcmp(*args, "gateway") == 0) { args++; if (!*args) bb_show_usage(); if (rt.rt_flags & RTF_GATEWAY) bb_show_usage(); safe_strncpy(gateway, *args, (sizeof gateway)); if ((isnet = INET_resolve(gateway, (struct sockaddr_in *) &rt.rt_gateway, 1)) < 0) { bb_error_msg(_("can't resolve gw %s"), gateway); return E_LOOKUP; } if (isnet) { bb_error_msg(_("%s: cannot use a NETWORK as gateway!"), gateway); return E_OPTERR; } rt.rt_flags |= RTF_GATEWAY; args++; continue; } if (strcmp(*args, "mss") == 0) { args++; rt.rt_flags |= RTF_MSS; if (!*args) bb_show_usage(); rt.rt_mss = atoi(*args); args++; if (rt.rt_mss < 64 || rt.rt_mss > 32768) { bb_error_msg(_("Invalid MSS.")); return E_OPTERR; } continue; } if (strcmp(*args, "window") == 0) { args++; if (!*args) bb_show_usage(); rt.rt_flags |= RTF_WINDOW; rt.rt_window = atoi(*args); args++; if (rt.rt_window < 128) { bb_error_msg(_("Invalid window.")); return E_OPTERR; } continue; } if (strcmp(*args, "irtt") == 0) { args++; if (!*args) bb_show_usage(); args++; #if HAVE_RTF_IRTT rt.rt_flags |= RTF_IRTT; rt.rt_irtt = atoi(*(args - 1)); rt.rt_irtt *= (sysconf(_SC_CLK_TCK) / 100); /* FIXME */ #if 0 /* FIXME: do we need to check anything of this? */ if (rt.rt_irtt < 1 || rt.rt_irtt > (120 * HZ)) { bb_error_msg(_("Invalid initial rtt.")); return E_OPTERR; } #endif #else ENOSUPP("inet_setroute", "RTF_IRTT"); /* XXX Fixme */ #endif continue; } if (strcmp(*args, "reject") == 0) { args++; #if HAVE_RTF_REJECT rt.rt_flags |= RTF_REJECT; #else ENOSUPP("inet_setroute", "RTF_REJECT"); /* XXX Fixme */ #endif continue; } if (strcmp(*args, "mod") == 0) { args++; rt.rt_flags |= RTF_MODIFIED; continue; } if (strcmp(*args, "dyn") == 0) { args++; rt.rt_flags |= RTF_DYNAMIC; continue; } if (strcmp(*args, "reinstate") == 0) { args++; rt.rt_flags |= RTF_REINSTATE; continue; } if (strcmp(*args, "device") == 0 || strcmp(*args, "dev") == 0) { args++; if (rt.rt_dev || *args == NULL) bb_show_usage(); rt.rt_dev = *args++; continue; } /* nothing matches */ if (!rt.rt_dev) { rt.rt_dev = *args++; if (*args) bb_show_usage(); /* must be last to catch typos */ } else { bb_show_usage(); } } #if HAVE_RTF_REJECT if ((rt.rt_flags & RTF_REJECT) && !rt.rt_dev) rt.rt_dev = "lo"; #endif /* sanity checks.. */ if (mask_in_addr(rt)) { unsigned long mask = mask_in_addr(rt); mask = ~ntohl(mask); if ((rt.rt_flags & RTF_HOST) && mask != 0xffffffff) { bb_error_msg(_("netmask %.8x doesn't make sense with host route"), (unsigned int) mask); return E_OPTERR; } if (mask & (mask + 1)) { bb_error_msg(_("bogus netmask %s"), netmask); return E_OPTERR; } mask = ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr; if (mask & ~mask_in_addr(rt)) { bb_error_msg(_("netmask doesn't match route address")); return E_OPTERR; } } /* Fill out netmask if still unset */ if ((action == RTACTION_ADD) && rt.rt_flags & RTF_HOST) mask_in_addr(rt) = 0xffffffff; /* Create a socket to the INET kernel. */ if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); return E_SOCK; } /* Tell the kernel to accept this route. */ if (action == RTACTION_DEL) { if (ioctl(skfd, SIOCDELRT, &rt) < 0) { perror("SIOCDELRT"); close(skfd); return E_SOCK; } } else { if (ioctl(skfd, SIOCADDRT, &rt) < 0) { perror("SIOCADDRT"); close(skfd); return E_SOCK; } } /* Close the socket. */ (void) close(skfd); return EXIT_SUCCESS; }
void rtmon_check_updates(struct rtmon_t *rtmon) { int i, j; for (i=0; i < rtmon->_route_sz; i++) { if (rtmon->_routes[i].has_data) { if (rtmon->_routes[i].destination.s_addr == 0) { log_dbg("Default Route %s", inet_ntoa(rtmon->_routes[i].gateway)); for (j=0; j < rtmon->_iface_sz; j++) { if (rtmon->_ifaces[j].has_data) { if (rtmon->_routes[i].if_index == rtmon->_ifaces[j].index) { struct arpreq areq; struct sockaddr_in *sin; int s, attempt=0, retries=3; log_dbg("Route Interface %s", rtmon->_ifaces[j].devname); if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); return; } memset(&areq, 0, sizeof(areq)); sin = (struct sockaddr_in *) &areq.arp_pa; sin->sin_family = AF_INET; sin->sin_addr.s_addr = rtmon->_routes[i].gateway.s_addr; safe_strncpy(areq.arp_dev, rtmon->_ifaces[j].devname, sizeof(areq.arp_dev)); while (attempt < retries) { struct sockaddr_in addr; char b[1]={0}; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = sin->sin_addr; addr.sin_port = htons(10000); if (sendto(s, b, sizeof(b), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) perror("sendto"); if (ioctl(s, SIOCGARP, (caddr_t) &areq) == -1) { if (errno == ENXIO) { log_dbg("%s -- no entry\n", inet_ntoa(sin->sin_addr)); attempt++; sleep(1); continue; } else { perror("SIOCGARP"); break; } } else { log_dbg("MAC %s", mactoa((uint8_t *)&areq.arp_ha.sa_data)); memcpy(rtmon->_routes[i].gwaddr, &areq.arp_ha.sa_data, sizeof(rtmon->_routes[i].gwaddr)); if (rtmon->cb(rtmon, &rtmon->_ifaces[j], &rtmon->_routes[i])) log_err(errno, "callback failed"); break; } } close(s); return; } } } } } } }
void rtmon_discover_ifaces(struct rtmon_t *rtmon) { struct rtmon_iface ri; struct ifconf ic; int fd, len, i; for (i=0; i < rtmon->_iface_sz; i++) if (rtmon->_ifaces[i].has_data) rtmon->_ifaces[i].has_data |= RTMON_REMOVE; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return; } ic.ifc_buf=0; ic.ifc_len=0; if (ioctl(fd, SIOCGIFCONF, &ic) < 0) { close(fd); return; } ic.ifc_buf = calloc((size_t)ic.ifc_len, 1); if (ioctl(fd, SIOCGIFCONF, &ic) < 0) { close(fd); free(ic.ifc_buf); return; } len = (ic.ifc_len/sizeof(struct ifreq)); for (i=0; i < len; ++i) { struct ifreq *ifr = (struct ifreq *)&ic.ifc_req[i]; memset(&ri, 0, sizeof(ri)); /* device name and address */ safe_strncpy(ri.devname, ifr->ifr_name, sizeof(ri.devname)); ri.address = inaddr(ifr_addr); /* index */ if (-1 < ioctl(fd, SIOCGIFINDEX, (caddr_t) ifr)) { ri.index = ifr->ifr_ifindex; } /* netmask */ if (-1 < ioctl(fd, SIOCGIFNETMASK, (caddr_t)ifr)) { ri.netmask = inaddr(ifr_addr); } ri.network.s_addr = ri.address.s_addr & ri.netmask.s_addr; /* hardware address */ #ifdef SIOCGIFHWADDR if (-1 < ioctl(fd, SIOCGIFHWADDR, (caddr_t)ifr)) { switch (ifr->ifr_hwaddr.sa_family) { case ARPHRD_PPP: break; case ARPHRD_NETROM: case ARPHRD_ETHER: case ARPHRD_EETHER: case ARPHRD_IEEE802: { unsigned char *u = (unsigned char *)&ifr->ifr_addr.sa_data; memcpy(ri.hwaddr, u, 6); } break; } } #else #ifdef SIOCGENADDR if (-1 < ioctl(fd, SIOCGENADDR, (caddr_t)ifr)) { unsigned char *u = (unsigned char *)&ifr->ifr_enaddr; memcpy(ri.hwaddr, u, 6); } #else #warning Do not know how to find interface hardware address #endif /* SIOCGENADDR */ #endif /* SIOCGIFHWADDR */ /* flags */ if (-1 < ioctl(fd, SIOCGIFFLAGS, (caddr_t)ifr)) { ri.devflags = ifr->ifr_flags; } /* point-to-point gateway */ if (ri.devflags & IFF_POINTOPOINT) { if (-1 < ioctl(fd, SIOCGIFDSTADDR, (caddr_t)ifr)) { ri.gateway = inaddr(ifr_addr); } } /* broadcast address */ if (ri.devflags & IFF_BROADCAST) { if (-1 < ioctl(fd, SIOCGIFBRDADDR, (caddr_t)ifr)) { ri.broadcast = inaddr(ifr_addr); } } if (-1 < ioctl(fd, SIOCGIFMTU, (caddr_t)ifr)) { ri.mtu = ifr->ifr_mtu; } rtmon_add_iface(rtmon, &ri); } for (i=0; i < rtmon->_iface_sz; i++) { if (rtmon->_ifaces[i].has_data & RTMON_REMOVE) { tun_delif(tun, rtmon->_ifaces[i].index); memset(&rtmon->_ifaces[i], 0, sizeof(struct rtmon_iface)); } } free(ic.ifc_buf); close(fd); }
ncInstance * load_instance_struct (const char * instanceId) { const int meta_size = sizeof (struct ncInstance_t); ncInstance * instance = calloc (1, meta_size); if (instance==NULL) { logprintfl (EUCADEBUG, "load_instance_struct: out of memory for instance struct\n"); return NULL; } safe_strncpy (instance->instanceId, instanceId, sizeof (instance->instanceId)); // we don't know userId, so we'll look for instanceId in every user's // directory (we're assuming that instanceIds are unique in the system) char user_paths [MAX_PATH]; set_path (user_paths, sizeof (user_paths), NULL, NULL); DIR * insts_dir = opendir(user_paths); if (insts_dir == NULL) { logprintfl (EUCADEBUG, "load_instance_struct: failed to open %s\n", user_paths); goto free; } struct dirent * dir_entry; while ((dir_entry = readdir (insts_dir)) != NULL) { char tmp_path [MAX_PATH]; struct stat mystat; snprintf(tmp_path, sizeof (tmp_path), "%s/%s/%s", user_paths, dir_entry->d_name, instance->instanceId); if (stat(tmp_path, &mystat)==0) { safe_strncpy (instance->userId, dir_entry->d_name, sizeof (instance->userId)); break; // found it } } closedir (insts_dir); if (strlen(instance->userId)<1) { logprintfl (EUCADEBUG, "load_instance_struct: didn't find instance %s\n", instance->instanceId); goto free; } int fd; char checkpoint_path [MAX_PATH]; set_path (checkpoint_path, sizeof (checkpoint_path), instance, "instance.checkpoint"); if ((fd = open(checkpoint_path, O_RDONLY)) < 0 || read (fd, instance, meta_size) < meta_size) { logprintfl(EUCADEBUG, "load_instance_struct: failed to load metadata for %s from %s: %s\n", instance->instanceId, checkpoint_path, strerror (errno)); if(fd >= 0) close (fd); goto free; } close (fd); instance->stateCode = NO_STATE; // clear out pointers, since they are now wrong instance->params.root = NULL; instance->params.kernel = NULL; instance->params.ramdisk = NULL; instance->params.swap = NULL; instance->params.ephemeral0 = NULL; vbr_parse (&(instance->params), NULL); // fix up the pointers return instance; free: if (instance) free (instance); return NULL; }
bool DOS_Shell::Execute(char * name,char * args) { /* return true => don't check for hardware changes in do_command * return false => check for hardware changes in do_command */ char fullname[DOS_PATHLENGTH+4]; //stores results from Which char* p_fullname; char line[CMD_MAXLINE]; if(strlen(args)!= 0){ if(*args != ' '){ //put a space in front line[0]=' ';line[1]=0; strncat(line,args,CMD_MAXLINE-2); line[CMD_MAXLINE-1]=0; } else { safe_strncpy(line,args,CMD_MAXLINE); } }else{ line[0]=0; }; /* check for a drive change */ if (((strcmp(name + 1, ":") == 0) || (strcmp(name + 1, ":\\") == 0)) && isalpha(*name)) { if (!DOS_SetDrive(toupper(name[0])-'A')) { WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(name[0])); } return true; } /* Check for a full name */ p_fullname = Which(name); if (!p_fullname) return false; strcpy(fullname,p_fullname); const char* extension = strrchr(fullname,'.'); __android_log_print(ANDROID_LOG_INFO, "dosbox", "command fullname:%s", fullname); /*always disallow files without extension from being executed. */ /*only internal commands can be run this way and they never get in this handler */ if(extension == 0) { //Check if the result will fit in the parameters. Else abort if(strlen(fullname) >( DOS_PATHLENGTH - 1) ) return false; char temp_name[DOS_PATHLENGTH+4],* temp_fullname; //try to add .com, .exe and .bat extensions to filename strcpy(temp_name,fullname); strcat(temp_name,".COM"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".com";strcpy(fullname,temp_fullname); } else { strcpy(temp_name,fullname); strcat(temp_name,".EXE"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".exe";strcpy(fullname,temp_fullname);} else { strcpy(temp_name,fullname); strcat(temp_name,".BAT"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".bat";strcpy(fullname,temp_fullname);} else { return false; } } } } if (strcasecmp(extension, ".bat") == 0) { /* Run the .bat file */ /* delete old batch file if call is not active*/ bool temp_echo=echo; /*keep the current echostate (as delete bf might change it )*/ if(bf && !call) delete bf; bf=new BatchFile(this,fullname,name,line); echo=temp_echo; //restore it. } else { /* only .bat .exe .com extensions maybe be executed by the shell */ if(strcasecmp(extension, ".com") !=0) { if(strcasecmp(extension, ".exe") !=0) return false; } /* Run the .exe or .com file from the shell */ /* Allocate some stack space for tables in physical memory */ reg_sp-=0x200; //Add Parameter block DOS_ParamBlock block(SegPhys(ss)+reg_sp); block.Clear(); //Add a filename RealPt file_name=RealMakeSeg(ss,reg_sp+0x20); MEM_BlockWrite(Real2Phys(file_name),fullname,(Bitu)(strlen(fullname)+1)); /* HACK: Store full commandline for mount and imgmount */ full_arguments.assign(line); /* Fill the command line */ CommandTail cmdtail; cmdtail.count = 0; memset(&cmdtail.buffer,0,126); //Else some part of the string is unitialized (valgrind) if (strlen(line)>126) line[126]=0; cmdtail.count=(Bit8u)strlen(line); memcpy(cmdtail.buffer,line,strlen(line)); cmdtail.buffer[strlen(line)]=0xd; /* Copy command line in stack block too */ MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmdtail,128); /* Parse FCB (first two parameters) and put them into the current DOS_PSP */ Bit8u add; FCB_Parsename(dos.psp(),0x5C,0x00,cmdtail.buffer,&add); FCB_Parsename(dos.psp(),0x6C,0x00,&cmdtail.buffer[add],&add); block.exec.fcb1=RealMake(dos.psp(),0x5C); block.exec.fcb2=RealMake(dos.psp(),0x6C); /* Set the command line in the block and save it */ block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData(); #if 0 /* Save CS:IP to some point where i can return them from */ Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); RealPt newcsip=CALLBACK_RealPointer(call_shellstop); SegSet16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); #endif /* Start up a dos execute interrupt */ reg_ax=0x4b00; //Filename pointer SegSet16(ds,SegValue(ss)); reg_dx=RealOff(file_name); //Paramblock SegSet16(es,SegValue(ss)); reg_bx=reg_sp; SETFLAGBIT(IF,false); CALLBACK_RunRealInt(0x21); /* Restore CS:IP and the stack */ reg_sp+=0x200; #if 0 reg_eip=oldeip; SegSet16(cs,oldcs); #endif } return true; //Executable started }
int main(int argc, char **argv) { struct sockaddr sa; struct sockaddr samask; struct sockaddr_in sin; char host[128]; struct aftype *ap; struct hwtype *hw; struct ifreq ifr; int goterr = 0, didnetmask = 0, neednetmask=0; char **spp; int fd; #if HAVE_AFINET6 extern struct aftype inet6_aftype; struct sockaddr_in6 sa6; struct in6_ifreq ifr6; unsigned long prefix_len; char *cp; #endif #if HAVE_AFINET extern struct aftype inet_aftype; #endif #if I18N setlocale (LC_ALL, ""); bindtextdomain("net-tools", "/usr/share/locale"); textdomain("net-tools"); #endif /* Find any options. */ argc--; argv++; while (argc && *argv[0] == '-') { if (!strcmp(*argv, "-a")) opt_a = 1; else if (!strcmp(*argv, "-s")) ife_short = 1; else if (!strcmp(*argv, "-v")) opt_v = 1; else if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") || !strcmp(*argv, "--version")) version(); else if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") || !strcmp(*argv, "-help") || !strcmp(*argv, "--help")) usage(); else { fprintf(stderr, _("ifconfig: option `%s' not recognised.\n"), argv[0]); fprintf(stderr, _("ifconfig: `--help' gives usage information.\n")); exit(1); } argv++; argc--; } /* Create a channel to the NET kernel. */ if ((skfd = sockets_open(0)) < 0) { perror("socket"); exit(1); } /* Do we have to show the current setup? */ if (argc == 0) { int err = if_print((char *) NULL); (void) close(skfd); exit(err < 0); } /* No. Fetch the interface name. */ spp = argv; safe_strncpy(ifr.ifr_name, *spp++, IFNAMSIZ); if (*spp == (char *) NULL) { int err = if_print(ifr.ifr_name); (void) close(skfd); exit(err < 0); } /* The next argument is either an address family name, or an option. */ if ((ap = get_aftype(*spp)) != NULL) spp++; /* it was a AF name */ else ap = get_aftype(DFLT_AF); if (ap) { addr_family = ap->af; skfd = ap->fd; } /* Process the remaining arguments. */ while (*spp != (char *) NULL) { if (!strcmp(*spp, "arp")) { goterr |= clr_flag(ifr.ifr_name, IFF_NOARP); spp++; continue; } if (!strcmp(*spp, "-arp")) { goterr |= set_flag(ifr.ifr_name, IFF_NOARP); spp++; continue; } #ifdef IFF_PORTSEL if (!strcmp(*spp, "media") || !strcmp(*spp, "port")) { if (*++spp == NULL) usage(); if (!strcasecmp(*spp, "auto")) { goterr |= set_flag(ifr.ifr_name, IFF_AUTOMEDIA); } else { int i, j, newport; char *endp; newport = strtol(*spp, &endp, 10); if (*endp != 0) { newport = -1; for (i = 0; if_port_text[i][0] && newport == -1; i++) { for (j = 0; if_port_text[i][j]; j++) { if (!strcasecmp(*spp, if_port_text[i][j])) { newport = i; break; } } } } spp++; if (newport == -1) { fprintf(stderr, _("Unknown media type.\n")); goterr = 1; } else { if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { perror("port: SIOCGIFMAP"); goterr = 1; continue; } ifr.ifr_map.port = newport; if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { perror("port: SIOCSIFMAP"); goterr = 1; } } } continue; } #endif if (!strcmp(*spp, "trailers")) { goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS); spp++; continue; } if (!strcmp(*spp, "-trailers")) { goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS); spp++; continue; } if (!strcmp(*spp, "promisc")) { goterr |= set_flag(ifr.ifr_name, IFF_PROMISC); spp++; continue; } if (!strcmp(*spp, "-promisc")) { goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC); if (test_flag(ifr.ifr_name, IFF_PROMISC) > 0) fprintf(stderr, _("Warning: Interface %s still in promisc mode... maybe other application is running?\n"), ifr.ifr_name); spp++; continue; } if (!strcmp(*spp, "multicast")) { goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST); spp++; continue; } if (!strcmp(*spp, "-multicast")) { goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST); if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in MULTICAST mode.\n"), ifr.ifr_name); spp++; continue; } if (!strcmp(*spp, "allmulti")) { goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI); spp++; continue; } if (!strcmp(*spp, "-allmulti")) { goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI); if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in ALLMULTI mode.\n"), ifr.ifr_name); spp++; continue; } if (!strcmp(*spp, "up")) { goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); spp++; continue; } if (!strcmp(*spp, "down")) { goterr |= clr_flag(ifr.ifr_name, IFF_UP); spp++; continue; } #ifdef HAVE_DYNAMIC if (!strcmp(*spp, "dynamic")) { goterr |= set_flag(ifr.ifr_name, IFF_DYNAMIC); spp++; continue; } if (!strcmp(*spp, "-dynamic")) { goterr |= clr_flag(ifr.ifr_name, IFF_DYNAMIC); spp++; if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in DYNAMIC mode.\n"), ifr.ifr_name); continue; } #endif if (!strcmp(*spp, "metric")) { if (*++spp == NULL) usage(); ifr.ifr_metric = atoi(*spp); if (ioctl(skfd, SIOCSIFMETRIC, &ifr) < 0) { fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "mtu")) { if (*++spp == NULL) usage(); ifr.ifr_mtu = atoi(*spp); if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) { fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #ifdef SIOCSKEEPALIVE if (!strcmp(*spp, "keepalive")) { if (*++spp == NULL) usage(); ifr.ifr_data = (caddr_t) atoi(*spp); if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) { fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif #ifdef SIOCSOUTFILL if (!strcmp(*spp, "outfill")) { if (*++spp == NULL) usage(); ifr.ifr_data = (caddr_t) atoi(*spp); if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) { fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif if (!strcmp(*spp, "-broadcast")) { goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST); if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in BROADCAST mode.\n"), ifr.ifr_name); spp++; continue; } if (!strcmp(*spp, "broadcast")) { if (*++spp != NULL) { safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { if (ap->herror) ap->herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for broadcast\n"), host); goterr = 1; spp++; continue; } memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFBRDADDR: %s\n", strerror(errno)); goterr = 1; } spp++; } goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST); continue; } if (!strcmp(*spp, "dstaddr")) { if (*++spp == NULL) usage(); safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { if (ap->herror) ap->herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for dstaddr\n"), host); goterr = 1; spp++; continue; } memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFDSTADDR: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "netmask")) { if (*++spp == NULL || didnetmask) usage(); safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { if (ap->herror) ap->herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for netmask\n"), host); goterr = 1; spp++; continue; } didnetmask++; goterr |= set_netmask(ap->fd, &ifr, &sa); spp++; continue; } #ifdef HAVE_TXQUEUELEN if (!strcmp(*spp, "txqueuelen")) { if (*++spp == NULL) usage(); ifr.ifr_qlen = strtoul(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFTXQLEN, &ifr) < 0) { fprintf(stderr, "SIOCSIFTXQLEN: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif if (!strcmp(*spp, "mem_start")) { if (*++spp == NULL) usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { fprintf(stderr, "mem_start: SIOCGIFMAP: %s\n", strerror(errno)); spp++; goterr = 1; continue; } ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { fprintf(stderr, "mem_start: SIOCSIFMAP: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "io_addr")) { if (*++spp == NULL) usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { fprintf(stderr, "io_addr: SIOCGIFMAP: %s\n", strerror(errno)); spp++; goterr = 1; continue; } ifr.ifr_map.base_addr = strtol(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { fprintf(stderr, "io_addr: SIOCSIFMAP: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "irq")) { if (*++spp == NULL) usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { fprintf(stderr, "irq: SIOCGIFMAP: %s\n", strerror(errno)); goterr = 1; spp++; continue; } ifr.ifr_map.irq = atoi(*spp); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { fprintf(stderr, "irq: SIOCSIFMAP: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } if (!strcmp(*spp, "-pointopoint")) { goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT); spp++; if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in POINTOPOINT mode.\n"), ifr.ifr_name); continue; } if (!strcmp(*spp, "pointopoint")) { if (*(spp + 1) != NULL) { spp++; safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa)) { if (ap->herror) ap->herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for pointopoint\n"), host); goterr = 1; spp++; continue; } memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFDSTADDR: %s\n", strerror(errno)); goterr = 1; } } goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT); spp++; continue; }; if (!strcmp(*spp, "hw")) { if (*++spp == NULL) usage(); if ((hw = get_hwtype(*spp)) == NULL) usage(); if (hw->input == NULL) { fprintf(stderr, _("hw address type `%s' has no handler to set address. failed.\n"), *spp); spp+=2; goterr = 1; continue; } if (*++spp == NULL) usage(); safe_strncpy(host, *spp, (sizeof host)); if (hw->input(host, &sa) < 0) { fprintf(stderr, _("%s: invalid %s address.\n"), host, hw->name); goterr = 1; spp++; continue; } memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) { if (errno == EBUSY) fprintf(stderr, "SIOCSIFHWADDR: %s - you may need to down the interface\n", strerror(errno)); else fprintf(stderr, "SIOCSIFHWADDR: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #if HAVE_AFINET || HAVE_AFINET6 if (!strcmp(*spp, "add")) { if (*++spp == NULL) usage(); #if HAVE_AFINET6 if (strchr(*spp, ':')) { /* INET6 */ if ((cp = strchr(*spp, '/'))) { prefix_len = atol(cp + 1); if ((prefix_len < 0) || (prefix_len > 128)) usage(); *cp = 0; } else { prefix_len = 128; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { if (inet6_aftype.herror) inet6_aftype.herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for add\n"), host); goterr = 1; spp++; continue; } memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr)); fd = get_socket_for_af(AF_INET6); if (fd < 0) { fprintf(stderr, _("No support for INET6 on this system.\n")); goterr = 1; spp++; continue; } if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); goterr = 1; spp++; continue; } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) { perror("SIOCSIFADDR"); goterr = 1; } spp++; continue; } #endif #ifdef HAVE_AFINET { /* ipv4 address a.b.c.d */ unsigned long ip, nm, bc; safe_strncpy(host, *spp, (sizeof host)); if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) { ap->herror(host); goterr = 1; spp++; continue; } fd = get_socket_for_af(AF_INET); if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); goterr = 1; spp++; continue; } memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long)); if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) { fprintf(stderr, _("Interface %s not initialized\n"), ifr.ifr_name); goterr = 1; spp++; continue; } set_ifstate(ifr.ifr_name, ip, nm, bc, 1); } spp++; continue; #else fprintf(stderr, _("Bad address.\n")); #endif } #endif #if HAVE_AFINET || HAVE_AFINET6 if (!strcmp(*spp, "del")) { if (*++spp == NULL) usage(); #ifdef SIOCDIFADDR #if HAVE_AFINET6 if (strchr(*spp, ':')) { /* INET6 */ if ((cp = strchr(*spp, '/'))) { prefix_len = atol(cp + 1); if ((prefix_len < 0) || (prefix_len > 128)) usage(); *cp = 0; } else { prefix_len = 128; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { inet6_aftype.herror(host); goterr = 1; spp++; continue; } memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr)); fd = get_socket_for_af(AF_INET6); if (fd < 0) { fprintf(stderr, _("No support for INET6 on this system.\n")); goterr = 1; spp++; continue; } if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); goterr = 1; spp++; continue; } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (opt_v) fprintf(stderr, "now deleting: ioctl(SIOCDIFADDR,{ifindex=%d,prefixlen=%ld})\n",ifr.ifr_ifindex,prefix_len); if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) { fprintf(stderr, "SIOCDIFADDR: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif #ifdef HAVE_AFINET { /* ipv4 address a.b.c.d */ unsigned long ip, nm, bc; safe_strncpy(host, *spp, (sizeof host)); if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) { ap->herror(host); goterr = 1; spp++; continue; } fd = get_socket_for_af(AF_INET); if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); goterr = 1; spp++; continue; } memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long)); if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) { fprintf(stderr, _("Interface %s not initialized\n"), ifr.ifr_name); goterr = 1; spp++; continue; } set_ifstate(ifr.ifr_name, ip, nm, bc, 0); } spp++; continue; #else fprintf(stderr, _("Bad address.\n")); #endif #else fprintf(stderr, _("Address deletion not supported on this system.\n")); #endif } #endif #if HAVE_AFINET6 if (!strcmp(*spp, "tunnel")) { if (*++spp == NULL) usage(); if ((cp = strchr(*spp, '/'))) { prefix_len = atol(cp + 1); if ((prefix_len < 0) || (prefix_len > 128)) usage(); *cp = 0; } else { prefix_len = 128; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { inet6_aftype.herror(host); goterr = 1; spp++; continue; } memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr)); fd = get_socket_for_af(AF_INET6); if (fd < 0) { fprintf(stderr, _("No support for INET6 on this system.\n")); goterr = 1; spp++; continue; } if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); goterr = 1; spp++; continue; } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) { fprintf(stderr, "SIOCSIFDSTADDR: %s\n", strerror(errno)); goterr = 1; } spp++; continue; } #endif /* If the next argument is a valid hostname, assume OK. */ safe_strncpy(host, *spp, (sizeof host)); /* FIXME: sa is too small for INET6 addresses, inet6 should use that too, broadcast is unexpected */ if (ap->getmask) { switch (ap->getmask(host, &samask, NULL)) { case -1: usage(); break; case 1: if (didnetmask) usage(); // remeber to set the netmask from samask later neednetmask = 1; break; } } if (ap->input == NULL) { fprintf(stderr, _("ifconfig: Cannot set address for this protocol family.\n")); exit(1); } if (ap->input(0, host, &sa) < 0) { if (ap->herror) ap->herror(host); else fprintf(stderr,_("ifconfig: error resolving '%s' to set address for af=%s\n"), host, ap->name); fprintf(stderr, _("ifconfig: `--help' gives usage information.\n")); exit(1); } memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr)); { int r = 0; /* to shut gcc up */ switch (ap->af) { #if HAVE_AFINET case AF_INET: fd = get_socket_for_af(AF_INET); if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); exit(1); } r = ioctl(fd, SIOCSIFADDR, &ifr); break; #endif #if HAVE_AFECONET case AF_ECONET: fd = get_socket_for_af(AF_ECONET); if (fd < 0) { fprintf(stderr, _("No support for ECONET on this system.\n")); exit(1); } r = ioctl(fd, SIOCSIFADDR, &ifr); break; #endif default: fprintf(stderr, _("Don't know how to set addresses for family %d.\n"), ap->af); exit(1); } if (r < 0) { perror("SIOCSIFADDR"); goterr = 1; } } /* * Don't do the set_flag() if the address is an alias with a - at the * end, since it's deleted already! - Roman * * Should really use regex.h here, not sure though how well it'll go * with the cross-platform support etc. */ { char *ptr; short int found_colon = 0; for (ptr = ifr.ifr_name; *ptr; ptr++ ) if (*ptr == ':') found_colon++; if (!(found_colon && *(ptr - 1) == '-')) goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); } spp++; } if (neednetmask) { goterr |= set_netmask(skfd, &ifr, &samask); didnetmask++; } if (opt_v && goterr) fprintf(stderr, _("WARNING: at least one error occured. (%d)\n"), goterr); return (goterr); }
/* Returns 1 if no reply received */ int FAST_FUNC arpping(uint32_t test_nip, const uint8_t *safe_mac, uint32_t from_ip, uint8_t *from_mac, const char *interface) { int timeout_ms; struct pollfd pfd[1]; #define s (pfd[0].fd) /* socket */ int rv = 1; /* "no reply received" yet */ struct sockaddr addr; /* for interface name */ struct arpMsg arp; s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); if (s == -1) { bb_perror_msg("%s", bb_msg_can_not_create_raw_socket); return -1; } if (setsockopt_broadcast(s) == -1) { bb_perror_msg("can't enable bcast on raw socket"); goto ret; } /* send arp request */ memset(&arp, 0, sizeof(arp)); memset(arp.h_dest, 0xff, 6); /* MAC DA */ memcpy(arp.h_source, from_mac, 6); /* MAC SA */ arp.h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */ arp.htype = htons(ARPHRD_ETHER); /* hardware type */ arp.ptype = htons(ETH_P_IP); /* protocol type (ARP message) */ arp.hlen = 6; /* hardware address length */ arp.plen = 4; /* protocol address length */ arp.operation = htons(ARPOP_REQUEST); /* ARP op code */ memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */ memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */ /* tHaddr is zero-filled */ /* target hardware address */ memcpy(arp.tInaddr, &test_nip, sizeof(test_nip));/* target IP address */ memset(&addr, 0, sizeof(addr)); safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data)); if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0) { // TODO: error message? caller didn't expect us to fail, // just returning 1 "no reply received" misleads it. goto ret; } /* wait for arp reply, and check it */ timeout_ms = 2000; do { typedef uint32_t aliased_uint32_t FIX_ALIASING; int r; unsigned prevTime = monotonic_ms(); pfd[0].events = POLLIN; r = safe_poll(pfd, 1, timeout_ms); if (r < 0) break; if (r) { r = safe_read(s, &arp, sizeof(arp)); if (r < 0) break; //log3("sHaddr %02x:%02x:%02x:%02x:%02x:%02x", // arp.sHaddr[0], arp.sHaddr[1], arp.sHaddr[2], // arp.sHaddr[3], arp.sHaddr[4], arp.sHaddr[5]); if (r >= ARP_MSG_SIZE && arp.operation == htons(ARPOP_REPLY) /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */ /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */ && *(aliased_uint32_t*)arp.sInaddr == test_nip ) { /* if ARP source MAC matches safe_mac * (which is client's MAC), then it's not a conflict * (client simply already has this IP and replies to ARPs!) */ if (!safe_mac || memcmp(safe_mac, arp.sHaddr, 6) != 0) rv = 0; //else log2("sHaddr == safe_mac"); break; } } timeout_ms -= (unsigned)monotonic_ms() - prevTime; } while (timeout_ms > 0); ret: close(s); log1("%srp reply received for this address", rv ? "No a" : "A"); return rv; }
struct ax_routes *read_ax_routes(void) { FILE *fp; char buffer[256], *cp, *cmd; struct ax_routes *p=NULL, *list = NULL, *new_el; int i = 0, k; errno = 0; if ((fp = fopen(AX_ROUTES_FILE, "r")) == NULL) return NULL; while (fgets(buffer, 256, fp) != NULL) { if (i++<1) continue; if(*buffer=='#' || *buffer==' ' ) continue; /* commented line */ cp=strchr(buffer, '#'); /* ignore comments */ if (cp) *cp='\0'; cmd=strtok(buffer, " \t\n\r"); if(cmd==NULL) continue; /* empty line */ if (strcasecmp(cmd,"route")==0) { /* add route */ if ((new_el = calloc(1, sizeof(struct ax_routes))) == NULL) break; safe_strncpy(new_el->dest_call, strupr(strtok(NULL, " \t\n\r")), 9); safe_strncpy(new_el->alias, strupr(strtok(NULL, " \t\n\r")), 9); safe_strncpy(new_el->dev, strtok(NULL, " \t\n\r"), 13); safe_strncpy(new_el->conn_type, strupr(strtok(NULL, " \t\n\r")), 1); safe_strncpy(new_el->description, strtok(NULL, "'\t\n\r"), 50); if (new_el->description==NULL) strcpy(new_el->description," "); switch(*new_el->conn_type) { case CONN_TYPE_DIRECT: { break; } case CONN_TYPE_NODE: { safe_strncpy(new_el->digis[0], strupr(strtok(NULL, " \t\n\r")), 9); break; } case CONN_TYPE_DIGI: { k=0; while((cp=strtok(NULL, " \t\n\r"))!=NULL&&k<AX25_MAX_DIGIS) safe_strncpy(new_el->digis[k++],strupr(cp),9); while(k<AX25_MAX_DIGIS) strcpy(new_el->digis[k++],"\0"); break; } default: { return NULL; break; } } if(list==NULL) { list=new_el; p=list; } else { p->next = new_el; p=p->next; } } } fclose(fp); return list; }
static void func_rgroup(char *buf, int size, const procps_status_t *ps) { safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1); }
int waste_srvmain_start(int argc, char **argv) { SetProgramDirectory(argv[0]); g_log_level=ds_Console; _logfile=stderr; { bool dohelp=false; if (argc<2) { dohelp=true; } else { if (!strcmp(argv[1],"-i")) { log_printf(ds_Console,"Interactive!"); } else if (!strcmp(argv[1],"-L")) { char *szLI2; szLI2=(char*)malloc(sK0[3]); safe_strncpy(szLI2,(char*)sK1[3],sK0[3]); dpi(szLI2,4); RelpaceCr(szLI2); fprintf(_logfile,"\n\n%s\n",szLI2); memset(szLI2,0,sK0[3]);free(szLI2); return 1; } else if (!strcmp(argv[1],"-d")) { if (argc==3) { log_printf(ds_Console,"Forking DAEMON!"); log_UpdatePath(argv[2],true); #ifndef _WIN32 daemon(1,0); #endif log_printf(ds_Console,"DAEMON!"); } else { dohelp=true; }; } else { dohelp=true; }; }; if (dohelp) { char *szCR2; szCR2=(char*)malloc(sK0[1]); safe_strncpy(szCR2,(char*)sK1[1],sK0[1]); dpi(szCR2,2); RelpaceCr(szCR2); log_printf(ds_Console, "%s\n" "%s\n" "\n" "Usage: wastesrv <-i> | -d <logfile>\n" "\t -L print license\n" "\t -i interactive mode\n" "\t -d daemon mode (on linux this will put wastesrv in the background)\n" "\n" "\twastesrv.ini must to be present on Windows\n" "\tthe config is default.pr0 to default.pr4\n", g_nameverstr, szCR2 ); memset(szCR2,0,sK0[1]);free(szCR2); return 1; }; }; installsighandler(); log_printf(ds_Console,"%s starting up...",g_nameverstr); MYSRAND(); if (!g_exit) //emergency break! { strcat(g_config_prefix,"default"); #ifdef _WIN32 WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 0), &wsaData)) { memset(&g_key,0,sizeof(g_key)); MessageBox(NULL,"Error initializing Winsock\n",APP_NAME " Error",0); return 1; } #endif UnifiedReadConfig(); InitialLoadDb(); PrepareDownloadDirectory(); if (!g_key.bits) { reloadKey( g_config->ReadInt(CONFIG_storepass,CONFIG_storepass_DEFAULT)? g_config->ReadString(CONFIG_keypass,CONFIG_keypass_DEFAULT): NULL ); }; InitializeNetworkparts(); } return (g_exit); }
static void func_ruser(char *buf, int size, const procps_status_t *ps) { safe_strncpy(buf, get_cached_username(ps->ruid), size+1); }
/* Write out a tar header for the specified file/directory/whatever */ static int writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name, const char *fileName, struct stat *statbuf) { struct tar_header_t header; memset(&header, 0, sizeof(header)); strncpy(header.name, header_name, sizeof(header.name)); /* POSIX says to mask mode with 07777. */ PUT_OCTAL(header.mode, statbuf->st_mode & 07777); PUT_OCTAL(header.uid, statbuf->st_uid); PUT_OCTAL(header.gid, statbuf->st_gid); memset(header.size, '0', sizeof(header.size)-1); /* Regular file size is handled later */ /* users report that files with negative st_mtime cause trouble, so: */ PUT_OCTAL(header.mtime, statbuf->st_mtime >= 0 ? statbuf->st_mtime : 0); /* Enter the user and group names */ safe_strncpy(header.uname, get_cached_username(statbuf->st_uid), sizeof(header.uname)); safe_strncpy(header.gname, get_cached_groupname(statbuf->st_gid), sizeof(header.gname)); if (tbInfo->hlInfo) { /* This is a hard link */ header.typeflag = LNKTYPE; strncpy(header.linkname, tbInfo->hlInfo->name, sizeof(header.linkname)); #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS /* Write out long linkname if needed */ if (header.linkname[sizeof(header.linkname)-1]) writeLongname(tbInfo->tarFd, GNULONGLINK, tbInfo->hlInfo->name, 0); #endif } else if (S_ISLNK(statbuf->st_mode)) { char *lpath = xmalloc_readlink_or_warn(fileName); if (!lpath) return FALSE; header.typeflag = SYMTYPE; strncpy(header.linkname, lpath, sizeof(header.linkname)); #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS /* Write out long linkname if needed */ if (header.linkname[sizeof(header.linkname)-1]) writeLongname(tbInfo->tarFd, GNULONGLINK, lpath, 0); #else /* If it is larger than 100 bytes, bail out */ if (header.linkname[sizeof(header.linkname)-1]) { free(lpath); bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); return FALSE; } #endif free(lpath); } else if (S_ISDIR(statbuf->st_mode)) { header.typeflag = DIRTYPE; /* Append '/' only if there is a space for it */ if (!header.name[sizeof(header.name)-1]) header.name[strlen(header.name)] = '/'; } else if (S_ISCHR(statbuf->st_mode)) { header.typeflag = CHRTYPE; PUT_OCTAL(header.devmajor, major(statbuf->st_rdev)); PUT_OCTAL(header.devminor, minor(statbuf->st_rdev)); } else if (S_ISBLK(statbuf->st_mode)) { header.typeflag = BLKTYPE; PUT_OCTAL(header.devmajor, major(statbuf->st_rdev)); PUT_OCTAL(header.devminor, minor(statbuf->st_rdev)); } else if (S_ISFIFO(statbuf->st_mode)) { header.typeflag = FIFOTYPE; } else if (S_ISREG(statbuf->st_mode)) { /* header.size field is 12 bytes long */ /* Does octal-encoded size fit? */ uoff_t filesize = statbuf->st_size; if (sizeof(filesize) <= 4 || filesize <= (uoff_t)0777777777777LL ) { PUT_OCTAL(header.size, filesize); } /* Does base256-encoded size fit? * It always does unless off_t is wider than 64 bits. */ else if (ENABLE_FEATURE_TAR_GNU_EXTENSIONS #if ULLONG_MAX > 0xffffffffffffffffLL /* 2^64-1 */ && (filesize <= 0x3fffffffffffffffffffffffLL) #endif ) { /* GNU tar uses "base-256 encoding" for very large numbers. * Encoding is binary, with highest bit always set as a marker * and sign in next-highest bit: * 80 00 .. 00 - zero * bf ff .. ff - largest positive number * ff ff .. ff - minus 1 * c0 00 .. 00 - smallest negative number */ char *p8 = header.size + sizeof(header.size); do { *--p8 = (uint8_t)filesize; filesize >>= 8; } while (p8 != header.size); *p8 |= 0x80; } else {
static int writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name, const char *fileName, struct stat *statbuf) { struct TarHeader header; if (sizeof(header) != 512) BUG_tar_header_size(); memset(&header, 0, sizeof(struct TarHeader)); strncpy(header.name, header_name, sizeof(header.name)); /* POSIX says to mask mode with 07777. */ PUT_OCTAL(header.mode, statbuf->st_mode & 07777); PUT_OCTAL(header.uid, statbuf->st_uid); PUT_OCTAL(header.gid, statbuf->st_gid); memset(header.size, '0', sizeof(header.size)-1); /* Regular file size is handled later */ PUT_OCTAL(header.mtime, statbuf->st_mtime); /* Enter the user and group names */ safe_strncpy(header.uname, get_cached_username(statbuf->st_uid), sizeof(header.uname)); safe_strncpy(header.gname, get_cached_groupname(statbuf->st_gid), sizeof(header.gname)); if (tbInfo->hlInfo) { /* This is a hard link */ header.typeflag = LNKTYPE; strncpy(header.linkname, tbInfo->hlInfo->name, sizeof(header.linkname)); #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS /* Write out long linkname if needed */ if (header.linkname[sizeof(header.linkname)-1]) writeLongname(tbInfo->tarFd, GNULONGLINK, tbInfo->hlInfo->name, 0); #endif } else if (S_ISLNK(statbuf->st_mode)) { char *lpath = xmalloc_readlink_or_warn(fileName); if (!lpath) return FALSE; header.typeflag = SYMTYPE; strncpy(header.linkname, lpath, sizeof(header.linkname)); #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS /* Write out long linkname if needed */ if (header.linkname[sizeof(header.linkname)-1]) writeLongname(tbInfo->tarFd, GNULONGLINK, lpath, 0); #else /* If it is larger than 100 bytes, bail out */ if (header.linkname[sizeof(header.linkname)-1]) { free(lpath); bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); return FALSE; } #endif free(lpath); } else if (S_ISDIR(statbuf->st_mode)) { header.typeflag = DIRTYPE; /* Append '/' only if there is a space for it */ if (!header.name[sizeof(header.name)-1]) header.name[strlen(header.name)] = '/'; } else if (S_ISCHR(statbuf->st_mode)) { header.typeflag = CHRTYPE; PUT_OCTAL(header.devmajor, major(statbuf->st_rdev)); PUT_OCTAL(header.devminor, minor(statbuf->st_rdev)); } else if (S_ISBLK(statbuf->st_mode)) { header.typeflag = BLKTYPE; PUT_OCTAL(header.devmajor, major(statbuf->st_rdev)); PUT_OCTAL(header.devminor, minor(statbuf->st_rdev)); } else if (S_ISFIFO(statbuf->st_mode)) { header.typeflag = FIFOTYPE; } else if (S_ISREG(statbuf->st_mode)) { if (sizeof(statbuf->st_size) > 4 && statbuf->st_size > (off_t)0777777777777LL ) { bb_error_msg_and_die("cannot store file '%s' " "of size %"OFF_FMT"d, aborting", fileName, statbuf->st_size); } header.typeflag = REGTYPE; PUT_OCTAL(header.size, statbuf->st_size); } else { bb_error_msg("%s: unknown file type", fileName); return FALSE; } #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS /* Write out long name if needed */ /* (we, like GNU tar, output long linkname *before* long name) */ if (header.name[sizeof(header.name)-1]) writeLongname(tbInfo->tarFd, GNULONGNAME, header_name, S_ISDIR(statbuf->st_mode)); #endif /* Now write the header out to disk */ chksum_and_xwrite(tbInfo->tarFd, &header); /* Now do the verbose thing (or not) */ if (tbInfo->verboseFlag) { FILE *vbFd = stdout; if (tbInfo->tarFd == STDOUT_FILENO) /* If the archive goes to stdout, verbose to stderr */ vbFd = stderr; /* GNU "tar cvvf" prints "extended" listing a-la "ls -l" */ /* We don't have such excesses here: for us "v" == "vv" */ /* '/' is probably a GNUism */ fprintf(vbFd, "%s%s\n", header_name, S_ISDIR(statbuf->st_mode) ? "/" : ""); } return TRUE; }
void HiveStringVectorRowSet::extractField(size_t column_idx) { assert(column_idx < getColumnCount()); assert(m_fields_weak_ptr != NULL); safe_strncpy(m_field_buffer, m_fields_weak_ptr->at(column_idx).c_str(), sizeof(m_field_buffer)); }
static len_and_sockaddr *str2sockaddr(const char *host, int port, int ai_flags) { int rc; len_and_sockaddr *r = NULL; struct addrinfo *result = NULL; const char *org_host = host; /* only for error msg */ const char *cp; struct addrinfo hint; /* Ugly parsing of host:addr */ if (ENABLE_FEATURE_IPV6 && host[0] == '[') { host++; cp = strchr(host, ']'); if (!cp || cp[1] != ':') { /* Malformed: must have [xx]:nn */ //bb_error_msg_and_die("bad address '%s'", org_host); printf("bad address '%s'", org_host); exit (-1); } //return r; /* return NULL */ } else { cp = strrchr(host, ':'); if (ENABLE_FEATURE_IPV6 && cp && strchr(host, ':') != cp) { /* There is more than one ':' (e.g. "::1") */ cp = NULL; /* it's not a port spec */ } } if (cp) { int sz = cp - host + 1; host = safe_strncpy(alloca(sz), host, sz); if (ENABLE_FEATURE_IPV6 && *cp != ':') cp++; /* skip ']' */ cp++; /* skip ':' */ port = xatou16(cp); } memset(&hint, 0 , sizeof(hint)); #if !ENABLE_FEATURE_IPV6 hint.ai_family = AF_INET; /* do not try to find IPv6 */ #else hint.ai_family = af; #endif /* Needed. Or else we will get each address thrice (or more) for each possible socket type (tcp,udp,raw...): */ hint.ai_socktype = SOCK_STREAM; hint.ai_flags = ai_flags & ~DIE_ON_ERROR; rc = getaddrinfo(host, NULL, &hint, &result); if (rc || !result) { //bb_error_msg("bad address '%s'", org_host); printf("bad address '%s'", org_host); if (ai_flags & DIE_ON_ERROR) exit(-1); goto ret; } r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); r->len = result->ai_addrlen; memcpy(&r->sa, result->ai_addr, result->ai_addrlen); set_nport(r, htons(port)); ret: freeaddrinfo(result); return r; }
int main(int argc, char **argv) { struct gengetopt_args_info args_info; struct hostent *host; char hostname[USERURLSIZE]; int numargs; int ret = -1; int i; options_init(); memset(&args_info, 0, sizeof(args_info)); if (cmdline_parser2(argc, argv, &args_info, 1, 1, 1) != 0) { log_err(0, "Failed to parse command line options"); goto end_processing; } if (args_info.version_given) { options_print_version(); exit(2); } if (args_info.help_given) { options_print_help(); exit(2); } if (cmdline_parser_configfile(args_info.conf_arg ? args_info.conf_arg : DEFCHILLICONF, &args_info, 0, 0, 0)) { log_err(0, "Failed to parse configuration file: %s!", args_info.conf_arg); if (!args_info.forgiving_flag) goto end_processing; } /* Get the system default DNS entries */ if (res_init()) { log_err(0, "Failed to update system DNS settings (res_init()!"); goto end_processing; } /* Handle each option */ _options.initialized = 1; if (args_info.debug_flag) _options.debug = args_info.debugfacility_arg; else _options.debug = 0; /* pass-throughs */ memset(_options.pass_throughs, 0, sizeof(_options.pass_throughs)); _options.num_pass_throughs = 0; /** simple configuration parameters **/ _options.layer3 = args_info.layer3_flag; #if(_debug_ && !defined(ENABLE_LAYER3)) if (_options.layer3) log_warn(0, "layer3 not implemented. build with --enable-layer3"); #endif _options.uid = args_info.uid_arg; _options.gid = args_info.gid_arg; _options.mtu = args_info.mtu_arg; _options.usetap = args_info.usetap_flag; _options.noarpentries = args_info.noarpentries_flag; #if(_debug_ && !defined(ENABLE_TAP)) if (_options.noarpentries) log_warn(0, "tap not implemented. build with --enable-tap"); #endif #if(_debug_ && !defined(ENABLE_TAP)) if (_options.usetap) log_warn(0, "tap not implemented. build with --enable-tap"); #endif _options.foreground = args_info.fg_flag; _options.interval = args_info.interval_arg; _options.lease = args_info.lease_arg; _options.leaseplus = args_info.leaseplus_arg; _options.dhcpstart = args_info.dhcpstart_arg; _options.dhcpend = args_info.dhcpend_arg; _options.eapolenable = args_info.eapolenable_flag; #if(_debug_ && !defined(ENABLE_EAPOL)) if (_options.eapolenable) log_warn(0, "EAPOL not implemented. build with --enable-eapol"); #endif _options.swapoctets = args_info.swapoctets_flag; _options.logfacility = args_info.logfacility_arg; _options.chillixml = args_info.chillixml_flag; _options.macauth = args_info.macauth_flag; _options.macreauth = args_info.macreauth_flag; _options.macauthdeny = args_info.macauthdeny_flag; _options.uamport = args_info.uamport_arg; #ifdef ENABLE_UAMUIPORT _options.uamuiport = args_info.uamuiport_arg; #endif _options.macallowlocal = args_info.macallowlocal_flag; _options.strictmacauth = args_info.strictmacauth_flag; _options.strictdhcp = args_info.strictdhcp_flag; _options.no_wispr1 = args_info.nowispr1_flag; _options.no_wispr2 = args_info.nowispr2_flag; _options.wpaguests = args_info.wpaguests_flag; _options.openidauth = args_info.openidauth_flag; _options.challengetimeout = args_info.challengetimeout_arg; _options.challengetimeout2 = args_info.challengetimeout2_arg; _options.defsessiontimeout = args_info.defsessiontimeout_arg; _options.definteriminterval = args_info.definteriminterval_arg; _options.defbandwidthmaxdown = args_info.defbandwidthmaxdown_arg; _options.defbandwidthmaxup = args_info.defbandwidthmaxup_arg; _options.defidletimeout = args_info.defidletimeout_arg; _options.radiusnasporttype = args_info.radiusnasporttype_arg; _options.radiusauthport = args_info.radiusauthport_arg; _options.radiusacctport = args_info.radiusacctport_arg; _options.coaport = args_info.coaport_arg; _options.coanoipcheck = args_info.coanoipcheck_flag; _options.radiustimeout = args_info.radiustimeout_arg; _options.radiusretry = args_info.radiusretry_arg; _options.radiusretrysec = args_info.radiusretrysec_arg; #ifdef ENABLE_RADPROXY _options.proxyport = args_info.proxyport_arg; _options.proxymacaccept = args_info.proxymacaccept_flag; _options.proxyonacct = args_info.proxyonacct_flag; #endif #if(_debug_ && !defined(ENABLE_RADPROXY)) if (args_info.proxyport_arg) log_err(0,"radproxy not implemented. build with --enable-radproxy"); #endif _options.txqlen = args_info.txqlen_arg; _options.ringsize = args_info.ringsize_arg; _options.sndbuf = args_info.sndbuf_arg; _options.rcvbuf = args_info.rcvbuf_arg; _options.childmax = args_info.childmax_arg; _options.postauth_proxyport = args_info.postauthproxyport_arg; _options.pap_always_ok = args_info.papalwaysok_flag; _options.mschapv2 = args_info.mschapv2_flag; _options.acct_update = args_info.acctupdate_flag; _options.dhcpradius = args_info.dhcpradius_flag; _options.dhcp_broadcast = args_info.dhcpbroadcast_flag; _options.dhcpgwport = args_info.dhcpgatewayport_arg; _options.noc2c = args_info.noc2c_flag; _options.tcpwin = args_info.tcpwin_arg; _options.tcpmss = args_info.tcpmss_arg; _options.max_clients = args_info.maxclients_arg; _options.radiusqsize = args_info.radiusqsize_arg; _options.dhcphashsize = args_info.dhcphashsize_arg; _options.uamdomain_ttl = args_info.uamdomainttl_arg; _options.seskeepalive = args_info.seskeepalive_flag; _options.uamallowpost = args_info.uamallowpost_flag; _options.redir = args_info.redir_flag; _options.redirurl = args_info.redirurl_flag; _options.statusfilesave = args_info.statusfilesave_flag; _options.dhcpnotidle = args_info.dhcpnotidle_flag; #if(_debug_ && !defined(ENABLE_CHILLIREDIR)) if (_options.redir) log_err(0, "chilli_redir not implemented. build with --enable-chilliredir"); #endif _options.redirssl = args_info.redirssl_flag; _options.uamuissl = args_info.uamuissl_flag; _options.domaindnslocal = args_info.domaindnslocal_flag; _options.framedservice = args_info.framedservice_flag; _options.radsec = args_info.radsec_flag; #if(_debug_ && !defined(ENABLE_CHILLIRADSEC)) if (_options.radsec) log_err(0, "chilli_radsec not implemented. build with --enable-chilliradsec"); #endif _options.noradallow = args_info.noradallow_flag; _options.peerid = args_info.peerid_arg; #if(_debug_ && !defined(ENABLE_CLUSTER)) if (_options.peerid) log_err(0, "clustering not implemented. build with --enable-cluster"); #endif _options.redirdnsreq = args_info.redirdnsreq_flag; #if(_debug_ && !defined(ENABLE_REDIRDNSREQ)) if (_options.redirdnsreq) log_err(0, "redirdnsreq not implemented. build with --enable-redirdnsreq"); #endif #ifdef ENABLE_IPV6 _options.ipv6 = args_info.ipv6_flag; _options.ipv6only = args_info.ipv6only_flag; #endif #ifdef ENABLE_LEAKYBUCKET _options.scalewin = args_info.scalewin_flag; _options.bwbucketupsize = args_info.bwbucketupsize_arg; _options.bwbucketdnsize = args_info.bwbucketdnsize_arg; _options.bwbucketminsize = args_info.bwbucketminsize_arg; #endif #ifdef ENABLE_PROXYVSA _options.vlanlocation = args_info.vlanlocation_flag; _options.location_stop_start = args_info.locationstopstart_flag; _options.location_copy_called = args_info.locationcopycalled_flag; _options.location_immediate_update = args_info.locationimmediateupdate_flag; _options.location_option_82 = args_info.locationopt82_flag; if (args_info.proxylocattr_given) { for (numargs = 0; numargs < args_info.proxylocattr_given && numargs < PROXYVSA_ATTR_CNT; ++numargs) { unsigned int i[2]; switch (sscanf(args_info.proxylocattr_arg[numargs], "%u,%u", &i[0], &i[1])) { case 0: log_err(0, "invalid input %s", args_info.proxylocattr_arg[numargs]); break; case 1: _options.proxy_loc[numargs].attr = i[0]; break; case 2: _options.proxy_loc[numargs].attr_vsa = i[0]; _options.proxy_loc[numargs].attr = i[1]; break; } log_dbg("Proxy location attr %d %d", (int)_options.proxy_loc[numargs].attr_vsa, (int)_options.proxy_loc[numargs].attr); } } #endif if (args_info.dhcpgateway_arg && !inet_aton(args_info.dhcpgateway_arg, &_options.dhcpgwip)) { log_err(0, "Invalid DHCP gateway IP address: %s!", args_info.dhcpgateway_arg); if (!args_info.forgiving_flag) goto end_processing; } if (args_info.dhcprelayagent_arg && !inet_aton(args_info.dhcprelayagent_arg, &_options.dhcprelayip)) { log_err(0, "Invalid DHCP gateway relay IP address: %s!", args_info.dhcprelayagent_arg); if (!args_info.forgiving_flag) goto end_processing; } _options.dhcpif = STRDUP(args_info.dhcpif_arg); #ifdef ENABLE_MULTILAN for (numargs = 0; numargs < args_info.moreif_given && numargs < MAX_MOREIF; ++numargs) { char *nif = STRDUP(args_info.moreif_arg[numargs]); char *vln = strchr(nif, '/'); _options.moreif[numargs].dhcpif = nif; if (vln) { if (strlen(vln) > 1) _options.moreif[numargs].vlan = vln + 1; *vln = 0; } else { vln = strchr(nif, '.'); if (vln && strlen(vln) > 1) _options.moreif[numargs].vlan = vln + 1; } } #endif if (!args_info.radiussecret_arg) { log_err(0, "radiussecret must be specified!"); if (!args_info.forgiving_flag) goto end_processing; } if (!args_info.nexthop_arg) { memset(_options.nexthop, 0, PKT_ETH_ALEN); _options.has_nexthop = 0; } else { unsigned int temp[PKT_ETH_ALEN]; char macstr[RADIUS_ATTR_VLEN]; int macstrlen; int i; if ((macstrlen = strlen(args_info.nexthop_arg)) >= (RADIUS_ATTR_VLEN-1)) { log_err(0, "MAC address too long"); if (!args_info.forgiving_flag) goto end_processing; } memcpy(macstr, args_info.nexthop_arg, macstrlen); macstr[macstrlen] = 0; /* Replace anything but hex with space */ for (i=0; i<macstrlen; i++) if (!isxdigit((int) macstr[i])) macstr[i] = 0x20; if (sscanf (macstr, "%2x %2x %2x %2x %2x %2x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5]) != 6) { log_err(0, "MAC conversion failed!"); return -1; } for (i = 0; i < PKT_ETH_ALEN; i++) _options.nexthop[i] = temp[i]; _options.has_nexthop = 1; } if (!args_info.dhcpmac_arg) { memset(_options.dhcpmac, 0, PKT_ETH_ALEN); _options.dhcpusemac = 0; _options.dhcpmacset = 0; } else { unsigned int temp[PKT_ETH_ALEN]; char macstr[RADIUS_ATTR_VLEN]; int macstrlen; int i; if ((macstrlen = strlen(args_info.dhcpmac_arg)) >= (RADIUS_ATTR_VLEN-1)) { log_err(0, "MAC address too long"); if (!args_info.forgiving_flag) goto end_processing; } memcpy(macstr, args_info.dhcpmac_arg, macstrlen); macstr[macstrlen] = 0; /* Replace anything but hex with space */ for (i=0; i<macstrlen; i++) if (!isxdigit((int) macstr[i])) macstr[i] = 0x20; if (sscanf (macstr, "%2x %2x %2x %2x %2x %2x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5]) != 6) { log_err(0, "MAC conversion failed!"); return -1; } for (i = 0; i < PKT_ETH_ALEN; i++) _options.dhcpmac[i] = temp[i]; _options.dhcpusemac = 1; _options.dhcpmacset = args_info.dhcpmacset_flag; } if (args_info.net_arg) { if (option_aton(&_options.net, &_options.mask, args_info.net_arg, 0)) { log_err(0, "Invalid network address: %s!", args_info.net_arg); if (!args_info.forgiving_flag) goto end_processing; } if (!args_info.uamlisten_arg) { _options.uamlisten.s_addr = htonl(ntohl(_options.net.s_addr)+1); } else if (!inet_aton(args_info.uamlisten_arg, &_options.uamlisten)) { log_err(0, "Invalid UAM IP address: %s!", args_info.uamlisten_arg); if (!args_info.forgiving_flag) goto end_processing; } if (!args_info.dhcplisten_arg) { _options.dhcplisten.s_addr = _options.uamlisten.s_addr; } else if (!inet_aton(args_info.dhcplisten_arg, &_options.dhcplisten)) { log_err(0, "Invalid DHCP IP address: %s!", args_info.dhcplisten_arg); if (!args_info.forgiving_flag) goto end_processing; } } else { log_err(0, "Network address must be specified ('net' parameter)!"); if (!args_info.forgiving_flag) goto end_processing; } log_dbg("DHCP Listen: %s", inet_ntoa(_options.dhcplisten)); log_dbg("UAM Listen: %s", inet_ntoa(_options.uamlisten)); if (!args_info.uamserver_arg) { log_err(0, "WARNING: No uamserver defiend!"); } if (args_info.uamserver_arg) { int uamserverport=80; if (_options.debug & DEBUG_CONF) { log_dbg("Uamserver: %s\n", args_info.uamserver_arg); } if (get_urlparts(args_info.uamserver_arg, hostname, USERURLSIZE, &uamserverport, 0)) { log_err(0, "Failed to parse uamserver: %s!", args_info.uamserver_arg); if (!args_info.forgiving_flag) goto end_processing; } if (!args_info.uamaliasname_arg || strncmp(args_info.uamaliasname_arg, hostname, strlen(args_info.uamaliasname_arg))) { if (!(host = gethostbyname(hostname))) { log_err(0, "Could not resolve IP address of uamserver: %s!", args_info.uamserver_arg); } else { int j = 0; pass_through pt; memset(&pt, 0, sizeof(pt)); pt.port = uamserverport; pt.mask.s_addr = ~0; while (host->h_addr_list[j] != NULL) { if (_options.debug & DEBUG_CONF) { log_dbg("Uamserver IP address #%d: %s\n", j, inet_ntoa(*(struct in_addr*) host->h_addr_list[j])); } pt.host.s_addr = ((struct in_addr*) host->h_addr_list[j++])->s_addr; if (pass_through_add(_options.pass_throughs, MAX_PASS_THROUGHS, &_options.num_pass_throughs, &pt, 0 #ifdef HAVE_PATRICIA , 0 #endif )) log_err(0, "Too many pass-throughs! skipped %s:%d", inet_ntoa(pt.host), pt.port); } } } } _options.uamanydns = args_info.uamanydns_flag; #ifdef ENABLE_UAMANYIP _options.uamanyip = args_info.uamanyip_flag; _options.uamnatanyip = args_info.uamnatanyip_flag; #endif _options.dnsparanoia = args_info.dnsparanoia_flag; _options.radiusoriginalurl = args_info.radiusoriginalurl_flag; _options.routeonetone = args_info.routeonetone_flag; #ifdef HAVE_PATRICIA _options.patricia = args_info.patricia_flag; #endif #ifdef ENABLE_GARDENACCOUNTING _options.nousergardendata = args_info.nousergardendata_flag; _options.uamgardendata = args_info.uamgardendata_flag; _options.uamotherdata = args_info.uamotherdata_flag; #endif for (numargs = 0; numargs < args_info.uamallowed_given; ++numargs) { pass_throughs_from_string(_options.pass_throughs, MAX_PASS_THROUGHS, &_options.num_pass_throughs, args_info.uamallowed_arg[numargs], 0, 0 #ifdef HAVE_PATRICIA , 0 #endif ); } #ifdef ENABLE_DHCPOPT _options.dhcp_options_len = 0; for (numargs = 0; numargs < args_info.dhcpopt_given; ++numargs) { unsigned char binopt[128]; int hex_length = strlen(args_info.dhcpopt_arg[numargs]); int bin_length = hex_length / 2; if (hex_length > 0 && (bin_length * 2) == hex_length && bin_length < sizeof(binopt)) { log_dbg("DHCP Options %s", args_info.dhcpopt_arg[numargs]); if (redir_hextochar((unsigned char *)args_info.dhcpopt_arg[numargs], hex_length, binopt, bin_length) == 0) { if (_options.dhcp_options_len + bin_length < sizeof(_options.dhcp_options)) { memcpy(_options.dhcp_options + _options.dhcp_options_len, binopt, bin_length); _options.dhcp_options_len += bin_length; } else { log_dbg("No room for DHCP option %d", (int)binopt[0]); } } else { log_dbg("Bad DHCP option hex encoding"); } } else { log_dbg("DHCP options are hex encoded binary"); } } #endif #ifdef ENABLE_MODULES memset(_options.modules, 0, sizeof(_options.modules)); for (numargs = 0; numargs < args_info.module_given; ++numargs) { if (numargs < MAX_MODULES) { char *n, *sc; int len, nlen; n = args_info.module_arg[numargs]; len = strlen(n); sc = strchr(n, ';'); if (!sc) sc = strchr(n, ':'); nlen = sc ? (sc - n) : len; safe_snprintf(_options.modules[numargs].name, sizeof(_options.modules[numargs].name), "%.*s", nlen, n); if (sc && len > (nlen + 1)) { safe_snprintf(_options.modules[numargs].conf, sizeof(_options.modules[numargs].conf), "%.*s", len - nlen - 1, sc + 1); } } } #endif #ifdef ENABLE_CHILLIREDIR /* for (numargs = 0; numargs < MAX_REGEX_PASS_THROUGHS; ++numargs) { if (_options.regex_pass_throughs[numargs].re_host.allocated) regfree(&_options.regex_pass_throughs[numargs].re_host); if (_options.regex_pass_throughs[numargs].re_path.allocated) regfree(&_options.regex_pass_throughs[numargs].re_path); if (_options.regex_pass_throughs[numargs].re_qs.allocated) regfree(&_options.regex_pass_throughs[numargs].re_qs); } */ memset(_options.regex_pass_throughs, 0, sizeof(_options.regex_pass_throughs)); _options.regex_num_pass_throughs = 0; for (numargs = 0; numargs < args_info.uamregex_given; ++numargs) { regex_pass_throughs_from_string(_options.regex_pass_throughs, MAX_REGEX_PASS_THROUGHS, &_options.regex_num_pass_throughs, args_info.uamregex_arg[numargs], 0); } #endif for (numargs = 0; numargs < MAX_UAM_DOMAINS; ++numargs) { if (_options.uamdomains[numargs]) free(_options.uamdomains[numargs]); _options.uamdomains[numargs] = 0; } if (args_info.uamdomain_given) { for (numargs = 0, i=0; numargs < args_info.uamdomain_given && i < MAX_UAM_DOMAINS; ++numargs) { char *tb = args_info.uamdomain_arg[numargs]; char *tok, *str, *ptr; for (str = tb ; i < MAX_UAM_DOMAINS; str = NULL) { tok = strtok_r(str, ",", &ptr); if (!tok) break; log_dbg("uamdomain %s", tok); _options.uamdomains[i++] = STRDUP(tok); } } } _options.allowdyn = 1; #ifdef ENABLE_UAMANYIP _options.autostatip = args_info.autostatip_arg; if (_options.autostatip) _options.uamanyip = 1; #endif if (args_info.nodynip_flag) { _options.allowdyn = 0; } else { if (!args_info.dynip_arg) { _options.dynip = STRDUP(args_info.net_arg); } else { struct in_addr addr; struct in_addr mask; _options.dynip = STRDUP(args_info.dynip_arg); if (option_aton(&addr, &mask, _options.dynip, 0)) { log_err(0, "Failed to parse dynamic IP address pool!"); if (!args_info.forgiving_flag) goto end_processing; } } } /* statip */ if (args_info.statip_arg) { struct in_addr addr; struct in_addr mask; _options.statip = STRDUP(args_info.statip_arg); if (option_aton(&addr, &mask, _options.statip, 0)) { log_err(0, "Failed to parse static IP address pool!"); return -1; } _options.allowstat = 1; } else { _options.allowstat = 0; } #ifdef ENABLE_UAMANYIP if (args_info.uamnatanyipex_arg) { if (option_aton(&_options.uamnatanyipex_addr, &_options.uamnatanyipex_mask, args_info.uamnatanyipex_arg, 0)) { log_err(0, "Failed to parse uamnatanyipex network!"); return -1; } } if (args_info.uamanyipex_arg) { if (option_aton(&_options.uamanyipex_addr, &_options.uamanyipex_mask, args_info.uamanyipex_arg, 0)) { log_err(0, "Failed to parse uamanyipex network!"); return -1; } } #endif if (args_info.dns1_arg) { if (!inet_aton(args_info.dns1_arg, &_options.dns1)) { log_err(0,"Invalid primary DNS address: %s!", args_info.dns1_arg); if (!args_info.forgiving_flag) goto end_processing; } } else if (_res.nscount >= 1) { _options.dns1 = _res.nsaddr_list[0].sin_addr; } else { _options.dns1.s_addr = 0; } if (args_info.dns2_arg) { if (!inet_aton(args_info.dns2_arg, &_options.dns2)) { log_err(0,"Invalid secondary DNS address: %s!", args_info.dns1_arg); if (!args_info.forgiving_flag) goto end_processing; } } else if (_res.nscount >= 2) { _options.dns2 = _res.nsaddr_list[1].sin_addr; } else { _options.dns2.s_addr = _options.dns1.s_addr; } /* If no listen option is specified listen to any local port */ /* Do hostname lookup to translate hostname to IP address */ if (args_info.radiuslisten_arg) { if (!(host = gethostbyname(args_info.radiuslisten_arg))) { log_err(0, "Invalid listening address: %s! [%s]", args_info.radiuslisten_arg, strerror(errno)); if (!args_info.forgiving_flag) goto end_processing; } else { memcpy(&_options.radiuslisten.s_addr, host->h_addr, host->h_length); } } else { _options.radiuslisten.s_addr = htonl(INADDR_ANY); } #ifdef ENABLE_NETNAT if (args_info.natip_arg) { if (!(host = gethostbyname(args_info.natip_arg))) { log_warn(0, "Invalid natip address: %s! [%s]", args_info.natip_arg, strerror(errno)); } else { memcpy(&_options.natip.s_addr, host->h_addr, host->h_length); } } #endif if (args_info.uamlogoutip_arg) { if (!(host = gethostbyname(args_info.uamlogoutip_arg))) { log_warn(0, "Invalid uamlogoutup address: %s! [%s]", args_info.uamlogoutip_arg, strerror(errno)); } else { memcpy(&_options.uamlogout.s_addr, host->h_addr, host->h_length); } } if (args_info.uamaliasip_arg) { if (!(host = gethostbyname(args_info.uamaliasip_arg))) { log_warn(0, "Invalid uamaliasip address: %s! [%s]", args_info.uamlogoutip_arg, strerror(errno)); } else { memcpy(&_options.uamalias.s_addr, host->h_addr, host->h_length); } } if (args_info.postauthproxy_arg) { if (!(host = gethostbyname(args_info.postauthproxy_arg))) { log_warn(0, "Invalid postauthproxy address: %s! [%s]", args_info.postauthproxy_arg, strerror(errno)); } else { memcpy(&_options.postauth_proxyip.s_addr, host->h_addr, host->h_length); } } /* If no option is specified terminate */ /* Do hostname lookup to translate hostname to IP address */ if (args_info.radiusserver1_arg) { if (!(host = gethostbyname(args_info.radiusserver1_arg))) { log_err(0, "Invalid radiusserver1 address: %s! [%s]", args_info.radiusserver1_arg, strerror(errno)); if (!args_info.forgiving_flag) goto end_processing; } else { memcpy(&_options.radiusserver1.s_addr, host->h_addr, host->h_length); } } else { log_err(0,"No radiusserver1 address given!"); if (!args_info.forgiving_flag) goto end_processing; } /* radiusserver2 */ /* If no option is specified terminate */ /* Do hostname lookup to translate hostname to IP address */ if (args_info.radiusserver2_arg) { if (!(host = gethostbyname(args_info.radiusserver2_arg))) { log_err(0, "Invalid radiusserver2 address: %s! [%s]", args_info.radiusserver2_arg, strerror(errno)); if (!args_info.forgiving_flag) goto end_processing; } else { memcpy(&_options.radiusserver2.s_addr, host->h_addr, host->h_length); } } else { _options.radiusserver2.s_addr = 0; } /* If no listen option is specified listen to any local port */ /* Do hostname lookup to translate hostname to IP address */ if (args_info.proxylisten_arg) { #ifdef ENABLE_RADPROXY if (!(host = gethostbyname(args_info.proxylisten_arg))) { log_err(0, "Invalid listening address: %s! [%s]", args_info.proxylisten_arg, strerror(errno)); if (!args_info.forgiving_flag) goto end_processing; } else { memcpy(&_options.proxylisten.s_addr, host->h_addr, host->h_length); } } else { _options.proxylisten.s_addr = htonl(INADDR_ANY); #elif (_debug_) log_warn(0,"radproxy not implemented. build with --enable-radproxy"); #endif } /* Store proxyclient as in_addr net and mask */ if (args_info.proxyclient_arg) { #ifdef ENABLE_RADPROXY if(option_aton(&_options.proxyaddr, &_options.proxymask, args_info.proxyclient_arg, 0)) { log_err(0,"Invalid proxy client address: %s!", args_info.proxyclient_arg); if (!args_info.forgiving_flag) goto end_processing; } } else { _options.proxyaddr.s_addr = ~0; /* Let nobody through */ _options.proxymask.s_addr = 0; #elif (_debug_) log_warn(0,"radproxy not implemented. build with --enable-radproxy"); #endif } memset(_options.macok, 0, sizeof(_options.macok)); _options.macoklen = 0; for (numargs = 0; numargs < args_info.macallowed_given; ++numargs) { char *p1 = NULL; char *p2 = NULL; char *p3 = malloc(strlen(args_info.macallowed_arg[numargs])+1); int i; unsigned int mac[6]; log_dbg("Macallowed #%d: %s", numargs, args_info.macallowed_arg[numargs]); strcpy(p3, args_info.macallowed_arg[numargs]); p1 = p3; if ((p2 = strchr(p1, ','))) { *p2 = '\0'; } while (p1) { if (_options.macoklen>=MACOK_MAX) { log_err(0,"Too many addresses in macallowed %s!", args_info.macallowed_arg); } else { /* Replace anything but hex and comma with space */ for (i=0; i<strlen(p1); i++) if (!isxdigit((int) p1[i])) p1[i] = 0x20; if (sscanf (p1, "%2x %2x %2x %2x %2x %2x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) != 6) { log_err(0, "Failed to convert macallowed option to MAC Address"); } else { log_dbg("Macallowed address #%d: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X", _options.macoklen, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); for (i = 0; i < 6; i++) _options.macok[_options.macoklen][i] = (unsigned char) mac[i]; _options.macoklen++; } } if (p2) { p1 = p2+1; if ((p2 = strchr(p1, ','))) { *p2 = 0; } } else { p1 = NULL; } } free(p3); } /** string parameters **/ #ifdef HAVE_SSL _options.sslkeyfile = STRDUP(args_info.sslkeyfile_arg); _options.sslkeypass = STRDUP(args_info.sslkeypass_arg); _options.sslcertfile = STRDUP(args_info.sslcertfile_arg); _options.sslcafile = STRDUP(args_info.sslcafile_arg); #endif #ifdef USING_IPC_UNIX _options.unixipc = STRDUP(args_info.unixipc_arg); #endif #ifdef HAVE_NETFILTER_COOVA _options.kname = STRDUP(args_info.kname_arg); #endif #ifdef ENABLE_DNSLOG _options.dnslog = STRDUP(args_info.dnslog_arg); #else if (args_info.dnslog_arg) log_err(0, "option dnslog given when no support built-in"); #endif #ifdef ENABLE_IPWHITELIST _options.ipwhitelist = STRDUP(args_info.ipwhitelist_arg); #else if (args_info.ipwhitelist_arg) log_err(0, "option ipwhitelist given when no support built-in"); #endif #ifdef ENABLE_UAMDOMAINFILE _options.uamdomainfile = STRDUP(args_info.uamdomainfile_arg); #else if (args_info.uamdomainfile_arg) log_err(0, "option uamdomainfile given when no support built-in"); #endif #ifdef ENABLE_MODULES _options.moddir = STRDUP(args_info.moddir_arg); #else if (args_info.moddir_arg) log_err(0, "option moddir given when no support built-in"); #endif #ifdef ENABLE_RADPROXY if (!args_info.proxysecret_arg) { _options.proxysecret = STRDUP(args_info.radiussecret_arg); } else { _options.proxysecret = STRDUP(args_info.proxysecret_arg); } #endif #ifdef ENABLE_REDIRINJECT _options.inject = STRDUP(args_info.inject_arg); _options.inject_ext = STRDUP(args_info.injectext_arg); _options.inject_wispr = args_info.injectwispr_flag; #endif #ifdef ENABLE_EXTADMVSA if (args_info.extadmvsa_given) { for (numargs = 0; numargs < args_info.extadmvsa_given && numargs < EXTADMVSA_ATTR_CNT; ++numargs) { int len = strlen(args_info.extadmvsa_arg[numargs]); if (len > 0 && len < 256) { unsigned int i[2]; char s[256]; if (sscanf(args_info.extadmvsa_arg[numargs], "%u,%u:%s", &i[0], &i[1], s) == 3) { char *idx = strchr(s, ':'); _options.extadmvsa[numargs].attr_vsa = i[0]; _options.extadmvsa[numargs].attr = i[1]; if (idx) *idx = 0; safe_strncpy(_options.extadmvsa[numargs].script, s, sizeof(_options.extadmvsa[numargs].script)-1); if (idx) { safe_strncpy(_options.extadmvsa[numargs].data, idx + 1, sizeof(_options.extadmvsa[numargs].data)-1); } } else if (sscanf(args_info.extadmvsa_arg[numargs], "%u:%s", &i[0], s) == 2) { char *idx = strchr(s, ':'); _options.extadmvsa[numargs].attr = i[0]; if (idx) *idx = 0; safe_strncpy(_options.extadmvsa[numargs].script, s, sizeof(_options.extadmvsa[numargs].script)-1); if (idx) { safe_strncpy(_options.extadmvsa[numargs].data, idx + 1, sizeof(_options.extadmvsa[numargs].data)-1); } } else { log_err(0, "invalid input %s", args_info.extadmvsa_arg[numargs]); } } log_dbg("Extended admin-user attr (%d/%d) data=%s script=%s", (int)_options.extadmvsa[numargs].attr_vsa, (int)_options.extadmvsa[numargs].attr, _options.extadmvsa[numargs].data, _options.extadmvsa[numargs].script); } } #endif _options.peerkey = STRDUP(args_info.peerkey_arg); _options.routeif = STRDUP(args_info.routeif_arg); _options.wwwdir = STRDUP(args_info.wwwdir_arg); _options.wwwbin = STRDUP(args_info.wwwbin_arg); _options.uamui = STRDUP(args_info.uamui_arg); _options.localusers = STRDUP(args_info.localusers_arg); _options.uamurl = STRDUP(args_info.uamserver_arg); _options.uamaaaurl = STRDUP(args_info.uamaaaurl_arg); _options.uamhomepage = STRDUP(args_info.uamhomepage_arg); _options.wisprlogin = STRDUP(args_info.wisprlogin_arg); _options.uamsecret = STRDUP(args_info.uamsecret_arg); _options.macsuffix = STRDUP(args_info.macsuffix_arg); _options.macpasswd = STRDUP(args_info.macpasswd_arg); _options.adminuser = STRDUP(args_info.adminuser_arg); _options.adminpasswd = STRDUP(args_info.adminpasswd_arg); _options.adminupdatefile = STRDUP(args_info.adminupdatefile_arg); _options.rtmonfile = STRDUP(args_info.rtmonfile_arg); _options.ssid = STRDUP(args_info.ssid_arg); _options.vlan = STRDUP(args_info.vlan_arg); _options.nasmac = STRDUP(args_info.nasmac_arg); _options.nasip = STRDUP(args_info.nasip_arg); _options.tundev = STRDUP(args_info.tundev_arg); _options.radiusnasid = STRDUP(args_info.radiusnasid_arg); _options.radiuslocationid = STRDUP(args_info.radiuslocationid_arg); _options.radiuslocationname = STRDUP(args_info.radiuslocationname_arg); _options.locationname = STRDUP(args_info.locationname_arg); _options.radiussecret = STRDUP(args_info.radiussecret_arg); #ifdef ENABLE_LARGELIMITS /*_options.radiusacctsecret = STRDUP(args_info.radiusacctsecret_arg); _options.radiusadmsecret = STRDUP(args_info.radiusadmsecret_arg);*/ #endif _options.cmdsocket = STRDUP(args_info.cmdsocket_arg); _options.cmdsocketport = args_info.cmdsocketport_arg; _options.domain = STRDUP(args_info.domain_arg); _options.ipup = STRDUP(args_info.ipup_arg); _options.ipdown = STRDUP(args_info.ipdown_arg); _options.conup = STRDUP(args_info.conup_arg); _options.condown = STRDUP(args_info.condown_arg); _options.macup = STRDUP(args_info.macup_arg); _options.macdown = STRDUP(args_info.macdown_arg); _options.pidfile = STRDUP(args_info.pidfile_arg); _options.statedir = STRDUP(args_info.statedir_arg); _options.usestatusfile = STRDUP(args_info.usestatusfile_arg); _options.uamaliasname = STRDUP(args_info.uamaliasname_arg); _options.uamhostname = STRDUP(args_info.uamhostname_arg); _options.binconfig = STRDUP(args_info.bin_arg); _options.ethers = STRDUP(args_info.ethers_arg); #ifdef ENABLE_IEEE8021Q _options.ieee8021q = args_info.ieee8021q_flag; _options.ieee8021q_only = args_info.only8021q_flag; _options.vlanupdate = STRDUP(args_info.vlanupdate_arg); #endif #ifdef ENABLE_PROXYVSA _options.locationupdate = STRDUP(args_info.locationupdate_arg); #endif #ifdef EX_OPT_MAIN #include EX_OPT_MAIN #endif ret = 0; if (_options.binconfig) { /* save out the configuration */ bstring bt = bfromcstr(""); int ok = options_save(_options.binconfig, bt); if (!ok) log_err(0, "could not save configuration options!"); bdestroy(bt); } if (args_info.reload_flag) { if (execl(SBINDIR "/chilli_query", "chilli_query", args_info.cmdsocket_arg, "reload", (char *) 0) != 0) { log_err(errno, "execl() did not return 0!"); exit(2); } } end_processing: cmdline_parser_free (&args_info); return ret; }
static Uint32 build_update_list(const char* server, const char* file, const char* path, update_info_t** infos, Uint32* count, char md5[33], const Uint32 etag_size, char* etag, progress_fnc update_progress_function, void* user_data) { char *buffer = NULL; const size_t buffer_size = 1024; Uint64 file_size; FILE* tmp_file; void* file_buffer; Uint32 result; #ifdef WINDOWS tmp_file = my_tmpfile(); #else tmp_file = tmpfile(); #endif if (tmp_file == 0) { LOG_ERROR("Can't get tmp file"); return 3; } update_progress_function("Checking for updates", 0, 0, user_data); if ((buffer = calloc(buffer_size, sizeof(char))) == NULL) { fclose(tmp_file); return 1; } result = check_server_digest_files(file, tmp_file, server, path, buffer_size, buffer, md5); if (result == 0) { update_progress_function("No update needed", 0, 0, user_data); fclose(tmp_file); free(buffer); return 1; } fseek(tmp_file, 0, SEEK_SET); result = download_file(file, tmp_file, server, path, &file_size, buffer_size, buffer, etag_size, etag); if (result == 304) { fclose(tmp_file); update_progress_function("No update needed", 0, 0, user_data); free(buffer); return 1; } if (result != 0) { char *file_name = NULL; const size_t file_name_size = 1024; file_name = (char *)calloc(sizeof(char), file_name_size); safe_strncpy(file_name, file, file_name_size); safe_strcat(file_name, ".xz", file_name_size); fseek(tmp_file, 0, SEEK_SET); result = download_file(file_name, tmp_file, server, path, &file_size, buffer_size, buffer, etag_size, etag); free(file_name); if (result == 304) { fclose(tmp_file); update_progress_function("No update needed", 0, 0, user_data); free(buffer); return 1; } } if (result != 0) { char *error_str = NULL; const size_t error_str_size = 4096; fclose(tmp_file); error_str = (char *)calloc(sizeof(char), error_str_size); safe_snprintf(error_str, error_str_size, "Can't get update list" " file '%s' from server '%s' using path '%s', error %d.", file, server, path, result); LOG_ERROR(error_str); update_progress_function(error_str, 0, 0, user_data); free(error_str); free(buffer); return 4; } *infos = 0; *count = 0; fseek(tmp_file, 0, SEEK_SET); file_read(tmp_file, file_size, &file_buffer, &file_size); fclose(tmp_file); if (add_to_downloads(file_buffer, file_size, infos, count, update_progress_function, user_data) != 1) { char *error_str = NULL; const size_t error_str_size = 4096; free(file_buffer); error_str = (char *)calloc(sizeof(char), error_str_size); safe_snprintf(error_str, error_str_size, "Update list" " file '%s' from server '%s' using path '%s' has wrong" " magic number in first line.", file, server, path); LOG_ERROR(error_str); update_progress_function(error_str, 0, 0, user_data); free(error_str); free(buffer); return 5; } free(buffer); free(file_buffer); return 0; }
/* * return the file path separator for this type of OS */ void get_separator(I18N_STRING separator) { safe_strncpy(separator, I18N_STRING_LEN, "/", I18N_STRING_LEN); }
/* numeric: & 0x8000: default instead of *, * & 0x4000: host instead of net, * & 0x0fff: don't resolve */ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in, int numeric, unsigned int netmask) { struct hostent *ent; struct netent *np; struct addr *pn; uint32_t ad, host_ad; int host = 0; /* Grmpf. -FvK */ if (s_in->sin_family != AF_INET) { #ifdef DEBUG bb_error_msg("rresolve: unsupport address family %d !", s_in->sin_family); #endif errno = EAFNOSUPPORT; return -1; } ad = s_in->sin_addr.s_addr; #ifdef DEBUG bb_error_msg("rresolve: %08x, mask %08x, num %08x", (unsigned)ad, netmask, numeric); #endif if (ad == INADDR_ANY) { if ((numeric & 0x0FFF) == 0) { if (numeric & 0x8000) safe_strncpy(name, bb_str_default, len); else safe_strncpy(name, "*", len); return 0; } } if (numeric & 0x0FFF) { safe_strncpy(name, inet_ntoa(s_in->sin_addr), len); return 0; } if ((ad & (~netmask)) != 0 || (numeric & 0x4000)) host = 1; pn = INET_nn; while (pn != NULL) { if (pn->addr.sin_addr.s_addr == ad && pn->host == host) { safe_strncpy(name, pn->name, len); #ifdef DEBUG bb_error_msg("rresolve: found %s %08x in cache", (host ? "host" : "net"), (unsigned)ad); #endif return 0; } pn = pn->next; } host_ad = ntohl(ad); np = NULL; ent = NULL; if (host) { #ifdef DEBUG bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad); #endif ent = gethostbyaddr((char *) &ad, 4, AF_INET); if (ent != NULL) { safe_strncpy(name, ent->h_name, len); } } else { #ifdef DEBUG bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad); #endif np = getnetbyaddr(host_ad, AF_INET); if (np != NULL) { safe_strncpy(name, np->n_name, len); } } if (!ent && !np) { safe_strncpy(name, inet_ntoa(s_in->sin_addr), len); } pn = xmalloc(sizeof(struct addr)); pn->addr = *s_in; pn->next = INET_nn; pn->host = host; pn->name = xstrdup(name); INET_nn = pn; return 0; }
dir_information* open_directory(const char* dirname) { static dir_information dir; dir.dir=opendir(dirname); safe_strncpy(dir.base_path,dirname,CROSS_LEN); return dir.dir?&dir:NULL; }
int reset_soft_breaks (char *str, int len, int size, float zoom, int width, int *cursor, float *max_line_width) { char *buf; int ibuf; int nchar; int font_bit_width; int nlines; float line_width; int isrc, idst; int lastline; int dcursor = 0; /* the generic special text window code needs to know the maximum line length in pixels. This information is used but was previously throw away in this function. Others may fine it useful for setting the winow size, so pass back to the caller if they provide somewhere to store it. */ float local_max_line_width = 0; // error checking if (str == NULL || width <= 0 || size <= 0) { return 0; } /* strip existing soft breaks before we start, to avoid complicated code later */ for (isrc=0, idst=0; isrc<len; isrc++) { if (str[isrc] == '\r') { /* move the cursor back if after this point */ if ((cursor != NULL) && (isrc < *cursor)) dcursor--; } else str[idst++] = str[isrc]; } len = idst; str[len] = 0; /* allocate the working buffer so it can hold the maximum the source string can take. Previously, the fixed length buffer was sometimes not big enough. The code looked to attempt to cope but was floored. When ever the wrap caused more characters to be in the output, some of the source would be lost. This is still possable if the source size cannot take the extra characters. For example, try #glinfo and watch as the end characters are lost. At least characters are no longer lost wrap process. If you make size large enough for no character will be lost. Twice the actual string length is probably enough */ buf = (char *)calloc(size, sizeof(char)); nlines = 1; isrc = ibuf = idst = 0; line_width = 0; lastline = 0; // fill the buffer while (isrc < len && str[isrc] != '\0') { // see if it's an explicit line break if (str[isrc] == '\n') { nlines++; if (line_width > local_max_line_width) local_max_line_width = line_width; line_width = 0; } else { font_bit_width = (int) (0.5f + get_char_width (str[isrc]) * 11.0f * zoom / 12.0f); if (line_width + font_bit_width >= width) { // search back for a space for (nchar = 0; ibuf-nchar-1 > lastline; nchar++) { if (buf[ibuf-nchar-1] == ' ') { break; } } if (ibuf-nchar-1 <= lastline) // no space found, introduce a break in // the middle of the word nchar = 0; // introduce the break, and reset the counters ibuf -= nchar; isrc -= nchar; buf[ibuf] = '\r'; nlines++; ibuf++; if (cursor && isrc < *cursor) { dcursor++; } if (ibuf >= size - 1) { break; } if (line_width > local_max_line_width) local_max_line_width = line_width; lastline = ibuf; line_width = font_bit_width; } else { line_width += font_bit_width; } } // copy the character into the buffer buf[ibuf] = str[isrc]; isrc++; ibuf++; if (ibuf >= size - 1) { break; } } safe_strncpy(str, buf, size * sizeof(char)); str[size-1] = '\0'; if (cursor) { *cursor += dcursor; if(*cursor > size-1) { /* If there's a better way to detect this, please do */ *cursor = size-1; } } free(buf); if (line_width > local_max_line_width) local_max_line_width = line_width; if (max_line_width!=NULL) *max_line_width = local_max_line_width; return nlines; }
static void func_state(char *buf, int size, const procps_status_t *ps) { safe_strncpy(buf, ps->state, size+1); }
int zcip_main(int argc UNUSED_PARAM, char **argv) { int state; char *r_opt; unsigned opts; // ugly trick, but I want these zeroed in one go struct { const struct in_addr null_ip; const struct ether_addr null_addr; struct in_addr ip; struct ifreq ifr; int timeout_ms; /* must be signed */ unsigned conflicts; unsigned nprobes; unsigned nclaims; int ready; int verbose; } L; #define null_ip (L.null_ip ) #define null_addr (L.null_addr ) #define ip (L.ip ) #define ifr (L.ifr ) #define timeout_ms (L.timeout_ms) #define conflicts (L.conflicts ) #define nprobes (L.nprobes ) #define nclaims (L.nclaims ) #define ready (L.ready ) #define verbose (L.verbose ) memset(&L, 0, sizeof(L)); #define FOREGROUND (opts & 1) #define QUIT (opts & 2) // parse commandline: prog [options] ifname script // exactly 2 args; -v accumulates and implies -f opt_complementary = "=2:vv:vf"; opts = getopt32(argv, "fqr:v", &r_opt, &verbose); #if !BB_MMU // on NOMMU reexec early (or else we will rerun things twice) if (!FOREGROUND) bb_daemonize_or_rexec(0 /*was: DAEMON_CHDIR_ROOT*/, argv); #endif // open an ARP socket // (need to do it before openlog to prevent openlog from taking // fd 3 (sock_fd==3)) xmove_fd(xsocket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)), sock_fd); if (!FOREGROUND) { // do it before all bb_xx_msg calls openlog(applet_name, 0, LOG_DAEMON); logmode |= LOGMODE_SYSLOG; } if (opts & 4) { // -r n.n.n.n if (inet_aton(r_opt, &ip) == 0 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR ) { bb_error_msg_and_die("invalid link address"); } } argv += optind - 1; /* Now: argv[0]:junk argv[1]:intf argv[2]:script argv[3]:NULL */ /* We need to make space for script argument: */ argv[0] = argv[1]; argv[1] = argv[2]; /* Now: argv[0]:intf argv[1]:script argv[2]:junk argv[3]:NULL */ #define argv_intf (argv[0]) xsetenv("interface", argv_intf); // initialize the interface (modprobe, ifup, etc) if (run(argv, "init", NULL)) return EXIT_FAILURE; // initialize saddr // saddr is: { u16 sa_family; u8 sa_data[14]; } //memset(&saddr, 0, sizeof(saddr)); //TODO: are we leaving sa_family == 0 (AF_UNSPEC)?! safe_strncpy(saddr.sa_data, argv_intf, sizeof(saddr.sa_data)); // bind to the interface's ARP socket xbind(sock_fd, &saddr, sizeof(saddr)); // get the interface's ethernet address //memset(&ifr, 0, sizeof(ifr)); strncpy_IFNAMSIZ(ifr.ifr_name, argv_intf); xioctl(sock_fd, SIOCGIFHWADDR, &ifr); memcpy(ð_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); // start with some stable ip address, either a function of // the hardware address or else the last address we used. // we are taking low-order four bytes, as top-order ones // aren't random enough. // NOTE: the sequence of addresses we try changes only // depending on when we detect conflicts. { uint32_t t; move_from_unaligned32(t, ((char *)ð_addr + 2)); srand(t); } if (ip.s_addr == 0) ip.s_addr = pick(); // FIXME cases to handle: // - zcip already running! // - link already has local address... just defend/update // daemonize now; don't delay system startup if (!FOREGROUND) { #if BB_MMU bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); #endif bb_info_msg("start, interface %s", argv_intf); } // run the dynamic address negotiation protocol, // restarting after address conflicts: // - start with some address we want to try // - short random delay // - arp probes to see if another host uses it // - arp announcements that we're claiming it // - use it // - defend it, within limits // exit if: // - address is successfully obtained and -q was given: // run "<script> config", then exit with exitcode 0 // - poll error (when does this happen?) // - read error (when does this happen?) // - sendto error (in arp()) (when does this happen?) // - revents & POLLERR (link down). run "<script> deconfig" first state = PROBE; while (1) { struct pollfd fds[1]; unsigned deadline_us; struct arp_packet p; int source_ip_conflict; int target_ip_conflict; fds[0].fd = sock_fd; fds[0].events = POLLIN; fds[0].revents = 0; // poll, being ready to adjust current timeout if (!timeout_ms) { timeout_ms = random_delay_ms(PROBE_WAIT); // FIXME setsockopt(sock_fd, SO_ATTACH_FILTER, ...) to // make the kernel filter out all packets except // ones we'd care about. } // set deadline_us to the point in time when we timeout deadline_us = MONOTONIC_US() + timeout_ms * 1000; VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", timeout_ms, argv_intf, nprobes, nclaims); switch (safe_poll(fds, 1, timeout_ms)) { default: //bb_perror_msg("poll"); - done in safe_poll return EXIT_FAILURE; // timeout case 0: VDBG("state = %d\n", state); switch (state) { case PROBE: // timeouts in the PROBE state mean no conflicting ARP packets // have been received, so we can progress through the states if (nprobes < PROBE_NUM) { nprobes++; VDBG("probe/%u %s@%s\n", nprobes, argv_intf, inet_ntoa(ip)); arp(/* ARPOP_REQUEST, */ /* ð_addr, */ null_ip, &null_addr, ip); timeout_ms = PROBE_MIN * 1000; timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); } else { // Switch to announce state. state = ANNOUNCE; nclaims = 0; VDBG("announce/%u %s@%s\n", nclaims, argv_intf, inet_ntoa(ip)); arp(/* ARPOP_REQUEST, */ /* ð_addr, */ ip, ð_addr, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; } break; case RATE_LIMIT_PROBE: // timeouts in the RATE_LIMIT_PROBE state mean no conflicting ARP packets // have been received, so we can move immediately to the announce state state = ANNOUNCE; nclaims = 0; VDBG("announce/%u %s@%s\n", nclaims, argv_intf, inet_ntoa(ip)); arp(/* ARPOP_REQUEST, */ /* ð_addr, */ ip, ð_addr, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; break; case ANNOUNCE: // timeouts in the ANNOUNCE state mean no conflicting ARP packets // have been received, so we can progress through the states if (nclaims < ANNOUNCE_NUM) { nclaims++; VDBG("announce/%u %s@%s\n", nclaims, argv_intf, inet_ntoa(ip)); arp(/* ARPOP_REQUEST, */ /* ð_addr, */ ip, ð_addr, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; } else { // Switch to monitor state. state = MONITOR; // link is ok to use earlier // FIXME update filters run(argv, "config", &ip); ready = 1; conflicts = 0; timeout_ms = -1; // Never timeout in the monitor state. // NOTE: all other exit paths // should deconfig ... if (QUIT) return EXIT_SUCCESS; } break; case DEFEND: // We won! No ARP replies, so just go back to monitor. state = MONITOR; timeout_ms = -1; conflicts = 0; break; default: // Invalid, should never happen. Restart the whole protocol. state = PROBE; ip.s_addr = pick(); timeout_ms = 0; nprobes = 0; nclaims = 0; break; } // switch (state) break; // case 0 (timeout) // packets arriving, or link went down case 1: // We need to adjust the timeout in case we didn't receive // a conflicting packet. if (timeout_ms > 0) { unsigned diff = deadline_us - MONOTONIC_US(); if ((int)(diff) < 0) { // Current time is greater than the expected timeout time. // Should never happen. VDBG("missed an expected timeout\n"); timeout_ms = 0; } else { VDBG("adjusting timeout\n"); timeout_ms = (diff / 1000) | 1; /* never 0 */ } } if ((fds[0].revents & POLLIN) == 0) { if (fds[0].revents & POLLERR) { // FIXME: links routinely go down; // this shouldn't necessarily exit. bb_error_msg("iface %s is down", argv_intf); if (ready) { run(argv, "deconfig", &ip); } return EXIT_FAILURE; } continue; } // read ARP packet if (safe_read(sock_fd, &p, sizeof(p)) < 0) { bb_perror_msg_and_die(bb_msg_read_error); } if (p.eth.ether_type != htons(ETHERTYPE_ARP)) continue; #ifdef DEBUG { struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; VDBG("%s recv arp type=%d, op=%d,\n", argv_intf, ntohs(p.eth.ether_type), ntohs(p.arp.arp_op)); VDBG("\tsource=%s %s\n", ether_ntoa(sha), inet_ntoa(*spa)); VDBG("\ttarget=%s %s\n", ether_ntoa(tha), inet_ntoa(*tpa)); } #endif if (p.arp.arp_op != htons(ARPOP_REQUEST) && p.arp.arp_op != htons(ARPOP_REPLY)) continue; source_ip_conflict = 0; target_ip_conflict = 0; if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0 && memcmp(&p.arp.arp_sha, ð_addr, ETH_ALEN) != 0 ) { source_ip_conflict = 1; } if (p.arp.arp_op == htons(ARPOP_REQUEST) && memcmp(p.arp.arp_tpa, &ip.s_addr, sizeof(struct in_addr)) == 0 && memcmp(&p.arp.arp_tha, ð_addr, ETH_ALEN) != 0 ) { target_ip_conflict = 1; } VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n", state, source_ip_conflict, target_ip_conflict); switch (state) { case PROBE: case ANNOUNCE: // When probing or announcing, check for source IP conflicts // and other hosts doing ARP probes (target IP conflicts). if (source_ip_conflict || target_ip_conflict) { conflicts++; if (conflicts >= MAX_CONFLICTS) { VDBG("%s ratelimit\n", argv_intf); timeout_ms = RATE_LIMIT_INTERVAL * 1000; state = RATE_LIMIT_PROBE; } // restart the whole protocol ip.s_addr = pick(); timeout_ms = 0; nprobes = 0; nclaims = 0; } break; case MONITOR: // If a conflict, we try to defend with a single ARP probe. if (source_ip_conflict) { VDBG("monitor conflict -- defending\n"); state = DEFEND; timeout_ms = DEFEND_INTERVAL * 1000; arp(/* ARPOP_REQUEST, */ /* ð_addr, */ ip, ð_addr, ip); } break; case DEFEND: // Well, we tried. Start over (on conflict). if (source_ip_conflict) { state = PROBE; VDBG("defend conflict -- starting over\n"); ready = 0; run(argv, "deconfig", &ip); // restart the whole protocol ip.s_addr = pick(); timeout_ms = 0; nprobes = 0; nclaims = 0; } break; default: // Invalid, should never happen. Restart the whole protocol. VDBG("invalid state -- starting over\n"); state = PROBE; ip.s_addr = pick(); timeout_ms = 0; nprobes = 0; nclaims = 0; break; } // switch state break; // case 1 (packets arriving) } // switch poll } // while (1) #undef argv_intf }
static void show_entry(struct utmpx *ut, int state, time_t dur_secs) { unsigned days, hours, mins; char duration[sizeof("(%u+02:02)") + sizeof(int)*3]; char login_time[17]; char logout_time[8]; const char *logout_str; const char *duration_str; time_t tmp; /* manpages say ut_tv.tv_sec *is* time_t, * but some systems have it wrong */ tmp = ut->ut_tv.tv_sec; safe_strncpy(login_time, ctime(&tmp), 17); tmp = dur_secs; snprintf(logout_time, 8, "- %s", ctime(&tmp) + 11); dur_secs = MAX(dur_secs - (time_t)ut->ut_tv.tv_sec, (time_t)0); /* unsigned int is easier to divide than time_t (which may be signed long) */ mins = dur_secs / 60; days = mins / (24*60); mins = mins % (24*60); hours = mins / 60; mins = mins % 60; // if (days) { sprintf(duration, "(%u+%02u:%02u)", days, hours, mins); // } else { // sprintf(duration, " (%02u:%02u)", hours, mins); // } logout_str = logout_time; duration_str = duration; switch (state) { case NORMAL: break; case LOGGED: logout_str = " still"; duration_str = "logged in"; break; case DOWN: logout_str = "- down "; break; case REBOOT: break; case CRASH: logout_str = "- crash"; break; case GONE: logout_str = " gone"; duration_str = "- no logout"; break; } printf(HEADER_FORMAT, ut->ut_user, ut->ut_line, show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, ut->ut_host, login_time, logout_str, duration_str); }