/* ________________________________________________________________________ */ int nslookup_main(int argc, char **argv) { struct hostent *host; /* * initialize DNS structure _res used in printing the default * name server and in the explicit name server option feature. */ res_init(); /* * We allow 1 or 2 arguments. * The first is the name to be looked up and the second is an * optional DNS server with which to do the lookup. * More than 3 arguments is an error to follow the pattern of the * standard nslookup */ if (argc < 2 || *argv[1]=='-' || argc > 3) bb_show_usage(); else if(argc == 3) set_default_dns(argv[2]); server_print(); if (is_ip_address(argv[1])) { host = gethostbyaddr_wrapper(argv[1]); } else { host = xgethostbyname(argv[1]); } hostent_fprint(host, "Name: "); return EXIT_SUCCESS; }
static void init_RemoteLog(void) { struct sockaddr_in remoteaddr; struct hostent *hostinfo; int len = sizeof(remoteaddr); memset(&remoteaddr, 0, len); remotefd = socket(AF_INET, SOCK_DGRAM, 0); if (remotefd < 0) { bb_error_msg_and_die("cannot create socket"); } hostinfo = xgethostbyname(RemoteHost); remoteaddr.sin_family = AF_INET; remoteaddr.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; remoteaddr.sin_port = htons(RemotePort); /* Since we are using UDP sockets, connect just sets the default host and port * for future operations */ if (0 != (connect(remotefd, (struct sockaddr *) &remoteaddr, len))) { bb_error_msg_and_die("cannot connect to remote host %s:%d", RemoteHost, RemotePort); } }
HTTPConnection * HTTPConnection_new_client(const char * host, uint16_t port) { struct in_addr ip_address; if (! inet_aton(host, &ip_address)) { /* it's a host name */ if (xgethostbyname(host, &ip_address) != 0) { return NULL; } } SOCKET s = socket(PF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { return NULL; } struct sockaddr_in a; a.sin_family = AF_INET; a.sin_port = htons(port); a.sin_addr = ip_address; if (connect(s, (struct sockaddr *) &a, sizeof(a)) < 0) { closesocket(s); return NULL; } return HTTPConnection_new(s); }
void bb_lookup_host(struct sockaddr_in *s_in, const char *host) { struct hostent *he; memset(s_in, 0, sizeof(struct sockaddr_in)); s_in->sin_family = AF_INET; he = xgethostbyname(host); memcpy(&(s_in->sin_addr), he->h_addr_list[0], he->h_length); }
static struct in_addr getserver(char * host) { struct in_addr addr; struct hostent * he; he = xgethostbyname(host); memcpy(&addr, he->h_addr, sizeof addr); TRACE(1, ("addr: %s\n", inet_ntoa(addr))); return addr; }
static void init_RemoteLog(void) { memset(&remoteaddr, 0, sizeof(remoteaddr)); remotefd = socket(AF_INET, SOCK_DGRAM, 0); if (remotefd < 0) { bb_error_msg("cannot create socket"); } remoteaddr.sin_family = AF_INET; remoteaddr.sin_addr = *(struct in_addr *) *(xgethostbyname(RemoteHost))->h_addr_list; remoteaddr.sin_port = htons(RemotePort); }
static void init_RemoteLog(void) { memset(&remoteaddr, 0, sizeof(remoteaddr)); remotefd = socket(AF_INET, SOCK_DGRAM, 0); if (remotefd < 0) { /* BRCM begin */ if ((local_logging == FALSE) && (circular_logging == FALSE)) bb_error_msg_and_die("cannot create socket"); else bb_perror_msg("cannot create socket"); /* BRCM end */ } remoteaddr.sin_family = AF_INET; remoteaddr.sin_addr = *(struct in_addr *) *(xgethostbyname(RemoteHost))->h_addr_list; remoteaddr.sin_port = htons(RemotePort); }
static void tlist_add(char *str) { char *hostname; int port; struct hostent *host; TListNode n = NEW(TListNode); hostname = str; if((str = strchr(hostname, ':')) != NULL) { *str++ = '\0'; port = atoi(str); } else port = DEFAULT_TRACKER_PORT; memset(&(n->sin), '\0', sizeof(struct sockaddr_in)); if((n->sin.sin_addr.s_addr = inet_addr(hostname)) < 0) { if((host = xgethostbyname(hostname)) == NULL) goto err; memcpy(&n->sin.sin_addr, host->h_addr, host->h_length); xfree(host); } n->sin.sin_family = AF_INET; n->sin.sin_port = htons(port); if((n->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) goto err; n->l = tlist; tlist = n; tlist_count++; return; err: log("!!! Couldn't resolve tracker: %s", hostname); xfree(n); }
static void /* not inline */ send_probe(int seq, int ttl) { struct opacket *op = outpacket; struct ip *ip = &op->ip; struct udphdr *up = &op->udp; int i; struct timezone tz; #if defined (DMP_TRACEROUTE_1) int dataSize = datalen -12; /* Minus some parameters' length in struct opacket*/ #endif ip->ip_off = 0; ip->ip_hl = sizeof(*ip) >> 2; ip->ip_p = IPPROTO_UDP; #if defined (DMP_TRACEROUTE_1) ip->ip_len = dataSize; #else ip->ip_len = datalen; #endif ip->ip_ttl = ttl; ip->ip_v = IPVERSION; ip->ip_id = htons(ident+seq); up->source = htons(ident); up->dest = htons(port+seq); #if defined (DMP_TRACEROUTE_1) up->len = htons((u_short)(dataSize - sizeof(struct ip))); #else up->len = htons((u_short)(datalen - sizeof(struct ip))); #endif up->check = 0; op->seq = seq; op->ttl = ttl; (void) gettimeofday(&op->tv, &tz); #if defined (DMP_TRACEROUTE_1) i = sendto(sndsock, (char *)outpacket, dataSize, 0, &whereto, sizeof(struct sockaddr)); #else i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto, sizeof(struct sockaddr)); #endif #if defined (DMP_TRACEROUTE_1) if (i < 0 || i != dataSize) { #else if (i < 0 || i != datalen) { #endif if (i<0) perror("sendto"); #if defined (DMP_TRACEROUTE_1) printf("traceroute: wrote %s %d chars, ret=%d\n", hostname, dataSize, i); #else printf("traceroute: wrote %s %d chars, ret=%d\n", hostname, datalen, i); #endif (void) fflush(stdout); } } int #ifndef CONFIG_TRACEROUTE main(int argc, char *argv[]) #else traceroute_main(int argc, char *argv[]) #endif { extern char *optarg; extern int optind; struct hostent *hp; struct sockaddr_in from, *to; int ch, i, on, probe, seq, tos, ttl; int options = 0; /* socket options */ char *source = 0; int nprobes = 3; #if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000) int ttl_set_flag = 0; #endif #if defined(AEI_VDSL_CUSTOMER_NCS) int failcount = 0; #endif #if defined(DMP_TRACEROUTE_1) unsigned int repTime; char strRepTime[16]; TraceRouteDataMsgBody traceRouteInfo; memset(&traceRouteInfo, 0 , sizeof(TraceRouteDataMsgBody)); TraceRouteDataMsgBody *pTraceRouteInfo = &traceRouteInfo; cmsMsg_init(EID_TRACEROUTE, &msgHandle); #endif on = 1; seq = tos = 0; to = (struct sockaddr_in *)&whereto; while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF) switch(ch) { case 'd': #ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG options |= SO_DEBUG; #endif break; case 'm': max_ttl = atoi(optarg); #if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000) ttl_set_flag = 1; #endif if (max_ttl <= 1) bb_error_msg_and_die("max ttl must be >1."); break; case 'n': nflag++; break; case 'p': port = atoi(optarg); if (port < 1) bb_error_msg_and_die("port must be >0."); break; case 'q': nprobes = atoi(optarg); if (nprobes < 1) bb_error_msg_and_die("nprobes must be >0."); break; case 'r': options |= SO_DONTROUTE; break; case 's': /* * set the ip source address of the outbound * probe (e.g., on a multi-homed host). */ source = optarg; break; case 't': tos = atoi(optarg); if (tos < 0 || tos > 255) bb_error_msg_and_die("tos must be 0 to 255."); break; case 'v': #ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE verbose++; #endif break; case 'w': waittime = atoi(optarg); if (waittime <= 1) bb_error_msg_and_die("wait must be >1 sec."); break; default: bb_show_usage(); } argc -= optind; argv += optind; if (argc < 1) bb_show_usage(); setlinebuf (stdout); memset(&whereto, 0, sizeof(struct sockaddr)); #if defined(DMP_TRACEROUTE_1) hp = gethostbyname(*argv); if (*++argv) { requesterId = atoi(*argv); } if (hp == NULL) { AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_CannotResolveHostName); bb_herror_msg_and_die("%s", *--argv); } #else hp = xgethostbyname(*argv); #endif to->sin_family = hp->h_addrtype; memcpy(&to->sin_addr, hp->h_addr, hp->h_length); hostname = (char *)hp->h_name; if (*++argv) datalen = atoi(*argv); #if defined (DMP_TRACEROUTE_1) if (datalen == 0) { datalen = 40; /*Default data length*/ } #endif if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket)) bb_error_msg_and_die("packet size must be 0 <= s < %d.", MAXPACKET - sizeof(struct opacket)); datalen += sizeof(struct opacket); outpacket = (struct opacket *)xmalloc((unsigned)datalen); memset(outpacket, 0, datalen); outpacket->ip.ip_dst = to->sin_addr; outpacket->ip.ip_tos = tos; #if defined(DMP_TRACEROUTE_1) outpacket->ip.ip_tos = (outpacket->ip.ip_tos)<<2; #endif outpacket->ip.ip_v = IPVERSION; outpacket->ip.ip_id = 0; ident = (getpid() & 0xffff) | 0x8000; if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); s = create_icmp_socket(); #ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG if (options & SO_DEBUG) (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); #endif if (options & SO_DONTROUTE) (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on)); #ifdef SO_SNDBUF if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen, sizeof(datalen)) < 0) bb_perror_msg_and_die("SO_SNDBUF"); #endif #ifdef IP_HDRINCL if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) bb_perror_msg_and_die("IP_HDRINCL"); #endif #ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG if (options & SO_DEBUG) (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); #endif if (options & SO_DONTROUTE) (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on)); if (source) { memset(&from, 0, sizeof(struct sockaddr)); from.sin_family = AF_INET; from.sin_addr.s_addr = inet_addr(source); if (from.sin_addr.s_addr == -1) bb_error_msg_and_die("unknown host %s", source); outpacket->ip.ip_src = from.sin_addr; #ifndef IP_HDRINCL if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0) bb_perror_msg_and_die("bind"); #endif } fprintf(stderr, "traceroute to %s (%s)", hostname, inet_ntoa(to->sin_addr)); if (source) fprintf(stderr, " from %s", source); fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen); for (ttl = 1; ttl <= max_ttl; ++ttl) { u_long lastaddr = 0; int got_there = 0; int unreachable = 0; #if defined(DMP_TRACEROUTE_1) pTraceRouteInfo->routeHopsNumberOfEntries++; #endif printf("%2d ", ttl); for (probe = 0; probe < nprobes; ++probe) { int cc, reset_timer; struct timeval t1, t2; struct timezone tz; struct ip *ip; (void) gettimeofday(&t1, &tz); send_probe(++seq, ttl); reset_timer = 1; while ((cc = wait_for_reply(s, &from, reset_timer)) != 0) { (void) gettimeofday(&t2, &tz); if ((i = packet_ok(packet, cc, &from, seq))) { reset_timer = 1; if (from.sin_addr.s_addr != lastaddr) { print(packet, cc, &from); lastaddr = from.sin_addr.s_addr; } printf(" %g ms", deltaT(&t1, &t2)); #if defined(DMP_TRACEROUTE_1) struct icmp *hopIcp; int hopHlen; struct ip *hopIp; hopIp = (struct ip *) packet; hopHlen = hopIp->ip_hl << 2; hopIcp = (struct icmp *)(packet + hopHlen); repTime = ((int)(t2.tv_sec - t1.tv_sec) * 1000 + (int)(t2.tv_usec - t1.tv_usec) / 1000); sprintf(strRepTime, "%d,", repTime); pTraceRouteInfo->responseTime+=repTime; pTraceRouteInfo->routeHops[ttl-1].hopErrorCode = hopIcp->icmp_code; sprintf(pTraceRouteInfo->routeHops[ttl-1].hopHost, "%s", inet_ntoa(from.sin_addr)); sprintf(pTraceRouteInfo->routeHops[ttl-1].hopHostAddress, "%s", inet_ntoa(from.sin_addr)); strcat(pTraceRouteInfo->routeHops[ttl-1].hopRTTimes, strRepTime); #endif switch(i - 1) { case ICMP_UNREACH_PORT: ip = (struct ip *)packet; if (ip->ip_ttl <= 1) printf(" !"); ++got_there; break; case ICMP_UNREACH_NET: ++unreachable; printf(" !N"); break; case ICMP_UNREACH_HOST: ++unreachable; printf(" !H"); break; case ICMP_UNREACH_PROTOCOL: ++got_there; printf(" !P"); break; case ICMP_UNREACH_NEEDFRAG: ++unreachable; printf(" !F"); break; case ICMP_UNREACH_SRCFAIL: ++unreachable; printf(" !S"); break; } break; } else reset_timer = 0; } if (cc == 0) { #if defined(AEI_VDSL_CUSTOMER_NCS) failcount++; #endif printf(" *"); } #if defined(AEI_VDSL_CUSTOMER_NCS) else failcount=0; #endif (void) fflush(stdout); } putchar('\n'); if (got_there || (unreachable && unreachable >= nprobes-1)) { #if defined(DMP_TRACEROUTE_1) if (got_there) { AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Complete); } else if (unreachable && unreachable >= nprobes-1) { AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded); } #endif return 0; } #if defined(AEI_VDSL_CUSTOMER_NCS) #if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000) if (failcount >= nprobes*2&&ttl_set_flag==0) #else if (failcount >= nprobes*2) #endif { #if defined(DMP_TRACEROUTE_1) AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded); #endif return 0; } #endif } #if defined(DMP_TRACEROUTE_1) AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded); #endif return 0; }
int hostname_main(int argc UNUSED_PARAM, char **argv) { enum { OPT_d = 0x1, OPT_f = 0x2, OPT_i = 0x4, OPT_s = 0x8, OPT_F = 0x10, OPT_dfi = 0x7, }; unsigned opts; char *buf; char *hostname_str; #if ENABLE_LONG_OPTS applet_long_options = "domain\0" No_argument "d" "fqdn\0" No_argument "f" //Enable if seen in active use in some distro: // "long\0" No_argument "f" // "ip-address\0" No_argument "i" // "short\0" No_argument "s" // "verbose\0" No_argument "v" "file\0" No_argument "F" ; #endif /* dnsdomainname from net-tools 1.60, hostname 1.100 (2001-04-14), * supports hostname's options too (not just -v as manpage says) */ opts = getopt32(argv, "dfisF:v", &hostname_str); argv += optind; buf = safe_gethostname(); if (applet_name[0] == 'd') /* dnsdomainname? */ opts = OPT_d; if (opts & OPT_dfi) { /* Cases when we need full hostname (or its part) */ struct hostent *hp; char *p; hp = xgethostbyname(buf); p = strchrnul(hp->h_name, '.'); if (opts & OPT_f) { puts(hp->h_name); } else if (opts & OPT_s) { *p = '\0'; puts(hp->h_name); } else if (opts & OPT_d) { if (*p) puts(p + 1); } else /*if (opts & OPT_i)*/ { if (hp->h_length == sizeof(struct in_addr)) { struct in_addr **h_addr_list = (struct in_addr **)hp->h_addr_list; while (*h_addr_list) { printf(h_addr_list[1] ? "%s " : "%s", inet_ntoa(**h_addr_list)); h_addr_list++; } bb_putchar('\n'); } } } else if (opts & OPT_s) { strchrnul(buf, '.')[0] = '\0'; puts(buf); } else if (opts & OPT_F) { /* Set the hostname */ do_sethostname(hostname_str, 1); } else if (argv[0]) { /* Set the hostname */ do_sethostname(argv[0], 0); } else { /* Just print the current hostname */ puts(buf); } if (ENABLE_FEATURE_CLEAN_UP) free(buf); return EXIT_SUCCESS; }
int sendmail_main(int argc UNUSED_PARAM, char **argv) { char *opt_connect = opt_connect; char *opt_from = NULL; char *s; llist_t *list = NULL; char *host = sane_address(safe_gethostname()); unsigned nheaders = 0; int code; enum { HDR_OTHER = 0, HDR_TOCC, HDR_BCC, } last_hdr = 0; int check_hdr; int has_to = 0; enum { //--- standard options OPT_t = 1 << 0, // read message for recipients, append them to those on cmdline OPT_f = 1 << 1, // sender address OPT_o = 1 << 2, // various options. -oi IMPLIED! others are IGNORED! OPT_i = 1 << 3, // IMPLIED! //--- BB specific options OPT_w = 1 << 4, // network timeout OPT_H = 1 << 5, // use external connection helper OPT_S = 1 << 6, // specify connection string OPT_a = 1 << 7, // authentication tokens OPT_v = 1 << 8, // verbosity }; // init global variables INIT_G(); // save initial stdin since body is piped! xdup2(STDIN_FILENO, 3); G.fp0 = xfdopen_for_read(3); // parse options // -v is a counter, -H and -S are mutually exclusive, -a is a list opt_complementary = "vv:w+:H--S:S--H:a::"; // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility, // it is still under development. opts = getopt32(argv, "tf:o:iw:H:S:a::v", &opt_from, NULL, &timeout, &opt_connect, &opt_connect, &list, &verbose); //argc -= optind; argv += optind; // process -a[upm]<token> options if ((opts & OPT_a) && !list) bb_show_usage(); while (list) { char *a = (char *) llist_pop(&list); if ('u' == a[0]) G.user = xstrdup(a+1); if ('p' == a[0]) G.pass = xstrdup(a+1); // N.B. we support only AUTH LOGIN so far //if ('m' == a[0]) // G.method = xstrdup(a+1); } // N.B. list == NULL here //bb_info_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv); // connect to server // connection helper ordered? -> if (opts & OPT_H) { const char *args[] = { "sh", "-c", opt_connect, NULL }; // plug it in launch_helper(args); // Now: // our stdout will go to helper's stdin, // helper's stdout will be available on our stdin. // Wait for initial server message. // If helper (such as openssl) invokes STARTTLS, the initial 220 // is swallowed by helper (and not repeated after TLS is initiated). // We will send NOOP cmd to server and check the response. // We should get 220+250 on plain connection, 250 on STARTTLSed session. // // The problem here is some servers delay initial 220 message, // and consider client to be a spammer if it starts sending cmds // before 220 reached it. The code below is unsafe in this regard: // in non-STARTTLSed case, we potentially send NOOP before 220 // is sent by server. // Ideas? (--delay SECS opt? --assume-starttls-helper opt?) code = smtp_check("NOOP", -1); if (code == 220) // we got 220 - this is not STARTTLSed connection, // eat 250 response to our NOOP smtp_check(NULL, 250); else if (code != 250) bb_error_msg_and_die("SMTP init failed"); } else { // vanilla connection int fd; // host[:port] not explicitly specified? -> use $SMTPHOST // no $SMTPHOST? -> use localhost if (!(opts & OPT_S)) { opt_connect = getenv("SMTPHOST"); if (!opt_connect) opt_connect = (char *)"127.0.0.1"; } // do connect fd = create_and_connect_stream_or_die(opt_connect, 25); // and make ourselves a simple IO filter xmove_fd(fd, STDIN_FILENO); xdup2(STDIN_FILENO, STDOUT_FILENO); // Wait for initial server 220 message smtp_check(NULL, 220); } // we should start with modern EHLO if (250 != smtp_checkp("EHLO %s", host, -1)) smtp_checkp("HELO %s", host, 250); // perform authentication if (opts & OPT_a) { smtp_check("AUTH LOGIN", 334); // we must read credentials unless they are given via -a[up] options if (!G.user || !G.pass) get_cred_or_die(4); encode_base64(NULL, G.user, NULL); smtp_check("", 334); encode_base64(NULL, G.pass, NULL); smtp_check("", 235); } // set sender // N.B. we have here a very loosely defined algorythm // since sendmail historically offers no means to specify secrets on cmdline. // 1) server can require no authentication -> // we must just provide a (possibly fake) reply address. // 2) server can require AUTH -> // we must provide valid username and password along with a (possibly fake) reply address. // For the sake of security username and password are to be read either from console or from a secured file. // Since reading from console may defeat usability, the solution is either to read from a predefined // file descriptor (e.g. 4), or again from a secured file. // got no sender address? use auth name, then UID username as a last resort if (!opt_from) { opt_from = xasprintf("%s@%s", G.user ? G.user : xuid2uname(getuid()), xgethostbyname(host)->h_name); } free(host); smtp_checkp("MAIL FROM:<%s>", opt_from, 250); // process message // read recipients from message and add them to those given on cmdline. // this means we scan stdin for To:, Cc:, Bcc: lines until an empty line // and then use the rest of stdin as message body code = 0; // set "analyze headers" mode while ((s = xmalloc_fgetline(G.fp0)) != NULL) { dump: // put message lines doubling leading dots if (code) { // escape leading dots // N.B. this feature is implied even if no -i (-oi) switch given // N.B. we need to escape the leading dot regardless of // whether it is single or not character on the line if ('.' == s[0] /*&& '\0' == s[1] */) bb_putchar('.'); // dump read line send_r_n(s); free(s); continue; } // analyze headers // To: or Cc: headers add recipients check_hdr = (0 == strncasecmp("To:", s, 3)); has_to |= check_hdr; if (opts & OPT_t) { if (check_hdr || 0 == strncasecmp("Bcc:" + 1, s, 3)) { rcptto_list(s+3); last_hdr = HDR_TOCC; goto addheader; } // Bcc: header adds blind copy (hidden) recipient if (0 == strncasecmp("Bcc:", s, 4)) { rcptto_list(s+4); free(s); last_hdr = HDR_BCC; continue; // N.B. Bcc: vanishes from headers! } } check_hdr = (list && isspace(s[0])); if (strchr(s, ':') || check_hdr) { // other headers go verbatim // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines. // Continuation is denoted by prefixing additional lines with whitespace(s). // Thanks (stefan.seyfried at googlemail.com) for pointing this out. if (check_hdr && last_hdr != HDR_OTHER) { rcptto_list(s+1); if (last_hdr == HDR_BCC) continue; // N.B. Bcc: vanishes from headers! } else { last_hdr = HDR_OTHER; } addheader: // N.B. we allow MAX_HEADERS generic headers at most to prevent attacks if (MAX_HEADERS && ++nheaders >= MAX_HEADERS) goto bail; llist_add_to_end(&list, s); } else { // a line without ":" (an empty line too, by definition) doesn't look like a valid header // so stop "analyze headers" mode reenter: // put recipients specified on cmdline check_hdr = 1; while (*argv) { char *t = sane_address(*argv); rcptto(t); //if (MAX_HEADERS && ++nheaders >= MAX_HEADERS) // goto bail; if (!has_to) { const char *hdr; if (check_hdr && argv[1]) hdr = "To: %s,"; else if (check_hdr) hdr = "To: %s"; else if (argv[1]) hdr = "To: %s," + 3; else hdr = "To: %s" + 3; llist_add_to_end(&list, xasprintf(hdr, t)); check_hdr = 0; } argv++; } // enter "put message" mode // N.B. DATA fails iff no recipients were accepted (or even provided) // in this case just bail out gracefully if (354 != smtp_check("DATA", -1)) goto bail; // dump the headers while (list) { send_r_n((char *) llist_pop(&list)); } // stop analyzing headers code++; // N.B. !s means: we read nothing, and nothing to be read in the future. // just dump empty line and break the loop if (!s) { send_r_n(""); break; } // go dump message body // N.B. "s" already contains the first non-header line, so pretend we read it from input goto dump; } } // odd case: we didn't stop "analyze headers" mode -> message body is empty. Reenter the loop // N.B. after reenter code will be > 0 if (!code) goto reenter; // finalize the message smtp_check(".", 250); bail: // ... and say goodbye smtp_check("QUIT", 221); // cleanup if (ENABLE_FEATURE_CLEAN_UP) fclose(G.fp0); return EXIT_SUCCESS; }
int nc_main(int argc, char **argv) { int do_listen = 0, lport = 0, tmpfd, opt, sfd, x; char buf[BUFSIZ]; #ifdef GAPING_SECURITY_HOLE char * pr00gie = NULL; #endif struct sockaddr_in address; struct hostent *hostinfo; fd_set readfds, testfds; while ((opt = getopt(argc, argv, "lp:")) > 0) { switch (opt) { case 'l': do_listen++; break; case 'p': lport = atoi(optarg); break; #ifdef GAPING_SECURITY_HOLE case 'e': pr00gie = optarg; break; #endif default: show_usage(); } } #ifdef GAPING_SECURITY_HOLE if (pr00gie) { /* won't need stdin */ close (fileno(stdin)); } #endif /* GAPING_SECURITY_HOLE */ if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc)) show_usage(); if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) perror_msg_and_die("socket"); x = 1; if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1) perror_msg_and_die ("reuseaddr failed"); address.sin_family = AF_INET; if (lport != 0) { memset(&address.sin_addr, 0, sizeof(address.sin_addr)); address.sin_port = htons(lport); if (bind(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) perror_msg_and_die("bind"); } if (do_listen) { socklen_t addrlen = sizeof(address); if (listen(sfd, 1) < 0) perror_msg_and_die("listen"); if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0) perror_msg_and_die("accept"); close(sfd); sfd = tmpfd; } else { hostinfo = xgethostbyname(argv[optind]); address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; address.sin_port = htons(atoi(argv[optind+1])); if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) perror_msg_and_die("connect"); } #ifdef GAPING_SECURITY_HOLE /* -e given? */ if (pr00gie) { dup2(sfd, 0); close(sfd); dup2 (0, 1); dup2 (0, 2); execl (pr00gie, pr00gie, NULL); /* Don't print stuff or it will go over the wire.... */ _exit(-1); } #endif /* GAPING_SECURITY_HOLE */ FD_ZERO(&readfds); FD_SET(sfd, &readfds); FD_SET(STDIN_FILENO, &readfds); while (1) { int fd; int ofd; int nread; testfds = readfds; if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0) perror_msg_and_die("select"); for (fd = 0; fd < FD_SETSIZE; fd++) { if (FD_ISSET(fd, &testfds)) { if ((nread = safe_read(fd, buf, sizeof(buf))) < 0) perror_msg_and_die("read"); if (fd == sfd) { if (nread == 0) exit(0); ofd = STDOUT_FILENO; } else { if (nread == 0) shutdown(sfd, 1); ofd = sfd; } if (full_write(ofd, buf, nread) < 0) perror_msg_and_die("write"); } } } }
int nc_main(int argc, char **argv) { int do_listen = 0, lport = 0, delay = 0, wsecs = 0, tmpfd, opt, sfd, x; #ifdef CONFIG_NC_GAPING_SECURITY_HOLE char *pr00gie = NULL; #endif struct sockaddr_in address; struct hostent *hostinfo; fd_set readfds, testfds; while ((opt = getopt(argc, argv, "lp:i:e:w:")) > 0) { switch (opt) { case 'l': do_listen++; break; case 'p': lport = bb_lookup_port(optarg, "tcp", 0); break; case 'i': delay = atoi(optarg); break; #ifdef CONFIG_NC_GAPING_SECURITY_HOLE case 'e': pr00gie = optarg; break; #endif case 'w': wsecs = atoi(optarg); break; default: bb_show_usage(); } } if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc)) bb_show_usage(); sfd = bb_xsocket(AF_INET, SOCK_STREAM, 0); x = 1; if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1) bb_perror_msg_and_die("reuseaddr"); address.sin_family = AF_INET; if (wsecs) { signal(SIGALRM, timeout); alarm(wsecs); } if (lport != 0) { memset(&address.sin_addr, 0, sizeof(address.sin_addr)); address.sin_port = lport; bb_xbind(sfd, (struct sockaddr *) &address, sizeof(address)); } if (do_listen) { socklen_t addrlen = sizeof(address); bb_xlisten(sfd, 1); if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0) bb_perror_msg_and_die("accept"); close(sfd); sfd = tmpfd; } else { hostinfo = xgethostbyname(argv[optind]); address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; address.sin_port = bb_lookup_port(argv[optind+1], "tcp", 0); if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) bb_perror_msg_and_die("connect"); } if (wsecs) { alarm(0); signal(SIGALRM, SIG_DFL); } #ifdef CONFIG_NC_GAPING_SECURITY_HOLE /* -e given? */ if (pr00gie) { dup2(sfd, 0); close(sfd); dup2(0, 1); dup2(0, 2); execl(pr00gie, pr00gie, NULL); /* Don't print stuff or it will go over the wire.... */ _exit(-1); } #endif /* CONFIG_NC_GAPING_SECURITY_HOLE */ FD_ZERO(&readfds); FD_SET(sfd, &readfds); FD_SET(STDIN_FILENO, &readfds); while (1) { int fd; int ofd; int nread; testfds = readfds; if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0) bb_perror_msg_and_die("select"); for (fd = 0; fd < FD_SETSIZE; fd++) { if (FD_ISSET(fd, &testfds)) { if ((nread = safe_read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1))) < 0) { bb_perror_msg_and_die(bb_msg_read_error); } if (fd == sfd) { if (nread == 0) exit(0); ofd = STDOUT_FILENO; } else { if (nread <= 0) { shutdown(sfd, 1 /* send */ ); close(STDIN_FILENO); FD_CLR(STDIN_FILENO, &readfds); } ofd = sfd; } if (bb_full_write(ofd, bb_common_bufsiz1, nread) < 0) bb_perror_msg_and_die(bb_msg_write_error); if (delay > 0) { sleep(delay); } } } } }
int hostname_main(int argc, char **argv) { int opt; int type = 0; struct hostent *hp; char *filename = NULL; char buf[255]; char *p = NULL; if (argc < 1) bb_show_usage(); while ((opt = getopt(argc, argv, "dfisF:")) > 0) { switch (opt) { case 'd': case 'f': case 'i': case 's': type = opt; break; case 'F': filename = optarg; break; default: bb_show_usage(); } } /* Output in desired format */ if (type != 0) { gethostname(buf, 255); hp = xgethostbyname(buf); p = strchr(hp->h_name, '.'); if (type == 'f') { puts(hp->h_name); } else if (type == 's') { if (p != NULL) { *p = 0; } puts(hp->h_name); } else if (type == 'd') { if (p) puts(p + 1); } else if (type == 'i') { while (hp->h_addr_list[0]) { printf("%s ", inet_ntoa(*(struct in_addr *) (*hp->h_addr_list++))); } printf("\n"); } } /* Set the hostname */ else if (filename != NULL) { do_sethostname(filename, 1); } else if (optind < argc) { do_sethostname(argv[optind], 0); } /* Or if all else fails, * just print the current hostname */ else { gethostname(buf, 255); puts(buf); } return(0); }
void log_remote_message(syslogd_remote_config_t *remote, const char *msg) { remote_info_t *info; debug_printf("log_remote_message(remote=%p, msg=%s)", remote, msg); debug_printf("host=%s", remote->host); if (remote_socket == -1) { remote_socket = socket(AF_INET, SOCK_DGRAM, 0); if (remote_socket < 0) { bb_perror_msg_and_die("syslogd: cannot create socket"); } } if (!remote->common.priv) { struct hostent *hostinfo = 0; if (remote->host) { debug_printf("Getting ip address for server: %s", remote->host); hostinfo = xgethostbyname(remote->host); debug_printf("Got hostinfo=%p", hostinfo); } if (!hostinfo || !hostinfo->h_addr_list) { debug_printf("Disabling remote target because we couldn't resolve %s", remote->host); remote->common.level = LOG_NONE; return; } debug_printf("Allocating priv"); remote->common.priv = info = malloc(sizeof(*info)); memset(&info->saremote, 0, sizeof(info->saremote)); debug_printf("Creating socket"); debug_printf("Setting up saremote"); info->saremote.sin_family = AF_INET; debug_printf("%s:%d", __FILE__, __LINE__); info->saremote.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; debug_printf("%s:%d", __FILE__, __LINE__); info->saremote.sin_port = htons(remote->port); debug_printf("%s:%d", __FILE__, __LINE__); } else { debug_printf("%s:%d", __FILE__, __LINE__); info = (remote_info_t *)remote->common.priv; } debug_printf("%s:%d", __FILE__, __LINE__); for (;;) { debug_printf("%s:%d", __FILE__, __LINE__); if (-1 == sendto(remote_socket, msg, strlen(msg), 0, (struct sockaddr *)&info->saremote, sizeof(info->saremote))) { time_t now; static time_t last_message_time = 0; debug_printf("%s:%d", __FILE__, __LINE__); if (errno == EINTR) { debug_printf("%s:%d", __FILE__, __LINE__); continue; } debug_printf("%s:%d", __FILE__, __LINE__); /* * Throttle these messages so that we don't get one after * every message if the network is down */ now = time(0); if (now - last_message_time > MIN_ERRMSG_INTERVAL) { debug_printf("syslogd: cannot write to remote file handle on %s:%d - %m\n", remote->host, remote->port); debug_printf("host=%s", remote->host); debug_printf("port=%d", remote->port); syslog_local_message("syslogd: cannot write to remote file handle on %s:%d - %m\n", remote->host, remote->port); last_message_time = now; } } debug_printf("%s:%d", __FILE__, __LINE__); break; } }
traceroute_main(int argc, char *argv[]) #endif { extern char *optarg; extern int optind; struct hostent *hp; struct sockaddr_in from, *to; int ch, i, on, probe, seq, tos, ttl; int options = 0; /* socket options */ char *source = 0; int nprobes = 3; on = 1; seq = tos = 0; to = (struct sockaddr_in *)&whereto; while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF) switch(ch) { case 'd': #ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG options |= SO_DEBUG; #endif break; case 'm': max_ttl = atoi(optarg); if (max_ttl <= 1) bb_error_msg_and_die("max ttl must be >1."); break; case 'n': nflag++; break; case 'p': port = atoi(optarg); if (port < 1) bb_error_msg_and_die("port must be >0."); break; case 'q': nprobes = atoi(optarg); if (nprobes < 1) bb_error_msg_and_die("nprobes must be >0."); break; case 'r': options |= SO_DONTROUTE; break; case 's': /* * set the ip source address of the outbound * probe (e.g., on a multi-homed host). */ source = optarg; break; case 't': tos = atoi(optarg); if (tos < 0 || tos > 255) bb_error_msg_and_die("tos must be 0 to 255."); break; case 'v': #ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE verbose++; #endif break; case 'w': waittime = atoi(optarg); if (waittime <= 1) bb_error_msg_and_die("wait must be >1 sec."); break; default: bb_show_usage(); } argc -= optind; argv += optind; if (argc < 1) bb_show_usage(); setlinebuf (stdout); memset(&whereto, 0, sizeof(struct sockaddr)); hp = xgethostbyname(*argv); to->sin_family = hp->h_addrtype; memcpy(&to->sin_addr, hp->h_addr, hp->h_length); hostname = (char *)hp->h_name; if (*++argv) datalen = atoi(*argv); if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket)) bb_error_msg_and_die("packet size must be 0 <= s < %d.", MAXPACKET - sizeof(struct opacket)); datalen += sizeof(struct opacket); outpacket = (struct opacket *)xmalloc((unsigned)datalen); memset(outpacket, 0, datalen); outpacket->ip.ip_dst = to->sin_addr; outpacket->ip.ip_tos = tos; outpacket->ip.ip_v = IPVERSION; outpacket->ip.ip_id = 0; ident = (getpid() & 0xffff) | 0x8000; if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); s = create_icmp_socket(); #ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG if (options & SO_DEBUG) (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); #endif if (options & SO_DONTROUTE) (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on)); #ifdef SO_SNDBUF if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen, sizeof(datalen)) < 0) bb_perror_msg_and_die("SO_SNDBUF"); #endif #ifdef IP_HDRINCL if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) bb_perror_msg_and_die("IP_HDRINCL"); #endif #ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG if (options & SO_DEBUG) (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); #endif if (options & SO_DONTROUTE) (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on)); if (source) { memset(&from, 0, sizeof(struct sockaddr)); from.sin_family = AF_INET; from.sin_addr.s_addr = inet_addr(source); if (from.sin_addr.s_addr == -1) bb_error_msg_and_die("unknown host %s", source); outpacket->ip.ip_src = from.sin_addr; #ifndef IP_HDRINCL if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0) bb_perror_msg_and_die("bind"); #endif } fprintf(stderr, "traceroute to %s (%s)", hostname, inet_ntoa(to->sin_addr)); if (source) fprintf(stderr, " from %s", source); fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen); for (ttl = 1; ttl <= max_ttl; ++ttl) { u_long lastaddr = 0; int got_there = 0; int unreachable = 0; printf("%2d ", ttl); for (probe = 0; probe < nprobes; ++probe) { int cc, reset_timer; struct timeval t1, t2; struct timezone tz; struct ip *ip; (void) gettimeofday(&t1, &tz); send_probe(++seq, ttl); reset_timer = 1; while ((cc = wait_for_reply(s, &from, reset_timer)) != 0) { (void) gettimeofday(&t2, &tz); if ((i = packet_ok(packet, cc, &from, seq))) { reset_timer = 1; if (from.sin_addr.s_addr != lastaddr) { print(packet, cc, &from); lastaddr = from.sin_addr.s_addr; } printf(" %g ms", deltaT(&t1, &t2)); switch(i - 1) { case ICMP_UNREACH_PORT: ip = (struct ip *)packet; if (ip->ip_ttl <= 1) printf(" !"); ++got_there; break; case ICMP_UNREACH_NET: ++unreachable; printf(" !N"); break; case ICMP_UNREACH_HOST: ++unreachable; printf(" !H"); break; case ICMP_UNREACH_PROTOCOL: ++got_there; printf(" !P"); break; case ICMP_UNREACH_NEEDFRAG: ++unreachable; printf(" !F"); break; case ICMP_UNREACH_SRCFAIL: ++unreachable; printf(" !S"); break; } break; } else reset_timer = 0; } if (cc == 0) printf(" *"); (void) fflush(stdout); } putchar('\n'); if (got_there || unreachable >= nprobes-1) return 0; } return 0; }
int tftp_main(int argc, char **argv) { struct hostent *host = NULL; const char *localfile = NULL; const char *remotefile = NULL; int port; int cmd = 0; int fd = -1; int flags = 0; int result; int blocksize = TFTP_BLOCKSIZE_DEFAULT; /* figure out what to pass to getopt */ #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE char *sblocksize = NULL; #define BS "b:" #define BS_ARG , &sblocksize #else #define BS #define BS_ARG #endif #ifdef CONFIG_FEATURE_TFTP_GET #define GET "g" #define GET_COMPL ":g" #else #define GET #define GET_COMP #endif #ifdef CONFIG_FEATURE_TFTP_PUT #define PUT "p" #define PUT_COMPL ":p" #else #define PUT #define PUT_COMPL #endif #if defined(CONFIG_FEATURE_TFTP_GET) && defined(CONFIG_FEATURE_TFTP_PUT) bb_opt_complementally = GET_COMPL PUT_COMPL ":?g--p:p--g"; #elif defined(CONFIG_FEATURE_TFTP_GET) || defined(CONFIG_FEATURE_TFTP_PUT) bb_opt_complementally = GET_COMPL PUT_COMPL; #else /* XXX: may be should #error ? */ #endif cmd = bb_getopt_ulflags(argc, argv, GET PUT "l:r:" BS, &localfile, &remotefile BS_ARG); #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE if(sblocksize) { blocksize = atoi(sblocksize); if (!tftp_blocksize_check(blocksize, 0)) { return EXIT_FAILURE; } } #endif cmd &= (tftp_cmd_get | tftp_cmd_put); #ifdef CONFIG_FEATURE_TFTP_GET if(cmd == tftp_cmd_get) flags = O_WRONLY | O_CREAT | O_TRUNC; #endif #ifdef CONFIG_FEATURE_TFTP_PUT if(cmd == tftp_cmd_put) flags = O_RDONLY; #endif if(localfile == NULL) localfile = remotefile; if(remotefile == NULL) remotefile = localfile; /* XXX: I corrected this, but may be wrong too. vodz */ if(localfile==NULL || strcmp(localfile, "-") == 0) { fd = fileno((cmd==tftp_cmd_get)? stdout : stdin); } else if (fd==-1) { fd = open(localfile, flags, 0644); } if (fd < 0) { bb_perror_msg_and_die("local file"); } /* XXX: argv[optind] and/or argv[optind + 1] may be NULL! */ host = xgethostbyname(argv[optind]); port = bb_lookup_port(argv[optind + 1], "udp", 69); #ifdef CONFIG_FEATURE_TFTP_DEBUG fprintf(stderr, "using server \"%s\", remotefile \"%s\", " "localfile \"%s\".\n", inet_ntoa(*((struct in_addr *) host->h_addr)), remotefile, localfile); #endif result = tftp(cmd, host, remotefile, fd, port, blocksize); #ifdef CONFIG_FEATURE_CLEAN_UP if (!(fd == STDOUT_FILENO || fd == STDIN_FILENO)) { close(fd); } #endif return(result); }
int tftp_main(int argc, char **argv) { struct hostent *host = NULL; char *localfile = NULL; char *remotefile = NULL; int port; int cmd = 0; int fd = -1; int flags = 0; int opt; int result; int blocksize = TFTP_BLOCKSIZE_DEFAULT; /* figure out what to pass to getopt */ #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE #define BS "b:" #else #define BS #endif #ifdef CONFIG_FEATURE_TFTP_GET #define GET "g" #else #define GET #endif #ifdef CONFIG_FEATURE_TFTP_PUT #define PUT "p" #else #define PUT #endif while ((opt = getopt(argc, argv, BS GET PUT "l:r:")) != -1) { switch (opt) { #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE case 'b': blocksize = atoi(optarg); if (!tftp_blocksize_check(blocksize, 0)) { return EXIT_FAILURE; } break; #endif #ifdef CONFIG_FEATURE_TFTP_GET case 'g': cmd = tftp_cmd_get; flags = O_WRONLY | O_CREAT; break; #endif #ifdef CONFIG_FEATURE_TFTP_PUT case 'p': cmd = tftp_cmd_put; flags = O_RDONLY; break; #endif case 'l': localfile = bb_xstrdup(optarg); break; case 'r': remotefile = bb_xstrdup(optarg); break; } } if ((cmd == 0) || (optind == argc)) { bb_show_usage(); } if(localfile && strcmp(localfile, "-") == 0) { fd = fileno((cmd==tftp_cmd_get)? stdout : stdin); } if(localfile == NULL) localfile = remotefile; if(remotefile == NULL) remotefile = localfile; if (fd==-1) { fd = open(localfile, flags, 0644); } if (fd < 0) { bb_perror_msg_and_die("local file"); } host = xgethostbyname(argv[optind]); port = bb_lookup_port(argv[optind + 1], "udp", 69); #ifdef CONFIG_FEATURE_TFTP_DEBUG printf("using server \"%s\", remotefile \"%s\", " "localfile \"%s\".\n", inet_ntoa(*((struct in_addr *) host->h_addr)), remotefile, localfile); #endif result = tftp(cmd, host, remotefile, fd, port, blocksize); #ifdef CONFIG_FEATURE_CLEAN_UP if (!(fd == fileno(stdout) || fd == fileno(stdin))) { close(fd); } #endif return(result); }
static int tftpd_daemon (char *directory, char *address, int port) { struct tftphdr *tp; struct sockaddr_in from; struct sockaddr_in myaddr; struct sockaddr_in bindaddr; int fd = -1; int peer; int rv; int n; pid_t pid; int i = 1; char buf[TFTP_BLOCKSIZE_DEFAULT + 4]; struct iovec iov = { buf, sizeof buf }; struct cmsghdr *cmsg; char *ctrl = (char *)xmalloc(MAXCTRLSIZE); struct msghdr msg = { (void*)&from, sizeof from, &iov, 1, (void*)ctrl, MAXCTRLSIZE, 0}; struct in_pktinfo *info = NULL; daemon(0,1); if ((fd = socket (PF_INET, SOCK_DGRAM, 0)) < 0) perror_msg_and_die ("socket"); memset (&bindaddr, 0, sizeof (bindaddr)); bindaddr.sin_family = AF_INET; bindaddr.sin_addr.s_addr = INADDR_ANY; bindaddr.sin_port = htons (port); if (address != NULL) { struct hostent *hostent; hostent = xgethostbyname (address); if (!hostent || hostent->h_addrtype != AF_INET) perror_msg_and_die ("cannot resolve local bind address"); memcpy (&bindaddr.sin_addr, hostent->h_addr, hostent->h_length); } // set option for getting the to ip address. setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &i, sizeof(i)); if (bind (fd, (struct sockaddr *) &bindaddr, sizeof (bindaddr)) < 0) perror_msg_and_die ("daemon bind failed"); /* This means we don't want to wait() for children */ signal (SIGCHLD, SIG_IGN); while (1) { fd_set readset; memset(buf,0,TFTP_BLOCKSIZE_DEFAULT + 4); memset (&myaddr, 0, sizeof (myaddr)); FD_ZERO (&readset); FD_SET (fd, &readset); /* Never time out, we're in standalone mode */ rv = select (fd + 1, &readset, NULL, NULL, NULL); if (rv == -1 && errno == EINTR) continue; /* Signal caught, reloop */ if (rv == -1) perror_msg_and_die ("select loop"); if (rv == 0) { bb_error_msg ("We shouldn't be timeing out!"); exit (0); /* Timeout, return to inetd */ } n = recvmsg (fd, &msg, MSG_WAITALL); if (n <= 0) { printf("*** error recvmsg n=%d\n", n); break; } //printf("incoming_ip=%s, n=%d\n", inet_ntoa(from.sin_addr), n); for(cmsg=CMSG_FIRSTHDR(&msg); cmsg != NULL;cmsg =CMSG_NXTHDR(&msg,cmsg)) { if (cmsg->cmsg_type == IP_PKTINFO){ info = (struct in_pktinfo *)CMSG_DATA(cmsg); // printf("sepc_dst=%s, ipi_addr=%s\n", inet_ntoa(info->ipi_spec_dst),inet_ntoa(info->ipi_addr)); break; } } free(ctrl); /* Process the request */ myaddr.sin_family = AF_INET; myaddr.sin_port = htons (0); /* we want a new local port */ myaddr.sin_addr = getLanIp(); if (myaddr.sin_addr.s_addr != info->ipi_spec_dst.s_addr) memcpy (&myaddr.sin_addr, &bindaddr.sin_addr,sizeof bindaddr.sin_addr); /* Now that we have read the request packet from the UDP socket, we fork and go back to listening to the socket. */ pid = FORK (); if (pid < 0) perror_msg_and_die ("cannot fork"); if (pid == 0) break; /* Child exits the while(1), parent continues to loop */ } /* Close file descriptors we don't need */ // brcm close (fd); /* Get a socket. This has to be done before the chroot() (/dev goes away) */ peer = socket (AF_INET, SOCK_DGRAM, 0); if (peer < 0) perror_msg_and_die ("socket"); if (chroot (".")) perror_msg_and_die ("chroot"); from.sin_family = AF_INET; /* Process the request */ if (bind (peer, (struct sockaddr *) &myaddr, sizeof myaddr) < 0) perror_msg_and_die ("daemon-child bind"); //printf("after bind. my_ip=%s*****\n", inet_ntoa(myaddr.sin_addr)); if (connect (peer, (struct sockaddr *) &from, sizeof from) < 0) perror_msg_and_die ("daemon-child connect"); tp = (struct tftphdr *) buf; //printf("after connect \n"); int accessMode = bcmCheckEnable("tftp", from.sin_addr); //printf("accessmode = %d\n", accessMode); if (accessMode == CLI_ACCESS_DISABLED) { close(peer); exit(0); } if (accessMode == CLI_ACCESS_REMOTE) { glbIfName[0] = '\0'; if ((bcmGetIntfNameSocket(peer, glbIfName) != 0) || glbIfName[0] == '\0') { printf("Failed to get remote ifc name!\n"); close(peer); exit(0); } } //printf("socket ifname = %s\n", glbIfName); tp->th_opcode = ntohs (tp->th_opcode); switch(tp->th_opcode) { case RRQ: tftpd_send (peer, tp, n, TFTP_BLOCKSIZE_DEFAULT); break; case WRQ: tftpd_receive (peer, tp, n, TFTP_BLOCKSIZE_DEFAULT); break; } exit (0); }