void UDP_Socket_Init (void) { UDP_Socket = udp_get_socket(0, UDP_OPT_SEND_CS | UDP_OPT_CHK_CS, UDP_Socket_Listener); udp_open(UDP_Socket, UDP_PORT); }
int main(int argc, char **argv){ unsigned char out[CCNL_MAX_PACKET_SIZE]; int i = 0, len, opt, sock = 0; char *namecomp[CCNL_MAX_NAME_COMP], *cp, *dest, *comp; char *udp = "127.0.0.1/9695", *ux = NULL; float wait = 3.0; int (*sendproc)(int,char*,unsigned char*,int); int print = 0; while ((opt = getopt(argc, argv, "hptu:v:w:x:")) != -1) { switch (opt) { case 'u': udp = optarg; break; case 'w': wait = (float)strtof(optarg, (char**) NULL); break; case 'x': ux = optarg; break; case 'p': print = 1; break; case 'v': #ifdef USE_LOGGING if (isdigit(optarg[0])) debug_level = (int)strtol(optarg, (char **)NULL, 10); else debug_level = ccnl_debug_str2level(optarg); #endif break; case 'h': default: Usage: fprintf(stderr, "usage: %s " "[-u host/port] [-x ux_path_name] [-w timeout] COMPUTATION URI\n" " -p print interest on console and exit\n" " -u a.b.c.d/port UDP destination (default is 127.0.0.1/9695)\n" #ifdef USE_LOGGING " -v DEBUG_LEVEL (fatal, error, warning, info, debug, verbose, trace)\n" #endif " -w timeout in sec (float)\n" " -x ux_path_name UNIX IPC: use this instead of UDP\n", argv[0]); exit(1); } } if (!argv[optind]) goto Usage; comp = argv[optind++]; if (!argv[optind]) goto Usage; struct ccnl_prefix_s *prefix = create_prefix_from_name(argv[optind]); len = mkInterestCompute(prefix->comp, comp, strlen(comp), out); if(print){ fwrite(out, sizeof(char), len, stdout); return 0; } if (ux) { // use UNIX socket dest = ux; sock = ux_open(); sendproc = ux_sendto; } else { // UDP dest = udp; sock = udp_open(); sendproc = udp_sendto; } request_content(sock, sendproc, dest, out, len, wait); return 0; }
int RTSP_setup(RTSP_buffer * rtsp, RTSP_session ** new_session) { char address[16]; char object[255], server[255]; char url[255]; unsigned short port; RTSP_session *rtsp_s; RTP_session *rtp_s, *rtp_s_prec; int SessionID = 0; // port_pair cli_ports; // port_pair ser_ports; struct timeval now_tmp; char *p/* = NULL*/; unsigned int start_seq, start_rtptime; char transport_str[255]; media_entry *list, *matching_me, req; struct sockaddr_storage rtsp_peer; socklen_t namelen = sizeof(rtsp_peer); unsigned long ssrc; SD_descr *matching_descr; unsigned char is_multicast_dad = 1; //unicast and the first multicast RTP_transport transport; char *saved_ptr, *transport_tkn; int max_interlvd; // init memset(&req, 0, sizeof(req)); memset(&transport, 0, sizeof(transport)); // Parse the input message /* Get the URL */ if (!sscanf(rtsp->in_buffer, " %*s %254s ", url)) { send_reply(400, 0, rtsp); /* bad request */ return ERR_NOERROR; } /* Validate the URL */ switch (parse_url(url, server, sizeof(server), &port, object, sizeof(object))) { //object is requested file's name case 1: // bad request send_reply(400, 0, rtsp); return ERR_NOERROR; case -1: // interanl server error send_reply(500, 0, rtsp); return ERR_NOERROR; break; default: break; } if (strcmp(server, prefs_get_hostname()) != 0) { /* Currently this feature is disabled. */ /* wrong server name */ // send_reply(404, 0 , rtsp); /* Not Found */ // return ERR_NOERROR; } if (strstr(object, "../")) { /* disallow relative paths outside of current directory. */ send_reply(403, 0, rtsp); /* Forbidden */ return ERR_NOERROR; } if (strstr(object, "./")) { /* Disallow the ./ */ send_reply(403, 0, rtsp); /* Forbidden */ return ERR_NOERROR; } if (!(p = strrchr(object, '.'))) { // if filename is without extension send_reply(415, 0, rtsp); /* Unsupported media type */ return ERR_NOERROR; } else if (!is_supported_url(p)) { //if filename's extension is not valid send_reply(415, 0, rtsp); /* Unsupported media type */ return ERR_NOERROR; } if ( !(p = strchr(object, '!')) ) { //if '!' is not present then a file has not been specified send_reply(500, 0, rtsp); /* Internal server error */ return ERR_NOERROR; } else { // SETUP name.sd!stream strcpy(req.filename, p + 1); req.flags |= ME_FILENAME; *p = '\0'; } // ------------ START PATCH { char temp[255]; char *pd=NULL; strcpy(temp, object); #if 0 printf("%s\n", object); // BEGIN // if ( (p = strstr(temp, "/")) ) { if ( (p = strchr(temp, '/')) ) { strcpy(object, p + 1); // CRITIC. } printf("%s\n", temp); #endif // pd = strstr(p, ".sd"); // this part is usefull in order to pd = strstr(temp, ".sd"); if ( (p = strstr(pd + 1, ".sd")) ) { // have compatibility with RealOne strcpy(object, pd + 4); // CRITIC. } //Note: It's a critic part // END } // ------------ END PATCH if (enum_media(object, &matching_descr) != ERR_NOERROR) { send_reply(500, 0, rtsp); /* Internal server error */ return ERR_NOERROR; } list=matching_descr->me_list; if (get_media_entry(&req, list, &matching_me) == ERR_NOT_FOUND) { send_reply(404, 0, rtsp); /* Not found */ return ERR_NOERROR; } // Get the CSeq if ((p = strstr(rtsp->in_buffer, HDR_CSEQ)) == NULL) { send_reply(400, 0, rtsp); /* Bad Request */ return ERR_NOERROR; } else { if (sscanf(p, "%*s %d", &(rtsp->rtsp_cseq)) != 1) { send_reply(400, 0, rtsp); /* Bad Request */ return ERR_NOERROR; } } /*if ((p = strstr(rtsp->in_buffer, "ssrc")) != NULL) { p = strchr(p, '='); sscanf(p + 1, "%lu", &ssrc); } else {*/ ssrc = random32(0); //} // Start parsing the Transport header if ((p = strstr(rtsp->in_buffer, HDR_TRANSPORT)) == NULL) { send_reply(406, "Require: Transport settings" /* of rtp/udp;port=nnnn. "*/, rtsp); /* Not Acceptable */ return ERR_NOERROR; } if (sscanf(p, "%*10s%255s", transport_str) != 1) { fnc_log(FNC_LOG_ERR,"SETUP request malformed: Transport string is empty\n"); send_reply(400, 0, rtsp); /* Bad Request */ return ERR_NOERROR; } printf("transport: %s\n", transport_str); // XXX tmp. // tokenize the coma seaparated list of transport settings: if ( !(transport_tkn=strtok_r(transport_str, ",", &saved_ptr)) ) { fnc_log(FNC_LOG_ERR,"Malformed Transport string from client\n"); send_reply(400, 0, rtsp); /* Bad Request */ return ERR_NOERROR; } if (getpeername(rtsp->fd, (struct sockaddr *)&rtsp_peer, &namelen) != 0) { send_reply(415, 0, rtsp); // Internal server error return ERR_GENERIC; } transport.type = RTP_no_transport; do { // search a good transport string if ( (p = strstr(transport_tkn, RTSP_RTP_AVP)) ) { // Transport: RTP/AVP p += strlen(RTSP_RTP_AVP); if ( !*p || (*p == ';') || (*p == ' ')) { #if 0 // if ((p = strstr(rtsp->in_buffer, "client_port")) == NULL && strstr(rtsp->in_buffer, "multicast") == NULL) { if ((p = strstr(transport_tkn, "client_port")) == NULL && strstr(transport_tkn, "multicast") == NULL) { send_reply(406, "Require: Transport settings of rtp/udp;port=nnnn. ", rtsp); /* Not Acceptable */ return ERR_NOERROR; } #endif // #if 0 if (strstr(transport_tkn, "unicast")) { if( (p = strstr(transport_tkn, "client_port")) ) { p = strstr(p, "="); sscanf(p + 1, "%d", &(transport.u.udp.cli_ports.RTP)); p = strstr(p, "-"); sscanf(p + 1, "%d", &(transport.u.udp.cli_ports.RTCP)); } if (RTP_get_port_pair(&transport.u.udp.ser_ports) != ERR_NOERROR) { send_reply(500, 0, rtsp); /* Internal server error */ return ERR_GENERIC; } // strcpy(address, get_address()); //UDP connection for outgoing RTP packets udp_connect(transport.u.udp.cli_ports.RTP, &transport.u.udp.rtp_peer, (*((struct sockaddr_in *) (&rtsp_peer))).sin_addr.s_addr,&transport.rtp_fd); //UDP connection for outgoing RTCP packets udp_connect(transport.u.udp.cli_ports.RTCP, &transport.u.udp.rtcp_out_peer,(*((struct sockaddr_in *) (&rtsp_peer))).sin_addr.s_addr, &transport.rtcp_fd_out); udp_open(transport.u.udp.ser_ports.RTCP, &transport.u.udp.rtcp_in_peer, &transport.rtcp_fd_in); //bind transport.u.udp.is_multicast = 0; } else if ( matching_descr->flags & SD_FL_MULTICAST ) { /*multicast*/ // TODO: make the difference between only multicast allowed or unicast fallback allowed. transport.u.udp.cli_ports.RTP = transport.u.udp.ser_ports.RTP =matching_me->rtp_multicast_port; transport.u.udp.cli_ports.RTCP = transport.u.udp.ser_ports.RTCP =matching_me->rtp_multicast_port+1; is_multicast_dad = 0; if (!(matching_descr->flags & SD_FL_MULTICAST_PORT) ) { struct in_addr inp; unsigned char ttl=DEFAULT_TTL; struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr(matching_descr->multicast); mreq.imr_interface.s_addr = INADDR_ANY; setsockopt(transport.rtp_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); setsockopt(transport.rtp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); is_multicast_dad = 1; strcpy(address, matching_descr->multicast); //RTP outgoing packets inet_aton(address, &inp); udp_connect(transport.u.udp.ser_ports.RTP, &transport.u.udp.rtp_peer, inp.s_addr, &transport.rtp_fd); //RTCP outgoing packets inet_aton(address, &inp); udp_connect(transport.u.udp.ser_ports.RTCP, &transport.u.udp.rtcp_out_peer, inp.s_addr, &transport.rtcp_fd_out); //udp_open(transport.u.udp.ser_ports.RTCP, &(sp2->rtcp_in_peer), &(sp2->rtcp_fd_in)); //bind if(matching_me->next==NULL) matching_descr->flags |= SD_FL_MULTICAST_PORT; matching_me->rtp_multicast_port = transport.u.udp.ser_ports.RTP; transport.u.udp.is_multicast = 1; fnc_log(FNC_LOG_DEBUG,"\nSet up socket for multicast ok\n"); } } else continue; transport.type = RTP_rtp_avp; break; // found a valid transport } else if (!strncmp(p, "/TCP", 4)) { // Transport: RTP/AVP/TCP;interleaved=x-y // XXX still not finished if( (p = strstr(transport_tkn, "interleaved")) ) { p = strstr(p, "="); sscanf(p + 1, "%d", &(transport.u.tcp.interleaved.RTP)); if ( (p = strstr(p, "-")) ) sscanf(p + 1, "%d", &(transport.u.tcp.interleaved.RTCP)); else transport.u.tcp.interleaved.RTCP = transport.u.tcp.interleaved.RTP + 1; } else { // search for max used interleved channel. max_interlvd = -1; for (rtp_s = (rtsp->session_list)?rtsp->session_list->rtp_session:NULL; rtp_s; rtp_s = rtp_s->next) max_interlvd = max(max_interlvd, (rtp_s->transport.type == RTP_rtp_avp_tcp)?rtp_s->transport.u.tcp.interleaved.RTCP:-1); transport.u.tcp.interleaved.RTP = max_interlvd + 1; transport.u.tcp.interleaved.RTCP = max_interlvd + 2; } transport.rtp_fd = rtsp->fd; // dup(rtsp->fd); transport.rtcp_fd_out = rtsp->fd; // dup(rtsp->fd); transport.rtcp_fd_in = -1; transport.type = RTP_rtp_avp_tcp; break; // found a valid transport } } } while ((transport_tkn=strtok_r(NULL, ",", &saved_ptr))); printf("rtp transport: %d\n", transport.type); if (transport.type == RTP_no_transport) { // fnc_log(FNC_LOG_ERR,"Unsupported Transport\n"); send_reply(461, "Unsupported Transport", rtsp); /* Bad Request */ return ERR_NOERROR; } // If there's a Session header we have an aggregate control if ((p = strstr(rtsp->in_buffer, HDR_SESSION)) != NULL) { if (sscanf(p, "%*s %d", &SessionID) != 1) { send_reply(454, 0, rtsp); /* Session Not Found */ return ERR_NOERROR; } } else { // Generate a random Session number gettimeofday(&now_tmp, 0); srand((now_tmp.tv_sec * 1000) + (now_tmp.tv_usec / 1000)); #ifdef WIN32 SessionID = rand(); #else SessionID = 1 + (int) (10.0 * rand() / (100000 + 1.0)); #endif if (SessionID == 0) { SessionID++; } } // Add an RTSP session if necessary if ( !rtsp->session_list ) { rtsp->session_list = (RTSP_session *) calloc(1, sizeof(RTSP_session)); } rtsp_s = rtsp->session_list; // Setup the RTP session if (rtsp->session_list->rtp_session == NULL) { rtsp->session_list->rtp_session = (RTP_session *) calloc(1, sizeof(RTP_session)); rtp_s = rtsp->session_list->rtp_session; } else { for (rtp_s = rtsp_s->rtp_session; rtp_s != NULL; rtp_s = rtp_s->next) { rtp_s_prec = rtp_s; } rtp_s_prec->next = (RTP_session *) calloc(1, sizeof(RTP_session)); rtp_s = rtp_s_prec->next; } #ifdef WIN32 start_seq = rand(); start_rtptime = rand(); #else // start_seq = 1 + (int) (10.0 * rand() / (100000 + 1.0)); // start_rtptime = 1 + (int) (10.0 * rand() / (100000 + 1.0)); #if 0 start_seq = 1 + (unsigned int) ((float)(0xFFFF) * ((float)rand() / (float)RAND_MAX)); start_rtptime = 1 + (unsigned int) ((float)(0xFFFFFFFF) * ((float)rand() / (float)RAND_MAX)); #else start_seq = 1 + (unsigned int) (rand()%(0xFFFF)); start_rtptime = 1 + (unsigned int) (rand()%(0xFFFFFFFF)); #endif #endif if (start_seq == 0) { start_seq++; } if (start_rtptime == 0) { start_rtptime++; } rtp_s->pause = 1; strcpy(rtp_s->sd_filename, object); /*xxx*/ rtp_s->current_media = (media_entry *) calloc(1, sizeof(media_entry)); // if(!(matching_descr->flags & SD_FL_MULTICAST_PORT)){ if( is_multicast_dad ) { if ( mediacpy(&rtp_s->current_media, &matching_me) ) { send_reply(500, 0, rtsp); /* Internal server error */ return ERR_GENERIC; } } gettimeofday(&now_tmp, 0); srand((now_tmp.tv_sec * 1000) + (now_tmp.tv_usec / 1000)); rtp_s->start_rtptime = start_rtptime; rtp_s->start_seq = start_seq; memcpy(&rtp_s->transport, &transport, sizeof(transport)); rtp_s->is_multicast_dad = is_multicast_dad; /*xxx*/ rtp_s->sd_descr=matching_descr; rtp_s->sched_id = schedule_add(rtp_s); rtp_s->ssrc = ssrc; // Setup the RTSP session rtsp_s->session_id = SessionID; *new_session = rtsp_s; fnc_log(FNC_LOG_INFO,"SETUP %s RTSP/1.0 ",url); send_setup_reply(rtsp, rtsp_s, matching_descr, rtp_s); // See User-Agent if ((p=strstr(rtsp->in_buffer, HDR_USER_AGENT))!=NULL) { char cut[strlen(p)]; strcpy(cut,p); p=strstr(cut, "\n"); cut[strlen(cut)-strlen(p)-1]='\0'; fnc_log(FNC_LOG_CLIENT,"%s\n",cut); } else fnc_log(FNC_LOG_CLIENT,"- \n"); return ERR_NOERROR; }
errno_t dns_request(const unsigned char *host, ipv4_addr server, ipv4_addr *result) { // TODO 64 k on stack? unsigned char buf[32000]; //unsigned char buf[65536]; unsigned char *qname, *reader; int i, j, stop; struct RES_RECORD answers[20], auth[20], addit[20]; //the replies from the DNS server struct DNS_HEADER *dns = NULL; struct QUESTION *qinfo = NULL; #ifdef KERNEL void *s; int res = udp_open(&s); if( res ) { SHOW_ERROR0( 0, "Can't get socket"); return ENOTSOCK; } #else int s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries #endif //SHOW_FLOW0( 2, "got sock"); #ifdef KERNEL i4sockaddr addr; addr.port = 53; addr.addr.len = 4; addr.addr.type = ADDR_TYPE_IP; NETADDR_TO_IPV4(addr.addr) = server; #else struct sockaddr_in dest; dest.sin_family = AF_INET; dest.sin_port = htons(53); dest.sin_addr.s_addr = inet_addr(dns_servers[0]); //dns servers #endif memset(buf, 0, sizeof(buf)); //Set the DNS structure to standard queries dns = (struct DNS_HEADER *)&buf; #ifdef KERNEL dns->id = (unsigned short) random(); #else dns->id = (unsigned short) htons(getpid()); #endif dns->qr = 0; //This is a query dns->opcode = 0; //This is a standard query dns->aa = 0; //Not Authoritative dns->tc = 0; //This message is not truncated dns->rd = 1; //Recursion Desired dns->ra = 0; //Recursion not available! hey we dont have it (lol) dns->z = 0; dns->ad = 0; dns->cd = 0; dns->rcode = 0; dns->q_count = htons(1); //we have only 1 question dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; //point to the query portion qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)]; ChangetoDnsNameFormat(qname , host); int qname_len = (strlen((const char*)qname) + 1); qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + qname_len]; //fill it qinfo->qtype = htons(1); //we are requesting the ipv4 address qinfo->qclass = htons(1); //its internet (lol) STAT_INC_CNT(STAT_CNT_DNS_REQ); SHOW_FLOW0( 3, "Sending Packet"); int sendLen = sizeof(struct DNS_HEADER) + qname_len + sizeof(struct QUESTION); #ifdef KERNEL int ret = udp_sendto( s, buf, sendLen, &addr); if( ret ) #else if(sendto(s,(char*)buf, sendLen, 0, (struct sockaddr*)&dest, sizeof(dest)) != sendLen) #endif { SHOW_ERROR( 0, "Error sending req, %d", ret); goto reterr; } SHOW_FLOW0( 3, "Sent"); #ifdef KERNEL long tmo = 1000L*1000L*2; // 2 sec //long tmo = 1000L*10; if( udp_recvfrom( s, buf, sizeof(buf), &addr, SOCK_FLAG_TIMEOUT, tmo) <= 0 ) #else i = sizeof dest; ret = recvfrom (s,(char*)buf,65536,0,(struct sockaddr*)&dest,&i); if(ret == 0) #endif { SHOW_ERROR0( 1, "Failed"); goto reterr; } SHOW_FLOW0( 3, "Received"); STAT_INC_CNT(STAT_CNT_DNS_ANS); dns = (struct DNS_HEADER*) buf; //move ahead of the dns header and the query field reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)]; if(debug_level_flow > 6) { printf("The response contains : \n"); printf("%d Questions.\n",ntohs(dns->q_count)); printf("%d Answers.\n",ntohs(dns->ans_count)); printf("%d Authoritative Servers.\n",ntohs(dns->auth_count)); printf("%d Additional records.\n\n",ntohs(dns->add_count)); } //reading answers stop=0; for(i=0;i<ntohs(dns->ans_count);i++) { answers[i].name=ReadName(reader,buf,&stop); reader = reader + stop; answers[i].resource = (struct R_DATA*)(reader); reader = reader + sizeof(struct R_DATA); if(ntohs(answers[i].resource->type) == 1) //if its an ipv4 address { answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len)); for(j=0 ; j<ntohs(answers[i].resource->data_len) ; j++) answers[i].rdata[j]=reader[j]; answers[i].rdata[ntohs(answers[i].resource->data_len)] = FIN; reader = reader + ntohs(answers[i].resource->data_len); } else { answers[i].rdata = ReadName(reader,buf,&stop); reader = reader + stop; } } //read authorities for(i=0;i<ntohs(dns->auth_count);i++) { auth[i].name=ReadName(reader,buf,&stop); reader+=stop; auth[i].resource=(struct R_DATA*)(reader); reader+=sizeof(struct R_DATA); auth[i].rdata=ReadName(reader,buf,&stop); reader+=stop; } //read additional for(i=0;i<ntohs(dns->add_count);i++) { addit[i].name=ReadName(reader,buf,&stop); reader+=stop; addit[i].resource=(struct R_DATA*)(reader); reader+=sizeof(struct R_DATA); if(ntohs(addit[i].resource->type)==1) { addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len)); for(j=0;j<ntohs(addit[i].resource->data_len);j++) addit[i].rdata[j]=reader[j]; addit[i].rdata[ntohs(addit[i].resource->data_len)]= FIN; reader+=ntohs(addit[i].resource->data_len); } else { addit[i].rdata=ReadName(reader,buf,&stop); reader+=stop; } } if(debug_level_flow > 6) { //print answers for(i=0;i<ntohs(dns->ans_count);i++) { printf("Name : %s ",answers[i].name); if(ntohs(answers[i].resource->type)==1) //IPv4 address { long *p; p=(long*)answers[i].rdata; struct sockaddr_in a; a.sin_addr.s_addr=(*p); //working without ntohl printf("has IPv4 address : %s",inet_ntoa(a.sin_addr)); } if(ntohs(answers[i].resource->type)==5) //Canonical name for an alias printf("has alias name : %s",answers[i].rdata); printf("\n"); } //print authorities for(i=0;i<ntohs(dns->auth_count);i++) { printf("Name : %s ",auth[i].name); if(ntohs(auth[i].resource->type)==2) printf("has authoritative nameserver : %s",auth[i].rdata); printf("\n"); } //print additional resource records for(i=0;i<ntohs(dns->add_count);i++) { printf("Name : %s ",addit[i].name); if(ntohs(addit[i].resource->type)==1) { long *p; p=(long*)addit[i].rdata; struct sockaddr_in a; a.sin_addr.s_addr=(*p); //working without ntohl printf("has IPv4 address : %s",inet_ntoa(a.sin_addr)); } printf("\n"); } } // return answer for( i=0; i < ntohs(dns->ans_count); i++ ) { if( ntohs(answers[i].resource->type) == 1 ) //IPv4 address { *result = *( (long*)answers[i].rdata); udp_close(s); return 0; } } reterr: // No direct answer *result = 0; udp_close(s); return ENOENT; }
int main(int argc, char *argv[] ) { int n, i, c, err, max_port = 0; char *portname, *s; struct servent *servent; struct info *in; prog = argv[0]; Opterr = 1; while( (n = Getopt(argc, argv, "dut")) != EOF ){ switch(n){ default: usage(); break; case 'u': use_udp = !use_udp; break; case 't': use_tcp = !use_tcp; break; case 'd': debug = 1; break; } } i = argc - Optind; if( i > 1 ) usage(); if( i == 1 ){ portname = argv[Optind]; n = atoi( portname ); if( n <= 0 ){ servent = getservbyname( portname, "udp" ); if( servent ){ n = ntohs( servent->s_port ); } } if( n <= 0 ){ FPRINTF( STDERR, "udp_open: bad port number '%s'\n",portname ); usage(); } port_num = n; } if( !use_tcp && !use_udp ) use_udp = 1; if( debug ){ FPRINTF(STDERR,"monitor: udp %d, tcp %d, port %d\n", use_udp, use_tcp, port_num ); } max_port = 0; FD_ZERO( &readfds ); if( use_udp && (udp_fd = udp_open( port_num )) >= 0){ if( debug ) FPRINTF(STDERR,"monitor: udp port %d\n", udp_fd ); FD_SET(udp_fd, &readfds); if( udp_fd >= max_port ) max_port = udp_fd+1; } if( use_tcp && (tcp_fd = tcp_open( port_num )) >= 0){ if( debug ) FPRINTF(STDERR,"monitor: tcp port %d\n", tcp_fd ); FD_SET(tcp_fd, &readfds); if( tcp_fd >= max_port ) max_port = tcp_fd+1; } if( debug ){ FPRINTF(STDERR,"monitor: max_port %d\n", max_port ); for( i = 0; i < max_port; ++i ){ if( FD_ISSET(i, &readfds) ){ FPRINTF(STDERR,"monitor: initial on %d\n", i ); } } } while(1){ FD_ZERO( &testfds ); for( i = 0; i < max_port; ++i ){ if( FD_ISSET(i, &readfds) ){ if( debug ) FPRINTF(STDERR,"monitor: waiting on %d\n", i ); FD_SET(i, &testfds); } } if( debug ) FPRINTF(STDERR,"monitor: starting wait, max %d\n", i ); n = select( i, FD_SET_FIX((fd_set *))&testfds, FD_SET_FIX((fd_set *))0, FD_SET_FIX((fd_set *))0, (struct timeval *)0 ); err = errno; if( debug ) FPRINTF(STDERR,"monitor: select returned %d\n", n ); if( n < 0 ){ FPRINTF( STDERR, "select error - %s\n", Errormsg(errno) ); if( err != EINTR ) break; } if( n > 0 ) for( i = 0; i < max_port; ++i ){ if( FD_ISSET(i, &testfds) ){ if( debug ) FPRINTF(STDERR,"monitor: input on %d\n", i ); if( i == tcp_fd ){ #if defined(HAVE_SOCKLEN_T) socklen_t len; #else int len; #endif struct sockaddr_in sinaddr; len = sizeof( sinaddr ); i = accept( tcp_fd, (struct sockaddr *)&sinaddr, &len ); if( i < 0 ){ FPRINTF( STDERR, "accept error - %s\n", Errormsg(errno) ); continue; } FPRINTF( STDOUT, "connection from %s\n", inet_ntoa( sinaddr.sin_addr ) ); if( i >= max_port ) max_port = i+1; FD_SET(i, &readfds); } else { c = read( i, buffer, sizeof(buffer)-1 ); if( c == 0 ){ /* closed connection */ FPRINTF(STDOUT, "closed connection %d\n", i ); close( i ); FD_CLR(i, &readfds ); Clear_buffer(i); } else if( c > 0 ){ buffer[c] = 0; if(debug)FPRINTF( STDOUT, "recv port %d: %s\n", i, buffer ); Add_buffer(i); in = Save_outbuf_len( i, buffer, c ); while( (s = safestrchr(in->buffer,'\n')) ){ *s++ = 0; Decode(in->buffer); memmove(in->buffer,s, safestrlen(s)+1 ); in->len = safestrlen(in->buffer); } } else { FPRINTF( STDERR, "read error - %s\n", Errormsg(errno) ); close( i ); FD_CLR(i, &readfds ); } } } } } return(0); }
int main(int argc, char *argv[]) { unsigned char out[64*1024]; int len, opt, port, sock = 0, suite = CCNL_SUITE_DEFAULT; char *addr = NULL, *udp = NULL, *ux = NULL; struct sockaddr sa; float wait = 3.0; while ((opt = getopt(argc, argv, "hs:u:v:w:x:")) != -1) { switch (opt) { case 's': suite = ccnl_str2suite(optarg); if (!ccnl_isSuite(suite)) { DEBUGMSG(ERROR, "Unsupported suite %s\n", optarg); goto usage; } break; case 'u': udp = optarg; break; case 'w': wait = atof(optarg); break; case 'v': #ifdef USE_LOGGING if (isdigit(optarg[0])) debug_level = atoi(optarg); else debug_level = ccnl_debug_str2level(optarg); #endif break; case 'x': ux = optarg; break; case 'h': default: usage: fprintf(stderr, "usage: %s [options] URI [NFNexpr]\n" " -s SUITE (ccnb, ccnx2015, cisco2015, iot2014, ndn2013)\n" " -u a.b.c.d/port UDP destination (default is 127.0.0.1/6363)\n" #ifdef USE_LOGGING " -v DEBUG_LEVEL (fatal, error, warning, info, debug, verbose, trace)\n" #endif " -w timeout in sec (float)\n" " -x ux_path_name UNIX IPC: use this instead of UDP\n" "Examples:\n" "%% peek /ndn/edu/wustl/ping (classic lookup)\n" "%% peek /th/ere \"lambda expr\" (lambda expr, in-net)\n" "%% peek \"\" \"add 1 1\" (lambda expr, local)\n" "%% peek /rpc/site \"call 1 /test/data\" (lambda RPC, directed)\n", argv[0]); exit(1); } } if (!argv[optind]) goto usage; srandom(time(NULL)); if (ccnl_parseUdp(udp, suite, &addr, &port) != 0) { exit(-1); } DEBUGMSG(TRACE, "using suite %d:%s\n", suite, ccnl_suite2str(suite)); DEBUGMSG(TRACE, "using udp address %s/%d\n", addr, port); if (ux) { // use UNIX socket struct sockaddr_un *su = (struct sockaddr_un*) &sa; su->sun_family = AF_UNIX; strcpy(su->sun_path, ux); sock = ux_open(); } else { // UDP struct sockaddr_in *si = (struct sockaddr_in*) &sa; si->sin_family = PF_INET; si->sin_addr.s_addr = inet_addr(addr); si->sin_port = htons(port); sock = udp_open(); } char *url = argv[optind]; char *nfnexpr = 0; if (argv[optind+1]) { nfnexpr = argv[optind+1]; } unsigned char *content = 0; int contlen; unsigned int *curchunknum = NULL; // For CCNTLV always start with the first chunk because of exact content match // This means it can only fetch chunked data and not single content-object data if (suite == CCNL_SUITE_CCNTLV || suite == CCNL_SUITE_CISTLV) { curchunknum = ccnl_malloc(sizeof(unsigned int)); *curchunknum = 0; } struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(url, suite, nfnexpr, curchunknum); const int maxretry = 3; int retry = 0; while (retry < maxretry) { if (curchunknum) { if (!prefix->chunknum) { prefix->chunknum = ccnl_malloc(sizeof(unsigned int)); } *(prefix->chunknum) = *curchunknum; DEBUGMSG(INFO, "fetching chunk %d for prefix '%s'\n", *curchunknum, ccnl_prefix_to_path(prefix)); } else { DEBUGMSG(DEBUG, "fetching first chunk...\n"); DEBUGMSG(INFO, "fetching first chunk for prefix '%s'\n", ccnl_prefix_to_path(prefix)); } // Fetch chunk if (ccnl_fetchContentForChunkName(prefix, nfnexpr, curchunknum, suite, out, sizeof(out), &len, wait, sock, sa) < 0) { retry++; DEBUGMSG(WARNING, "timeout\n");//, retry number %d of %d\n", retry, maxretry); } else { unsigned int lastchunknum; unsigned char *t = &out[0]; struct ccnl_prefix_s *nextprefix = 0; // Parse response if (ccnl_extractDataAndChunkInfo(&t, &len, suite, &nextprefix, &lastchunknum, &content, &contlen) < 0) { retry++; DEBUGMSG(WARNING, "Could not extract response or it was an interest\n"); } else { prefix = nextprefix; // Check if the fetched content is a chunk if (!(prefix->chunknum)) { // Response is not chunked, print content and exit write(1, content, contlen); goto Done; } else { int chunknum = *(prefix->chunknum); // allocate curchunknum because it is the first fetched chunk if(!curchunknum) { curchunknum = ccnl_malloc(sizeof(unsigned int)); *curchunknum = 0; } // Remove chunk component from name if (ccnl_prefix_removeChunkNumComponent(suite, prefix) < 0) { retry++; DEBUGMSG(WARNING, "Could not remove chunknum\n"); } // Check if the chunk is the first chunk or the next valid chunk // otherwise discard content and try again (except if it is the first fetched chunk) if (chunknum == 0 || (curchunknum && *curchunknum == chunknum)) { DEBUGMSG(DEBUG, "Found chunk %d with contlen=%d, lastchunk=%d\n", *curchunknum, contlen, lastchunknum); write(1, content, contlen); if (lastchunknum != -1 && lastchunknum == chunknum) { goto Done; } else { *curchunknum += 1; retry = 0; } } else { // retry if the fetched chunk retry++; DEBUGMSG(WARNING, "Could not find chunk %d, extracted chunknum is %d (lastchunk=%d)\n", *curchunknum, chunknum, lastchunknum); } } } } if(retry > 0) { DEBUGMSG(INFO, "Retry %d of %d\n", retry, maxretry); } } close(sock); return 1; Done: DEBUGMSG(DEBUG, "Sucessfully fetched content\n"); close(sock); return 0; }
/* * Open a TFTP connection on a random local port (our transaction ID). * Send the request, wait for first data block and send the first ACK. */ static int tftp_open (DWORD server, const char *fname) { int retry; WORD port = 69; #if defined(USE_BSD_API) struct servent *sp = getservbyname ("tftp", "udp"); if (sp) port = intel16 ((WORD)sp->s_port); #endif currblock = 0UL; blocksize = 0; for (retry = 0; retry < tftp_retry; retry++) { WORD our_tid; /* our transaction ID (local port) */ if (tftp_lport && tftp_lport < TFTP_PORT_LOW) outsnl (_LANG("tftp: Illegal local port.")); if (tftp_lport >= TFTP_PORT_LOW) our_tid = tftp_lport; else our_tid = Random (TFTP_PORT_LOW, TFTP_PORT_HIGH); /* Try to open a TFTP connection to the server */ if (!udp_open(&sock->udp, our_tid, server, port, NULL)) { TRACE (("tftp: %s\n", sockerr(sock))); return (0); } sock->udp.locflags |= LF_NOCLOSE; /* don't close socket on timeout */ /* Send the file request block, and then wait for the first data * block. If there is no response to the query, retry it with * another transaction ID (local port), so that all old packets get * discarded automatically. */ send_req (RRQ, fname); /* This hack makes it work because the response is sent back on * a source-port different from port 69; i.e. the server TID * uses a random port. Force the response packet to match a passive * socket in udp_handler(). */ sock->udp.hisaddr = 0; ibuflen = recv_packet (1); if (ibuflen >= 0) { blocksize = ibuflen; isopen = TRUE; send_ack (1); return (1); } /* If an error (except timeout) occurred, retries are useless */ if (tftp_errno == ERR_ERR || tftp_errno == ERR_UNKNOWN) break; } return (0); }
static int cmd_minip(int argc, const cmd_args *argv) { if (argc == 1) { minip_usage: printf("minip commands\n"); printf("mi [a]rp dump arp table\n"); printf("mi [s]tatus print ip status\n"); printf("mi [t]est [dest] [port] [cnt] send <cnt> test packets to the dest:port\n"); } else { switch(argv[1].str[0]) { case 'a': arp_cache_dump(); break; case 's': { uint32_t ipaddr = minip_get_ipaddr(); printf("hostname: %s\n", minip_get_hostname()); printf("ip: %u.%u.%u.%u\n", IPV4_SPLIT(ipaddr)); } break; case 't': { uint32_t count = 1; uint32_t host = 0x0100000A; // 10.0.0.1 uint32_t port = 1025; udp_socket_t *handle; switch (argc) { case 5: count = argv[4].u; case 4: port = argv[3].u; case 3: host = str_ip_to_int(argv[2].str, strlen(argv[2].str)); break; } if (udp_open(host, port, port, &handle) != NO_ERROR) { printf("udp_open to %u.%u.%u.%u:%u failed\n", IPV4_SPLIT(host), port); return -1; } #define BUFSIZE 1470 uint8_t *buf; buf = malloc(BUFSIZE); if (!buf) { udp_close(handle); return -1; } memset(buf, 0x00, BUFSIZE); printf("sending %u packet(s) to %u.%u.%u.%u:%u\n", count, IPV4_SPLIT(host), port); lk_time_t t = current_time(); uint32_t failures = 0; for (uint32_t i = 0; i < count; i++) { if (udp_send(buf, BUFSIZE, handle) != 0) { failures++; } buf[128]++; } t = current_time() - t; printf("%d pkts failed\n", failures); uint64_t total_count = (uint64_t)count * BUFSIZE; printf("wrote %llu bytes in %u msecs (%llu bytes/sec)\n", total_count, (uint32_t)t, total_count * 1000 / t); free(buf); udp_close(handle); #undef BUFSIZE } break; default: goto minip_usage; } } return 0; }