int inet_srcrt_add(char *hostptr) { int len; struct addrinfo *ai; struct sockaddr_in *sin; if (ocnt > 9) { err_quit("too many source routes with: %s", hostptr); } ai = host_serv(hostptr, NULL, AF_INET, 0); sin = (struct sockaddr_in *) ai->ai_addr; memcpy(optr, &sin->sin_addr, sizeof(struct in_addr)); freeaddrinfo(ai); optr += sizeof(struct in_addr); ocnt++; len = 3 + (ocnt * sizeof(struct in_addr)); *lenptr = len; return(len + 1); // sizeo for setsockopt() }
void start_connect(struct file *fptr) { int fd, flags, n; struct addrinfo *ai; if ((ai = host_serv(fptr->f_host, SERV, 0, SOCK_STREAM)) < 0) { err_sys("host_serv error"); } if ((fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) { err_sys("socket error"); } fptr->f_fd = fd; printf("start_connect for %s, fd %d\n", fptr->f_name, fd); // set socket nonblocking if ((flags = fcntl(fd, F_GETFL, 0)) < 0) { err_sys("fcntl error"); } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { err_sys("fcntl error"); } // initiate nonblocking connect to the server if ((n = connect(fd, ai->ai_addr, ai->ai_addrlen)) < 0) { if (errno != EINPROGRESS) { err_sys("nonblocking connect error"); } fptr->f_flags = F_CONNECTING; FD_SET(fd, &rset); // select for reading and writing FD_SET(fd, &wset); if (fd > maxfd) { maxfd = fd; } } else if (n >= 0) { // connect is already done write_get_cmd(fptr); // write the GET command } }
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); }
int main(int argc, char **argv) { int n; struct addrinfo *ai; char *h; opterr = 0; /* don't want getopt() writing to stderr */ /* 只实现ping的一个参数选项-v供查询 */ /* 有关getopt函数的使用可以查阅相关资料 */ while( (n = getopt(argc, argv, "v")) != -1) { switch(n) { case 'v': verbose++; break; case '?': printf("unrecognize option: %c\n", n); exit(1); } } if(optind != argc-1) { perror("usage: ping [ -v ] <hostname>"); exit(1); } host = argv[optind]; pid = getpid() & 0xffff; /* ICMP ID field is 16 bits */ MySignal(SIGALRM, sig_alrm); MySignal(SIGINT, statistics); /* 将主机名和服务名映射到一个地址,并返回指向addrinfo的指针 */ ai = host_serv(host, NULL, 0, 0); /* 将网络字节序的地址转换为字符串格式地址,并返回该字符串的指针 */ h = Sock_ntop_host(ai->ai_addr, ai->ai_addrlen); /* 显示PING的主机名、地址与数据字节数 */ printf("PING %s (%s) %d bytes of data.\n", ai->ai_canonname ? ai->ai_canonname : h, h, datalen); /* initialize according to protocol */ if(ai->ai_family == AF_INET) { pr = &proto_v4;/* proto结构指针pr指向对应域的结构,这里是IPv4域的结构 */ #ifdef IPV6 }else if(ai->family == AF_INET6) { pr = &proc_v6; if(IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr))) { perror("connot ping IPv4-mapped IPv6 address"); exit(1); } #endif }else { printf("unknown address family %d", ai->ai_family); exit(1); } pr->sasend = ai->ai_addr;/* 发送地址赋值 */ pr->sarecv = (struct sockaddr *)Calloc(1, ai->ai_addrlen); pr->salen = ai->ai_addrlen;/* 地址的大小 */ /* 处理数据 */ readloop(); exit(0); }