void dg_cli(FILE *fp, int sockfd, const struct sockaddr *pservaddr, socklen_t servlen) { int n; const int on = 1; char sendline[MAXLINE], recvline[MAXLINE + 1]; socklen_t len; struct sockaddr *preply_addr; preply_addr = (struct sockaddr *) malloc(servlen); setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); strcpy(sendline, "hola\n\0"); for (;;) { sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); for (; ;) { len = servlen; n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); if (n < 0) { if (errno == EINTR) break; /* waited long enough for replies */ else puts("recvfrom error"); } else { recvline[n] = 0; /* null terminate */ printf("from %s: %s", sock_ntop_host(preply_addr, len), recvline); } } } free(preply_addr); }
// sock to host char * Sock_ntop_host(const struct sockaddr *sa, socklen_t salen) { char *ptr; if ( (ptr = sock_ntop_host(sa, salen)) == NULL) perror("sock_ntop_host error"); /* inet_ntop() sets errno */ return(ptr); }
// 打开分组捕获设备 void open_pcap(void) { uint32_t localnet, netmask; char cmd[MAXLINE], errbuf[PCAP_ERRBUF_SIZE]; char str1[INET_ADDRSTRLEN], str2[INET_ADDRSTRLEN]; struct bpf_program fcode; // 选择分组设备:如果分组设备未曾指定(通过 -i 选项),那就调用 // pcap_lookupdev函数选择一个设备 if (device == NULL) { if ((device = pcap_lookupdev(errbuf)) == NULL) { err_quit("pcap_lookup: %s", errbuf); } } printf("device = %s\n", device); // 打开设备 // hardcode: promisc = 0, to_ms = 500 if ((pd = pcap_open_live(device, snaplen, 0, 500, errbuf)) == NULL) { err_quit("pcap_open_live: %s", errbuf); } // 获取网络地址与子网掩码 if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0) { err_quit("pcap_lookupnet: % s", errbuf); } if (verbose) { printf("localnet = %s, netmask = %s\n", inet_ntop(AF_INET, &localnet, str1, sizeof(str1)), inet_ntop(AF_INET, &netmask, str2, sizeof(str2))); } // 编译分组过滤器 snprintf(cmd, sizeof(cmd), CMD, sock_ntop_host(dest, destlen), ntohs(sock_get_port(dest, destlen))); if (verbose) { printf("cmd = %s\n", cmd); } if (pcap_compile(pd, &fcode, cmd, 0, netmask) < 0) { err_quit("pcap_compile: %s", pcap_geterr(pd)); } // 装载过滤程序 if (pcap_setfilter(pd, &fcode) < 0) { err_quit("pcap_setfilter: %s", pcap_geterr(pd)); } // 确定数据链路类型 if ((datalink = pcap_datalink(pd)) < 0) { err_quit("pcap_datalink: %s", pcap_geterr(pd)); } if (verbose) { printf("datalink = %d\n", datalink); } }
char * Sock_ntop_host(const struct sockaddr *sa, socklen_t salen) { char *ptr; if ( (ptr = sock_ntop_host(sa, salen)) == NULL) { /* inet_ntop() sets errno */ fprintf(stderr, "sock_ntop_host error: %s\n", strerror(errno)); exit(EXIT_FAILURE); } return(ptr); }
void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) { int n, maxfdp1; const int on = 1; char sendline[MAXLINE], recvline[MAXLINE + 1]; fd_set rset; socklen_t len; struct sockaddr *preply_addr; if ((preply_addr = malloc(servlen)) == NULL) err_sys("dg_cli: malloc error"); if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) err_sys("dg_cli: setsockopt error"); if (pipe(pipefd) < 0) err_sys("dg_cli: pipe error"); maxfdp1 = max(sockfd, pipefd[0]) + 1; FD_ZERO(&rset); if (signal(SIGALRM, recvfrom_alarm) == SIG_ERR) err_sys("dg_cli: signal error"); while (fgets(sendline, MAXLINE, fp)) { Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); alarm(5); for ( ; ; ) { FD_SET(sockfd, &rset); FD_SET(pipefd[0], &rset); if ((n = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) { if (errno == EINTR) continue; else err_sys("select error"); } if (FD_ISSET(sockfd, &rset)) { len = servlen; n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); recvline[n] = 0; printf("from %s: %s", sock_ntop_host(preply_addr, len), recvline); } if (FD_ISSET(pipefd[0], &rset)) { read(pipefd[0], &n, 1); break; } } } free(preply_addr); }
int main(int argc, char *argv[]) { int sockfd, n; char recvline[MAXLINE + 1]; /* plus 1 for terminator */ socklen_t salen; struct sockaddr *sa; if (argc != 3) err_quit("usage: daytimeudpcli1 <hostname/IPaddress>" " <service/port#>"); sockfd = udp_client(argv[1], argv[2], (SA **)&sa, &salen); printf("sending to %s\n", sock_ntop_host(sa, salen)); if (sendto(sockfd, " ", 1, 0, sa, salen) < 0) err_sys("sendto error"); if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) err_sys("recvfrom error"); recvline[n] = 0; fputs(recvline, stdout); exit(0); }
int main(int argc, char **argv) { int sockfd[10], sockcount = 0, countline = 0, n = 0, s, nready, maxfdp1, i; fd_set rset, allset; socklen_t len, slen; const int on = 1; pid_t pid; struct ifi_info *ifi, *ifihead; struct sockaddr_in *sa, cliaddr, wildaddr, ss,childservaddr; char dataline[MAXLINE], mesg[MAXLINE], IPClient[MAXLINE],IPServer[MAXLINE]; config configdata[2]; char *mode = "r"; socket_info sockinfo[10]; FILE *ifp; int is_local = 0; ifp = fopen( "server.in", mode ); if ( ifp == NULL ) { fprintf( stderr, "Can't open input file server.in!\n" ); exit(1); } printf("***********************************************************************************\n"); printf("SERVER \n"); printf("***********************************************************************************\n"); while ( fgets( dataline,MAXLINE,ifp ) != NULL ) { n = strlen( dataline ); strcpy( configdata[countline].data, dataline ); s = strlen( configdata[ countline ].data ); if ( s > 0 && configdata[ countline ].data[ s-1 ] == '\n' ) /* if there's a newline */ { configdata[countline].data[s-1] = '\0'; /* truncate the string */ } dataline[n] = 0; countline++; } fclose( ifp ); printf("Creating the send window array dynamically for input window size..\n\n"); sender_window_size = (int) atoi( configdata[1].data ); swnd = (struct msghdr *) malloc( sender_window_size*sizeof( struct msghdr ) ); for ( ifihead = ifi = get_ifi_info_plus( AF_INET, 1 ); ifi != NULL; ifi = ifi->ifi_next) { sockfd[sockcount]=-1; printf("Total sockets bound : %d\n",sockcount); int x = 0; /*4bind unicast address */ if( ( sockfd[ sockcount ] = socket( AF_INET, SOCK_DGRAM, 0 ) ) == NULL ) { printf( "socket error\n" ); exit(1); } setsockopt( sockfd[sockcount], SOL_SOCKET, SO_REUSEADDR, &on, sizeof( on ) ); sa = ( struct sockaddr_in * )ifi->ifi_addr; sa->sin_family = AF_INET; sa->sin_port = htonl( ((int) atoi( configdata[0].data) )); // sa->sin_port = htonl( 12345 ); bind( sockfd[sockcount], (SA *) sa, sizeof( struct sockaddr_in ) ); slen = sizeof( ss ); if( getsockname( sockfd[sockcount], (SA *)&ss, &slen ) < 0 ) { printf( "sockname error\n" ); exit(1); } printf("\nBOUND SOCKET ADDRESSES : %s\n", inet_ntop( AF_INET, &(ss.sin_addr), IPClient, MAXLINE )); printf( "SERVER PORT: %d\n", ss.sin_port ); sockinfo[ sockcount ].sockfd = sockfd[ sockcount ]; sockinfo[ sockcount ].ip_addr = (SA *)sa; sockinfo[ sockcount ].ntmaddr = (struct sockaddr_in *)ifi->ifi_ntmaddr; //sockinfo[sockcount].subnetaddr=ifi->sockfd[sockcount]; printf( "\nSocket File Descriptor : %d\n", sockinfo[ sockcount ].sockfd ); printf( "IP addr: %s\n", sock_ntop_host( (SA *)sockinfo[sockcount].ip_addr, sizeof( *sockinfo[sockcount].ip_addr ) ) ); printf( "Network Mask : %s\n", sock_ntop_host( (SA *)sockinfo[sockcount].ntmaddr, sizeof(*sockinfo[sockcount].ntmaddr ) ) ); sockcount++; // if ( (pid = fork()) == 0) { /* child */ // mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa); // exit(0); /* never executed */ // } /* end udpserv1 */ } maxfdp1 = -1; FD_ZERO( &allset ); for( i = 0; i<sockcount; i++ ) { FD_SET( sockinfo[ i ].sockfd, &allset ); if( sockinfo[ i ].sockfd > maxfdp1 ) { maxfdp1 = sockinfo[ i ].sockfd; } } for ( ; ; ) { rset = allset; if ( ( nready = select( maxfdp1 + 1, &rset, NULL, NULL, NULL ) ) < 0 ) { if ( errno == EINTR ) continue; /* back to for() */ else err_sys("select error"); } for( i = 0; i<sockcount; i++ ) { if( FD_ISSET( sockinfo[ i ].sockfd, &rset ) ) { len = sizeof( cliaddr ); char hsMsg[PACKET_SIZE]; char recvBufStr[PACKET_SIZE]; n = recvfrom( sockinfo[ i ].sockfd, hsMsg, PACKET_SIZE, 0, (SA *) &cliaddr, &len ); printf("\nMESSAGE RECIEVED FROM CLIENT : %s\n", hsMsg ); sscanf(hsMsg,"%s %s",mesg,recvBufStr); recv_window_size=atoi(recvBufStr); inet_ntop( AF_INET, &cliaddr.sin_addr, IPClient, MAXLINE ); printf("CLIENT ADDRESS : %s\n\n",IPClient ); /* Returns which interface onto which the client has connected. */ if( getsockname( sockinfo[ i ].sockfd, (SA *)&ss, &slen ) < 0 ) { printf( "sockname error\n" ); exit(1); } printf("\nCONNECTION RECEIVED ON :\n "); printf("BOUND SOCKET ADDRESS : %s\n", inet_ntop( AF_INET, &(ss.sin_addr), IPServer, MAXLINE )); printf( "SERVER PORT: %d\n", ss.sin_port ); // printf( "sockfd----- %d\n", sockinfo[ i ].sockfd ); printf("\nChecking if Server is LOCAL to client..\n"); if( strcmp( IPServer, "127.0.0.1\n" ) == 0 ) { printf("STATUS : SAME HOST\nCLIENT ADDRESS : %s\nSERVER ADDRESS : %s\n", IPClient, IPServer ); is_local = 1; } else { struct in_addr ip, netmask, subnet, clientip, default_ip; struct in_addr longest_prefix_ip, longest_prefix_netmask; char network1[MAXLINE], network2[MAXLINE], ip1[MAXLINE], nm1[MAXLINE]; struct sockaddr_in *sd = (struct sockaddr_in *)(sockinfo[ i ].ip_addr); struct sockaddr_in *se = (struct sockaddr_in *)(sockinfo[ i ].ntmaddr); ip = sd->sin_addr; netmask = se->sin_addr; subnet.s_addr = ip.s_addr & netmask.s_addr; inet_ntop( AF_INET, &subnet, network1, MAXLINE ); inet_ntop( AF_INET, &ip, ip1, MAXLINE ); inet_ntop( AF_INET, &netmask, nm1, MAXLINE ); inet_pton( AF_INET, IPClient, &clientip ); subnet.s_addr = clientip.s_addr & netmask.s_addr; inet_ntop( AF_INET, &subnet, network2, MAXLINE ); if( strcmp( network1, network2 ) == 0 ) { /* LOCAL */ printf("STATUS : LOCAL\nCLIENT ADDRESS (IPClient) : %s\nSERVER ADDRESS (IPServer) : %s\n", IPClient, IPServer ); is_local = 1; } else { printf("STATUS : NOT LOCAL\nCLIENT ADDRESS : %s\nSERVER ADDRESS : %s\n", IPClient, IPServer ); is_local = 0; } } /* Filling up the child server address structure. */ childservaddr.sin_family = AF_INET; childservaddr.sin_port = htonl( 0 ); inet_pton( AF_INET, IPServer, &childservaddr.sin_addr ); slen = sizeof( ss ); inet_pton( AF_INET, IPServer, &childservaddr.sin_addr ); if ( ( pid = fork() ) == 0 ) { /* child */ if( is_local == 1 ) { setsockopt( sockinfo[ i ].sockfd, SOL_SOCKET, SO_DONTROUTE, &on, sizeof( on ) ) ; } mydg_echo( sockinfo[ i ].sockfd, (SA *) &childservaddr, sizeof(childservaddr), (SA *) &cliaddr, sizeof(cliaddr), mesg ); exit(0); /* never executed */ } } } } exit(0); }
int main(int argc, char **argv) { struct ODRmsg *msg; struct hwa_info *hwa, *hwahead; struct sockaddr_un su; struct sockaddr temp; struct sockaddr_un sckadr; struct sockaddr *sa; socklen_t addrlen; int i, j; int protocol, maxfdp1; fd_set rset; //char address[16]; char rcvline[MAXLINE]; struct hostent *host; if(argc < 2) { printf("Usage: odr staleness\n"); return -1; } staleness = atoi(argv[1]); gethostname(name, 16); host = malloc(sizeof(struct hostent)); host = gethostbyname(name); if(host == NULL) printf("host is NULL\n"); strncpy(canonical, inet_ntoa( *( struct in_addr*)( host -> h_addr_list[0])), 16); printf("Local ODR on host %s\n", name); printf( "Canonical IP: %s\n", canonical); printf("Finding interfaces\n"); for (i = 0, hwahead = hwa = Get_hw_addrs(); hwa != NULL && i < MAX_INTERFACES; hwa = hwa->hwa_next, i++) { if(strncmp(hwa->if_name, "eth0", 4) != 0 && strncmp(hwa->if_name, "lo", 2) != 0) { /* for(j = 0; j < 6; j++) { interfaces[i].if_haddr[j] = hwa->if_haddr[j]; }*/ memcpy((void*)interfaces[i].if_haddr, (void*)hwa->if_haddr, 6); interfaces[i].if_index = hwa->if_index; sa = hwa->ip_addr; strncpy(interfaces[i].ip_addr, sock_ntop_host(sa, sizeof(*sa)), 16); printf("IP Address: %s\n", interfaces[i].ip_addr); printf("Hardware Address: "); printHW(interfaces[i].if_haddr); printf("\nIndex: %d\n\n", interfaces[i].if_index); } else i--; } if_nums = i; err_msg("%s",ODR_SUNPATH); printf("Found %d interfaces\n", if_nums); //Creating packet socket pfsock = socket(AF_PACKET, SOCK_RAW, htons(ODR_PROTOCOL)); if(pfsock < 0) { printf("pfsock: %d %s\n", errno, strerror(errno)); return -1; } unlink(ODR_SUNPATH); bzero(&su, sizeof(su)); su.sun_family = AF_LOCAL; strcpy(su.sun_path, ODR_SUNPATH); //strcat(su.sun_path, "\0"); appsock = socket(AF_LOCAL, SOCK_DGRAM, 0); if(appsock < 0) { printf("appsock: %d %s\n", errno, strerror(errno)); return -1; } if(bind(appsock, (struct sockaddr*) &su, sizeof(su)) < 0) { printf("bind failed: %d %s\n", errno, strerror(errno)); return -1; } FD_ZERO(&rset); printf("Bound appsock\n"); for ( ; ; ) { FD_SET(pfsock, &rset); FD_SET(appsock, &rset); maxfdp1 = max(pfsock, appsock) + 1; printf("Selecting...\n"); if(select(maxfdp1, &rset, NULL, NULL, NULL) < 0) { printf("select error: %d %s\n", errno, strerror(errno)); } if(FD_ISSET(appsock, &rset)) { printf("appsock is ready\n"); //msg_recv(appsock, message, address, port); addrlen = sizeof(sckadr); if(recvfrom(appsock, rcvline, MAXLINE, 0, &temp, &addrlen) < 0) { printf("appsock recvfrom error: %d %s\n", errno, strerror(errno)); return -1; } //su = (struct sockaddr_un*) sa; //err_msg("%s",temp.sa_data); //err_msg("%d",addrlen); processAPPmsg(rcvline, &temp); } if(FD_ISSET(pfsock, &rset)) { printf("pfsock is ready\n"); if(recvfrom(pfsock, rcvline, MAXLINE, 0, sa, &addrlen) < 0) { printf("pfsock recvmsg error: %d %s\n", errno, strerror(errno)); return -1; } printf("Received message: \n"); printf("From: "); printHW(rcvline); printHW(rcvline + ETH_ALEN); if(!toss()) { msg = rcvline + 14; memcpy((void*)neighbor, (void*)rcvline + ETH_ALEN, ETH_ALEN); printf(" To: "); printHW(neighbor); printf("\n"); processODRmsg(msg, sa); } else printf("Toss it!\n"); } } }
int recv_v6(int seq, struct timeval *tv) { int hlen2, icmp6len, ret; ssize_t n; socklen_t len; struct ip6_hdr *hip6; struct icmp6_hdr *icmp6; struct udphdr *udp; gotalarm = 0; alarm(3); for ( ; ; ) { if (gotalarm) return -3; /* alarm expired */ len = pr->salen; n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len); if (n < 0) { /* * EINTR indicates an interrupted system call (maybe by our SIGALRM). * Linux doesn't interrupt recvfrom() so we set a socket timeout option * (in traceloop() function). If recvfrom() times out, it returns * EAGAIN == EWOULDBLOCK */ if (errno == EINTR || errno == EAGAIN) continue; else err_sys("recvfrom() error"); } icmp6 = (struct icmp6_hdr *) recvbuf; /* ICMP header */ if ((icmp6len = n) < 8) continue; /* not enough to look at ICMP header */ if (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED && icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) { if (icmp6len < 8 + sizeof(struct ip6_hdr) + 4) continue; /* not enough data to look at inner header */ hip6 = (struct ip6_hdr *) (recvbuf + 8); /* skip over ICMP header to get to inner IPv6 */ hlen2 = sizeof(struct ip6_hdr); udp = (struct udphdr *) (recvbuf + 8 + hlen2); /* skip over IPv6 header and inner IPv6 to get to inner UDP */ if (hip6->ip6_nxt == IPPROTO_UDP && udp->source == htons(sport) && /* BSD: udp->uh_sport */ udp->dest == htons(dport + seq)) { /* BSD: udp->uh_dport */ ret = -2; /* we hit an intermediate router */ break; } } else if (icmp6->icmp6_type == ICMP6_DST_UNREACH) { if (icmp6len < 8 + sizeof(struct ip6_hdr) + 4) continue; /* not enough data to look at inner header */ hip6 = (struct ip6_hdr *) (recvbuf + 8); /* skip over ICMP header to get to inner IPv6 */ hlen2 = sizeof(struct ip6_hdr); udp = (struct udphdr *) (recvbuf + 8 + hlen2); /* skip over IPv6 header and inner IPv6 to get to inner UDP */ if (hip6->ip6_nxt == IPPROTO_UDP && udp->source == htons(sport) && /* BSD: udp->uh_sport */ udp->dest == htons(dport + seq)) { /* BSD: udp->uh_dport */ if (icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT) ret = -1; /* have reached destination */ else ret = icmp6->icmp6_code; /* 0, 1, 2, ... */ break; } } else if (verbose) { printf(" (from %s: type = %d, code = %d)\n", sock_ntop_host(pr->sarecv, pr->salen), icmp6->icmp6_type, icmp6->icmp6_code); } /* Some other ICMP error, recvfrom() again */ } alarm(0); /* don't leave alarm running */ gettimeofday(tv, NULL); /* get time of packet arrival */ return ret; }
void GetSdpDescr(RTSP_buffer * pRtsp, char *pDescr, char *s8Str) { /*/===================================== char const* const SdpPrefixFmt = "v=0\r\n" //版本信息 "o=- %s %s IN IP4 %s\r\n" //<用户名><会话id><版本>//<网络类型><地址类型><地址> "c=IN IP4 %s\r\n" //c=<网络信息><地址信息><连接地址>对ip4为0.0.0.0 here! "s=RTSP Session\r\n" //会话名session id "i=N/A\r\n" //会话信息 "t=0 0\r\n" //<开始时间><结束时间> "a=recvonly\r\n" "m=video %s RTP/AVP 96\r\n\r\n"; //<媒体格式><端口><传送><格式列表,即媒体净荷类型> m=video 5004 RTP/AVP 96 struct ifreq stIfr; char pSdpId[128]; //获取本机地址 strcpy(stIfr.ifr_name, "eth0"); if(ioctl(pRtsp->fd, SIOCGIFADDR, &stIfr) < 0) { //printf("Failed to get host eth0 ip\n"); strcpy(stIfr.ifr_name, "wlan0"); if(ioctl(pRtsp->fd, SIOCGIFADDR, &stIfr) < 0) { printf("Failed to get host eth0 or wlan0 ip\n"); } } sock_ntop_host(&stIfr.ifr_addr, sizeof(struct sockaddr), s8Str, 128); GetSdpId(pSdpId); sprintf(pDescr, SdpPrefixFmt, pSdpId, pSdpId, s8Str, inet_ntoa(((struct sockaddr_in *)(&pRtsp->stClientAddr))->sin_addr), "5006", "H264"); "b=RR:0\r\n" //按spydroid改 "a=rtpmap:96 %s/90000\r\n" //a=rtpmap:<净荷类型><编码名>/<时钟速率> a=rtpmap:96 H264/90000 "a=fmtp:96 packetization-mode=1;profile-level-id=1EE042;sprop-parameter-sets=QuAe2gLASRA=,zjCkgA==\r\n" "a=control:trackID=0\r\n"; #ifdef RTSP_DEBUG // printf("SDP:\n%s\n", pDescr); #endif */ struct ifreq stIfr; char pSdpId[128]; char rtp_port[5]; strcpy(stIfr.ifr_name, "wlan0"); if(ioctl(pRtsp->fd, SIOCGIFADDR, &stIfr) < 0) { //printf("Failed to get host eth0 ip\n"); strcpy(stIfr.ifr_name, "wlan1"); if(ioctl(pRtsp->fd, SIOCGIFADDR, &stIfr) < 0) { printf("Failed to get host eth0 or wlan0 ip\n"); } } sock_ntop_host(&stIfr.ifr_addr, sizeof(struct sockaddr), s8Str, 128); GetSdpId(pSdpId); strcpy(pDescr, "v=0\r\n"); strcat(pDescr, "o=-"); strcat(pDescr, pSdpId); strcat(pDescr," "); strcat(pDescr, pSdpId); strcat(pDescr," IN IP4 "); strcat(pDescr, s8Str); strcat(pDescr, "\r\n"); strcat(pDescr, "s=Unnamed\r\n"); strcat(pDescr, "i=N/A\r\n"); strcat(pDescr, "c="); strcat(pDescr, "IN "); /* Network type: Internet. */ strcat(pDescr, "IP4 "); /* Address type: IP4. */ //strcat(pDescr, get_address()); strcat(pDescr, inet_ntoa(((struct sockaddr_in *)(&pRtsp->stClientAddr))->sin_addr)); strcat(pDescr, "\r\n"); strcat(pDescr, "t=0 0\r\n"); strcat(pDescr, "a=recvonly\r\n"); /**** media specific ****/ strcat(pDescr,"m="); strcat(pDescr,"video "); sprintf(rtp_port,"%d",s_u32StartPort); strcat(pDescr, rtp_port); strcat(pDescr," RTP/AVP "); /* Use UDP */ strcat(pDescr,"96\r\n"); //strcat(pDescr, "\r\n"); strcat(pDescr,"b=RR:0\r\n"); /**** Dynamically defined payload ****/ strcat(pDescr,"a=rtpmap:96"); strcat(pDescr," "); strcat(pDescr,"H264/90000"); strcat(pDescr, "\r\n"); strcat(pDescr,"a=fmtp:96 packetization-mode=1;"); strcat(pDescr,"profile-level-id="); strcat(pDescr,psp.base64profileid); strcat(pDescr,";sprop-parameter-sets="); strcat(pDescr,psp.base64sps); strcat(pDescr,","); strcat(pDescr,psp.base64pps); strcat(pDescr,";"); strcat(pDescr, "\r\n"); strcat(pDescr,"a=control:trackID=0"); strcat(pDescr, "\r\n"); /* strcat(pDescr, "m=audio "); strcat(pDescr,"5004"); strcat(pDescr," RTP/AVP 96\r\n"); strcat(pDescr, "b=AS:128\r\n"); strcat(pDescr, "b=RR:0\r\n"); strcat(pDescr, "a=rtpmap:96 AMR/8000\r\n"); strcat(pDescr, "a=fmtp:96 octrt-align=1;\r\n"); strcat(pDescr,"a=control:trackID=1"); strcat(pDescr, "\r\n"); */ //strcat(pDescr, "\r\n"); //printf("0\r\n"); }
/** * Create a new socket accepting a new connection from a listening socket. * @param main Listening socket. * @param octx optional ssl global context * @return the newly allocated Sock */ Sock * Sock_accept(Sock *s, void * octx) { int res = -1; char remote_host[128]; /*Unix Domain is largest*/ char local_host[128]; /*Unix Domain is largest*/ int remote_port = -1; int local_port = -1; Sock *new_s = NULL; struct sockaddr *sa_p = NULL; socklen_t sa_len = 0; #if ENABLE_SSL SSL_CTX * ctx = octx; SSL *ssl_con = NULL; #endif if (!s) return NULL; if ((res = sock_accept(s->fd)) < 0) { net_log(NET_LOG_ERR, "System error in sock_accept().\n"); return NULL; } #if ENABLE_SSL if(ctx) { if( !(ssl_con = SSL_sock_accept(res, ctx)) ) { net_log(NET_LOG_ERR, "Unable to accept SSL connection.\n"); sock_close(res); return NULL; } } #endif if (!(new_s = calloc(1, sizeof(Sock)))) { net_log(NET_LOG_FATAL, "Unable to allocate a Sock struct in Sock_accept().\n"); #if ENABLE_SSL if(ctx) SSL_close_connection(ssl_con, res); #endif sock_close(res); return NULL; } new_s->fd = res; new_s->socktype = s->socktype; new_s->flags = s->flags; #if ENABLE_SSL if(ctx) new_s->ssl = ssl_con; #endif sa_p = (struct sockaddr *) &(new_s->remote_stg); sa_len = sizeof(struct sockaddr_storage); if(getpeername(res, sa_p, &sa_len)) { net_log(NET_LOG_ERR, "Unable to get remote address in Sock_accept().\n"); Sock_close(new_s); return NULL; } if(!sock_ntop_host(sa_p, remote_host, sizeof(remote_host))) memset(remote_host, 0, sizeof(remote_host)); if (!(new_s->remote_host = strdup(remote_host))) { net_log(NET_LOG_FATAL, "Unable to allocate remote host in Sock_accept().\n"); Sock_close(new_s); return NULL; } remote_port = sock_get_port(sa_p); if(remote_port < 0) { net_log(NET_LOG_ERR, "Unable to get remote port in Sock_accept().\n"); Sock_close(new_s); return NULL; } else new_s->remote_port = ntohs(remote_port); sa_p = (struct sockaddr *) &(new_s->remote_stg); sa_len = sizeof(struct sockaddr_storage); if(getsockname(res, sa_p, &sa_len)) { net_log(NET_LOG_ERR, "Unable to get remote port in Sock_accept().\n"); Sock_close(new_s); return NULL; } if(!sock_ntop_host(sa_p, local_host, sizeof(local_host))) memset(local_host, 0, sizeof(local_host)); if (!(new_s->local_host = strdup(local_host))) { net_log(NET_LOG_FATAL, "Unable to allocate local host in Sock_accept().\n"); Sock_close(new_s); return NULL; } local_port = sock_get_port(sa_p); if(local_port < 0) { net_log(NET_LOG_ERR, "Unable to get local port in Sock_accept().\n"); Sock_close(new_s); return NULL; } else new_s->local_port = ntohs(local_port); net_log(NET_LOG_DEBUG, "Socket accepted between local=\"%s\":%u and " "remote=\"%s\":%u.\n", new_s->local_host, new_s->local_port, new_s->remote_host, new_s->remote_port); return new_s; }
// function used to configure a route to "daddr" by specifying either // the gateway address "gaddr" or the interface name "ifname"; // a mask given by "maddr" can also be specified // the command codes "cmd" indicate the type of operation // Note: addresses are given as 4-byte words (c.f. rtctl) int rtctl2(uint32_t *daddr, /* destination IP address */ uint32_t *gaddr, /* gateway IP address */ uint32_t *maddr, /* subnet mask */ char *ifname, /* network interface name */ u_char cmd) /* RTM_ADD RTM_DELETE RTM_CHANGE */ { int sockfd, mib[6], len; char *buf, rta_cmd[RTCTL_CMD_LEN], *ifbuf; char dstaddr[16], gateaddr[16], maskaddr[16]; u_char flag; pid_t pid; struct rt_msghdr *rtm; struct sockaddr_in *dst, *gate, *mask; struct sockaddr_dl *ifp, *sdl; struct if_msghdr *ifm; #ifdef RTCTL_PRINT_RESPONSE ssize_t n; struct sockaddr *sa, *rti_info[RTAX_MAX]; #endif /* check the arguments */ if (daddr == NULL) { fprintf(stderr, "Invalid destination IP address\n"); return -1; } flag = 0; if (cmd == RTM_ADD) { flag |= RTCTL_ADD; strncpy(rta_cmd, "add", sizeof("add")); if (gaddr == NULL) { if (ifname == NULL) flag |= RTCTL_UNKNOWN; else if (maddr != NULL) flag |= RTCTL_UNKNOWN; else flag |= RTCTL_IF; } else { flag |= RTCTL_GATEWAY; if (ifname != NULL) flag |= RTCTL_UNKNOWN; else if (maddr != NULL) flag |= RTCTL_NETMASK; } } else if (cmd == RTM_DELETE) { flag |= RTCTL_DELETE; strncpy(rta_cmd, "delete", sizeof("delete")); if ((ifname != NULL) | (gaddr != NULL) | (maddr != NULL)) flag |= RTCTL_UNKNOWN; } else if (cmd == RTM_CHANGE) { flag |= RTCTL_CHANGE; strncpy(rta_cmd, "change", sizeof("change")); if (gaddr == NULL) { if (ifname == NULL) flag |= RTCTL_UNKNOWN; else if (maddr != NULL) flag |= RTCTL_UNKNOWN; else flag |= RTCTL_IF; } else { flag |= RTCTL_GATEWAY; if (ifname != NULL) flag |= RTCTL_UNKNOWN; else if (maddr != NULL) flag |= RTCTL_NETMASK; } } else { fprintf(stderr, "Invalid command name\n"); return -1; } if (flag & RTCTL_UNKNOWN) { fprintf(stderr, "Unknown arguments are inputed.\n"); return -1; } if ((buf = calloc(1, BUFLEN)) == NULL) { perror("calloc"); return -1; } /* set address of rt messages */ rtm = (struct rt_msghdr *) buf; rtm->rtm_version = RTM_VERSION; rtm->rtm_type = cmd; rtm->rtm_pid = pid = getpid(); rtm->rtm_seq = ++rtm_seq; rtm->rtm_errno = 0; if ((flag & RTCTL_ADD) | (flag & RTCTL_CHANGE)) { if (flag & RTCTL_IF) { rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in) + sizeof(struct sockaddr_dl); rtm->rtm_addrs = RTA_DST | RTA_GATEWAY; rtm->rtm_flags = RTF_UP | RTF_HOST | RTF_LLINFO | RTF_STATIC; } else if (flag & RTCTL_NETMASK) { rtm->rtm_msglen = sizeof(struct rt_msghdr) + 3 * sizeof(struct sockaddr_in); rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; rtm->rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; } else { rtm->rtm_msglen = sizeof(struct rt_msghdr) + 2 * sizeof(struct sockaddr_in); rtm->rtm_addrs = RTA_DST | RTA_GATEWAY; rtm->rtm_flags = RTF_UP | RTF_HOST | RTF_GATEWAY | RTF_STATIC; } } else if (flag & RTCTL_DELETE) { rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in); rtm->rtm_addrs = RTA_DST; } /* set destination RTA_GATEWAY */ dst = (struct sockaddr_in *) (rtm + 1); dst->sin_len = sizeof(struct sockaddr_in); dst->sin_family = AF_INET; fflush(stderr); dst->sin_addr.s_addr = *daddr; if (flag & RTCTL_GATEWAY) { /* set gateway */ gate = (struct sockaddr_in *) (dst + 1); gate->sin_len = sizeof(struct sockaddr_in); gate->sin_family = AF_INET; gate->sin_addr.s_addr = *gaddr; if (flag & RTCTL_NETMASK) { mask = (struct sockaddr_in *) (gate + 1); mask->sin_len = sizeof(struct sockaddr_in); mask->sin_family = AF_INET; mask->sin_addr.s_addr = *maddr; } } else if (flag & RTCTL_IF) { /* get sockaddr_dl info */ mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; if ((mib[5] = if_nametoindex(ifname)) == 0) { perror("if_nametoindex"); return -1; } if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { perror("sysctl"); return -1; } if ((ifbuf = calloc(1, len)) == NULL) { perror("calloc"); return -1; } if (sysctl(mib, 6, ifbuf, &len, NULL, 0) < 0) { perror("sysctl2"); return -1; } ifm = (struct if_msghdr *) ifbuf; sdl = (struct sockaddr_dl *) (ifm + 1); /* set network interface */ ifp = (struct sockaddr_dl *) (dst + 1); bcopy(sdl, ifp, sizeof(struct sockaddr_dl)); ifp->sdl_len = sizeof(struct sockaddr_dl); } if ((sockfd = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) { perror("socket"); return -1; } if (write(sockfd, rtm, rtm->rtm_msglen) < 0) { perror("write"); //return -1; } else { strncpy(dstaddr, "", sizeof(dstaddr)); strncpy(gateaddr, "", sizeof(gateaddr)); strncpy(maskaddr, "", sizeof(maskaddr)); strncpy(dstaddr, inet_ntoa(dst->sin_addr), sizeof(dstaddr)); if (gaddr != NULL) strncpy(gateaddr, inet_ntoa(gate->sin_addr), sizeof(gateaddr)); if (maddr != NULL) strncpy(maskaddr, inet_ntoa(mask->sin_addr), sizeof(maskaddr)); fprintf(stderr, "\troute %s dst:%s gate:%s mask:%s ifp:%s\n", rta_cmd, dstaddr, gateaddr, maskaddr, ifname); /* A chunk of lines like this: */ /* strncpy(dstaddr, "", sizeof(dstaddr)); */ /* strncpy(gateaddr, "", sizeof(gateaddr)); */ /* strncpy(maskaddr, "", sizeof(maskaddr)); */ /* strncpy(dstaddr, inet_ntoa(dst->sin_addr), sizeof(dstaddr)); */ /* if (gaddr != NULL) */ /* strncpy(gateaddr, inet_ntoa(gate->sin_addr), */ /* sizeof(gateaddr)); */ /* if (maddr != NULL) */ /* strncpy(maskaddr, inet_ntoa(mask->sin_addr), */ /* sizeof(maskaddr)); */ /* fprintf(stderr, "\troute %s dst:%s gate:%s mask:%s ifp:%s\n", */ /* rta_cmd, dstaddr, gateaddr, maskaddr, ifname); */ /* can be rewritten as: */ /* fprintf(stderr, "\troute %s dst:%s gate:%s ", rta_cmd, dstaddr, */ /* (gaddr != NULL) : inet_ntoa(gate->sin_addr) ? ""); */ /* fprintf(stderr, "mask:%s ifp:%s\n", */ /* (maddr != NULL) : inet_ntoa(mask->sin_addr) ? "", ifname); */ } #ifdef RTCTL_PRINT_RESPONSE fprintf(stderr, "---print response\n"); do { n = read(sockfd, rtm, BUFLEN); } while (rtm->rtm_seq != rtm_seq || rtm->rtm_pid != pid); /* handle response */ rtm = (struct rt_msghdr *) buf; sa = (struct sockaddr *) (rtm + 1); get_rtaddrs(rtm->rtm_addrs, sa, rti_info); if ((sa = rti_info[RTAX_DST]) != NULL) fprintf(stderr, "dest: %s\n", sock_ntop_host(sa, sa->sa_len)); if ((sa = rti_info[RTAX_GATEWAY]) != NULL) fprintf(stderr, "gateway: %s\n", sock_ntop_host(sa, sa->sa_len)); if ((sa = rti_info[RTAX_NETMASK]) != NULL) fprintf(stderr, "netmask: %s\n", sock_masktop(sa, sa->sa_len)); if ((sa = rti_info[RTAX_GENMASK]) != NULL) fprintf(stderr, "genmask: %s\n", sock_masktop(sa, sa->sa_len)); if ((sa = rti_info[RTAX_IFP]) != NULL) fprintf(stderr, "ifp: len:%d fami:%d data:%s\n", sa->sa_len, sa->sa_family, sa->sa_data); if ((sa = rti_info[RTAX_IFA]) != NULL) fprintf(stderr, "ifa: len:%d fami:%d data:%s\n", sa->sa_len, sa->sa_family, sa->sa_data); if ((sa = rti_info[RTAX_AUTHOR]) != NULL) fprintf(stderr, "author: len:%d fami:%d data:%s\n", sa->sa_len, sa->sa_family, sa->sa_data); if ((sa = rti_info[RTAX_BRD]) != NULL) fprintf(stderr, "brd: len:%d fami:%d data:%s\n", sa->sa_len, sa->sa_family, sa->sa_data); #endif free(buf); if (flag & RTCTL_IF) free(ifbuf); return 0; }
int recv_v4(int seq, struct timeval *tv) { int hlen1, hlen2, icmplen, ret; socklen_t len; ssize_t n; struct ip *ip, *hip; struct icmp *icmp; struct udphdr *udp; gotalarm = 0; alarm(3); for ( ; ; ) { if (gotalarm) return(-3); /* alarm expired */ len = pr->salen; n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len); if (n < 0) { if (errno == EINTR) continue; else error(1, errno, "recvfrom error"); } ip = (struct ip *) recvbuf; /* start of IP header */ hlen1 = ip->ip_hl << 2; /* length of IP header */ icmp = (struct icmp *) (recvbuf + hlen1); /* start of ICMP header */ if ( (icmplen = n - hlen1) < 8) continue; /* not enough to look at ICMP header */ if (icmp->icmp_type == ICMP_TIMXCEED && icmp->icmp_code == ICMP_TIMXCEED_INTRANS) { if (icmplen < 8 + sizeof(struct ip)) continue; /* not enough data to look at inner IP */ hip = (struct ip *) (recvbuf + hlen1 + 8); hlen2 = hip->ip_hl << 2; if (icmplen < 8 + hlen2 + 4) continue; /* not enough data to look at UDP ports */ udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2); if (hip->ip_p == IPPROTO_UDP && udp->source == htons(sport) && udp->dest == htons(dport + seq)) { ret = -2; /* we hit an intermediate router */ break; } } else if (icmp->icmp_type == ICMP_UNREACH) { if (icmplen < 8 + sizeof(struct ip)) continue; /* not enough data to look at inner IP */ hip = (struct ip *) (recvbuf + hlen1 + 8); hlen2 = hip->ip_hl << 2; if (icmplen < 8 + hlen2 + 4) continue; /* not enough data to look at UDP ports */ udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2); if (hip->ip_p == IPPROTO_UDP && udp->source == htons(sport) && udp->dest == htons(dport + seq)) { if (icmp->icmp_code == ICMP_UNREACH_PORT) ret = -1; /* have reached destination */ else ret = icmp->icmp_code; /* 0, 1, 2, ... */ break; } } if (verbose) { printf(" (from %s: type = %d, code = %d)\n", sock_ntop_host(pr->sarecv, pr->salen, ipstr, sizeof(ipstr)), icmp->icmp_type, icmp->icmp_code); } /* Some other ICMP error, recvfrom() again */ } alarm(0); /* don't leave alarm running */ gettimeofday(tv, NULL); /* get time of packet arrival */ return(ret); }
void traceloop(void) { int seq, code, done; double rtt; struct rec *rec; struct timeval tvrecv; recvfd = socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto); setuid(getuid()); /* don't need special permissions anymore */ #ifdef IPV6 if (pr->sasend->sa_family == AF_INET6 && verbose == 0) { struct icmp6_filter myfilt; ICMP6_FILTER_SETBLOCKALL(&myfilt); ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &myfilt); ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &myfilt); setsockopt(recvfd, IPPROTO_IPV6, ICMP6_FILTER, &myfilt, sizeof(myfilt)); } #endif sendfd = socket(pr->sasend->sa_family, SOCK_DGRAM, 0); pr->sabind->sa_family = pr->sasend->sa_family; sport = (getpid() & 0xffff) | 0x8000; /* our source UDP port # */ sock_set_port(pr->sabind, pr->salen, htons(sport)); bind(sendfd, pr->sabind, pr->salen); sig_alrm(SIGALRM); seq = 0; done = 0; for (ttl = 1; ttl <= max_ttl && done == 0; ttl++) { setsockopt(sendfd, pr->ttllevel, pr->ttloptname, &ttl, sizeof(int)); bzero(pr->salast, pr->salen); printf("%2d ", ttl); fflush(stdout); for (probe = 0; probe < nprobes; probe++) { rec = (struct rec *) sendbuf; rec->rec_seq = ++seq; rec->rec_ttl = ttl; gettimeofday(&rec->rec_tv, NULL); sock_set_port(pr->sasend, pr->salen, htons(dport + seq)); sendto(sendfd, sendbuf, datalen, 0, pr->sasend, pr->salen); if ( (code = (*pr->recv)(seq, &tvrecv)) == -3) printf(" *"); /* timeout, no reply */ else { char str[NI_MAXHOST]; if (sock_cmp_addr(pr->sarecv, pr->salast, pr->salen) != 0) { if (getnameinfo(pr->sarecv, pr->salen, str, sizeof(str), NULL, 0, 0) == 0) printf(" %s (%s)", str, sock_ntop_host(pr->sarecv, pr->salen, ipstr, sizeof(ipstr))); else printf(" %s", sock_ntop_host(pr->sarecv, pr->salen, ipstr, sizeof(ipstr))); memcpy(pr->salast, pr->sarecv, pr->salen); } tv_sub(&tvrecv, &rec->rec_tv); rtt = tvrecv.tv_sec * 1000.0 + tvrecv.tv_usec / 1000.0; printf(" %.3f ms", rtt); if (code == -1) /* port unreachable; at destination */ done++; else if (code >= 0) printf(" (ICMP %s)", (*pr->icmpcode)(code)); } fflush(stdout); } printf("\n"); } }
Sock * Sock_connect(char *host, char *port, Sock *binded, sock_type socktype, sock_flags ssl_flag) { Sock *s; char remote_host[128]; /*Unix Domain is largest*/ char local_host[128]; /*Unix Domain is largest*/ int sockfd = -1; struct sockaddr *sa_p = NULL; socklen_t sa_len = 0; int32_t local_port; int32_t remote_port; #if HAVE_SSL SSL *ssl_con; #endif if(binded) { sockfd = binded->fd; } if (sock_connect(host, port, &sockfd, socktype)) { net_log(NET_LOG_ERR, "Sock_connect() failure.\n"); return NULL; } #if HAVE_SSL if(ssl_flag & IS_SSL) { if (sock_SSL_connect(&ssl_con)) net_log (NET_LOG_ERR, "Sock_connect() failure in SSL init.\n"); sock_close(sockfd); return NULL; } else #endif if (binded) { s = binded; free(s->local_host); s->local_host = NULL; free(s->remote_host); s->remote_host = NULL; } else if (!(s = calloc(1, sizeof(Sock)))) { net_log(NET_LOG_FATAL, "Unable to allocate a Sock struct in Sock_connect().\n"); #if HAVE_SSL if(ssl_flag & IS_SSL) sock_SSL_close(ssl_con); #endif sock_close (sockfd); return NULL; } s->fd = sockfd; s->socktype = socktype; #if HAVE_SSL if(ssl_flag & IS_SSL) s->ssl = ssl_con; #endif s->flags = ssl_flag; sa_p = (struct sockaddr *) &(s->local_stg); sa_len = sizeof(struct sockaddr_storage); if(getsockname(s->fd, sa_p, &sa_len)) { net_log(NET_LOG_ERR, "Unable to get remote port in Sock_connect().\n"); Sock_close(s); return NULL; } if(!sock_ntop_host(sa_p, local_host, sizeof(local_host))) memset(local_host, 0, sizeof(local_host)); if (!(s->local_host = strdup(local_host))) { net_log(NET_LOG_FATAL, "Unable to allocate local host in Sock_connect().\n"); Sock_close(s); return NULL; } local_port = sock_get_port(sa_p); if(local_port < 0) { net_log(NET_LOG_ERR, "Unable to get local port in Sock_connect().\n"); Sock_close(s); return NULL; } else s->local_port = ntohs(local_port); sa_p = (struct sockaddr *) &(s->remote_stg); sa_len = sizeof(struct sockaddr_storage); if(getpeername(s->fd, sa_p, &sa_len)) { net_log(NET_LOG_ERR, "Unable to get remote address in Sock_connect().\n"); Sock_close(s); return NULL; } if(!sock_ntop_host(sa_p, remote_host, sizeof(remote_host))) memset(remote_host, 0, sizeof(remote_host)); if (!(s->remote_host = strdup(remote_host))) { net_log(NET_LOG_FATAL, "Unable to allocate remote host in Sock_connect().\n"); Sock_close(s); return NULL; } remote_port = sock_get_port(sa_p); if(remote_port < 0) { net_log(NET_LOG_ERR, "Unable to get remote port in Sock_connect().\n"); Sock_close(s); return NULL; } else s->remote_port = ntohs(remote_port); net_log(NET_LOG_DEBUG, "Socket connected between local=\"%s\":%u and " "remote=\"%s\":%u.\n", s->local_host, s->local_port, s->remote_host, s->remote_port); if(is_multicast_address(sa_p, s->remote_stg.ss_family)) { //fprintf(stderr,"IS MULTICAST\n"); if(mcast_join(s->fd, sa_p, NULL, 0, &(s->addr))!=0) { Sock_close(s); return NULL; } s->flags |= IS_MULTICAST; } return s; }
int getrt(char *ipaddr) { int sockfd; char *buf; pid_t pid; ssize_t n; struct rt_msghdr *rtm; struct sockaddr *sa, *rti_info[RTAX_MAX]; struct sockaddr_in *sin; if (ipaddr == NULL) { fprintf(stderr, "getrt: IP address.\n"); return -1; } if ((sockfd = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) { perror("socket"); return -1; } buf = calloc(1, BUFLEN); rtm = (struct rt_msghdr *) buf; rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in); rtm->rtm_version = RTM_VERSION; rtm->rtm_type = RTM_GET; rtm->rtm_addrs = RTA_DST; rtm->rtm_pid = pid = getpid(); rtm->rtm_seq = SEQ; sin = (struct sockaddr_in *) (rtm + 1); sin->sin_len = sizeof(struct sockaddr_in); sin->sin_family = AF_INET; inet_pton(AF_INET, ipaddr, &sin->sin_addr); if (write(sockfd, rtm, rtm->rtm_msglen) < 0) { perror("write"); exit(1); } do { n = read(sockfd, rtm, BUFLEN); } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ || rtm->rtm_pid != pid); /* handle response */ rtm = (struct rt_msghdr *) buf; sa = (struct sockaddr *) (rtm + 1); get_rtaddrs(rtm->rtm_addrs, sa, rti_info); if ((sa = rti_info[RTAX_DST]) != NULL) fprintf(stderr, "dest: %s\n", sock_ntop_host(sa, sa->sa_len)); if ((sa = rti_info[RTAX_GATEWAY]) != NULL) fprintf(stderr, "gateway: %s\n", sock_ntop_host(sa, sa->sa_len)); if ((sa = rti_info[RTAX_NETMASK]) != NULL) fprintf(stderr, "netmask: %s\n", sock_masktop(sa, sa->sa_len)); if ((sa = rti_info[RTAX_GENMASK]) != NULL) fprintf(stderr, "genmask: %s\n", sock_masktop(sa, sa->sa_len)); if ((sa = rti_info[RTAX_IFP]) != NULL) fprintf(stderr, "ifp: len:%d fami:%d data:%s\n", sa->sa_len, sa->sa_family, sa->sa_data); if ((sa = rti_info[RTAX_IFA]) != NULL) fprintf(stderr, "ifa: len:%d fami:%d data:%s\n", sa->sa_len, sa->sa_family, sa->sa_data); return 0; }
int recv_v6(int seq, struct timeval *tv) { int hlen2, icmp6len, ret; ssize_t n; socklen_t len; struct ip6_hdr *hip6; struct icmp6_hdr *icmp6; struct udphdr *udp; gotalarm = 0; alarm(3); for ( ; ; ) { if (gotalarm) return(-3); /* alarm expired */ len = pr->salen; n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len); if (n < 0) { if (errno == EINTR) continue; else error(1, errno, "recvfrom error"); } icmp6 = (struct icmp6_hdr *) recvbuf; /* ICMP header */ if ( ( icmp6len = n ) < 8) continue; /* not enough to look at ICMP header */ if (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED && icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) { if (icmp6len < 8 + sizeof(struct ip6_hdr) + 4) continue; /* not enough data to look at inner header */ hip6 = (struct ip6_hdr *) (recvbuf + 8); hlen2 = sizeof(struct ip6_hdr); udp = (struct udphdr *) (recvbuf + 8 + hlen2); if (hip6->ip6_nxt == IPPROTO_UDP && udp->source == htons(sport) && udp->dest == htons(dport + seq)) ret = -2; /* we hit an intermediate router */ break; } else if (icmp6->icmp6_type == ICMP6_DST_UNREACH) { if (icmp6len < 8 + sizeof(struct ip6_hdr) + 4) continue; /* not enough data to look at inner header */ hip6 = (struct ip6_hdr *) (recvbuf + 8); hlen2 = sizeof(struct ip6_hdr); udp = (struct udphdr *) (recvbuf + 8 + hlen2); if (hip6->ip6_nxt == IPPROTO_UDP && udp->source == htons(sport) && udp->dest == htons(dport + seq)) { if (icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT) ret = -1; /* have reached destination */ else ret = icmp6->icmp6_code; /* 0, 1, 2, ... */ break; } } else if (verbose) { printf(" (from %s: type = %d, code = %d)\n", sock_ntop_host(pr->sarecv, pr->salen), icmp6->icmp6_type, icmp6->icmp6_code); } /* Some other ICMP error, recvfrom() again */ } alarm(0); /* don't leave alarm running */ gettimeofday(tv, NULL); /* get time of packet arrival */ return(ret); }
int main(int argc, char **argv) { int c; struct addrinfo *ai; char *h; opterr = 0; /* don't want getopt() writing to stderr */ while ( (c = getopt(argc, argv, "m:v")) != -1) { switch (c) { case 'm': if ( (max_ttl = atoi(optarg)) <= 1) error(1, 0, "invalid -m value"); break; case 'v': verbose++; break; case '?': error(1, 0, "unrecognized option: %c", c); } } if (optind != argc-1) error(1, 0, "usage: traceroute [ -m <maxttl> -v ] <hostname>"); host = argv[optind]; pid = getpid(); //signal(SIGALRM, sig_alrm); struct sigaction act; sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = sig_alrm; if (sigaction(SIGALRM, &act, NULL) == -1) error(1, errno, "sigaction"); ai = host_serv(host, NULL, 0, 0); if (ai == NULL) error(1, 0, "host_serv error"); h = sock_ntop_host(ai->ai_addr, ai->ai_addrlen, ipstr, sizeof(ipstr)); printf("traceroute to %s (%s): %d hops max, %d data bytes\n", ai->ai_canonname ? ai->ai_canonname : h, h, max_ttl, datalen); /* initialize according to protocol */ if (ai->ai_family == AF_INET) { pr = &proto_v4; #ifdef IPV6 } else if (ai->ai_family == AF_INET6) { pr = &proto_v6; if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr))) error(1, 0, "cannot traceroute IPv4-mapped IPv6 address"); #endif } else error(1, 0, "unknown address family %d", ai->ai_family); pr->sasend = ai->ai_addr; /* contains destination address */ pr->sarecv = calloc(1, ai->ai_addrlen); pr->salast = calloc(1, ai->ai_addrlen); pr->sabind = calloc(1, ai->ai_addrlen); pr->salen = ai->ai_addrlen; traceloop(); exit(0); }
Sock * Sock_bind(char const *host, char const *port, Sock *sock, sock_type socktype, void * octx) { Sock *s = NULL; int sockfd = -1; struct sockaddr *sa_p; socklen_t sa_len; char local_host[128]; int local_port; #if ENABLE_SSL if ((octx)) { if(socktype != TCP) { net_log(NET_LOG_ERR, "SSL can't work on this protocol.\n"); return NULL; } } #endif if(sock) { sockfd = sock->fd; } if (sock_bind(host, port, &sockfd, socktype)) { net_log(NET_LOG_ERR, "Error in low level sock_bind().\n"); return NULL; } if (!(s = calloc(1, sizeof(Sock)))) { net_log(NET_LOG_FATAL, "Unable to allocate a Sock struct in Sock_bind().\n"); sock_close(sockfd); return NULL; } s->fd = sockfd; s->socktype = socktype; s->flags = 0; sa_p = (struct sockaddr *)&(s->local_stg); sa_len = sizeof(struct sockaddr_storage); if(getsockname(s->fd, sa_p, &sa_len) < 0) { Sock_close(s); return NULL; } if(!sock_ntop_host(sa_p, local_host, sizeof(local_host))) memset(local_host, 0, sizeof(local_host)); if (!(s->local_host = strdup(local_host))) { net_log(NET_LOG_FATAL, "Unable to allocate local host in Sock_bind().\n"); Sock_close(s); return NULL; } local_port = sock_get_port(sa_p); if(local_port < 0) { net_log(NET_LOG_ERR, "Unable to get local port in Sock_bind().\n"); Sock_close(s); return NULL; } else s->local_port = ntohs(local_port); net_log(NET_LOG_DEBUG, "Socket bound with addr=\"%s\" and port=\"%u\".\n", s->local_host, s->local_port); if(is_multicast_address(sa_p, s->local_stg.ss_family)) { if(mcast_join(s->fd, sa_p)) { Sock_close(s); return NULL; } s->flags |= IS_MULTICAST; } return s; }