⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
字号:
/*   * Copyright (c) 2005,2006 Christophe Fillot. * E-mail: cf@utc.fr * * Network Utility functions. */#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <unistd.h>#include <time.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netdb.h>#include <fcntl.h>#include <errno.h>#include <assert.h>#include "utils.h"#include "net.h"/*  * IP mask table, which allows to find quickly a network mask  * with a prefix length. */n_ip_addr_t ip_masks[N_IP_ADDR_BITS+1] = {   0x0,    0x80000000, 0xC0000000, 0xE0000000, 0xF0000000,   0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000,   0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000,   0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000,   0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000,   0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00,   0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0,   0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF};/*  * IPv6 mask table, which allows to find quickly a network mask  * with a prefix length. Note this is a particularly ugly way * to do this, since we use statically 2 Kb. */n_ipv6_addr_t ipv6_masks[N_IPV6_ADDR_BITS+1];/* Initialize IPv6 masks */void ipv6_init_masks(void){   int i,index;   /* Set all bits to 1 */   memset(ipv6_masks,0xff,sizeof(ipv6_masks));   for(i=0;i<N_IPV6_ADDR_BITS;i++)    {      index = i >> 3;  /* Compute byte index (divide by 8) */      /* rotate byte */      ipv6_masks[i].ip6.u6_addr8[index++] <<= (8 - (i & 7));      /* clear following bytes */      while(index<N_IPV6_ADDR_LEN)         ipv6_masks[i].ip6.u6_addr8[index++] = 0;   }}/* Convert an IPv4 address into a string */char *n_ip_ntoa(char *buffer,n_ip_addr_t ip_addr){   u_char *p = (u_char *)&ip_addr;   sprintf(buffer,"%u.%u.%u.%u",p[0],p[1],p[2],p[3]);   return(buffer);}#if HAS_RFC2553/* Convert in IPv6 address into a string */char *n_ipv6_ntoa(char *buffer,n_ipv6_addr_t *ipv6_addr){   return((char *)inet_ntop(AF_INET6,ipv6_addr,buffer,INET6_ADDRSTRLEN));}#endif/* Convert a string containing an IP address in binary */int n_ip_aton(n_ip_addr_t *ip_addr,char *ip_str){   struct in_addr addr;   if (inet_aton(ip_str,&addr) == 0)      return(-1);   *ip_addr = ntohl(addr.s_addr);   return(0);}#if HAS_RFC2553/* Convert an IPv6 address from string into binary */int n_ipv6_aton(n_ipv6_addr_t *ipv6_addr,char *ip_str){   return(inet_pton(AF_INET6,ip_str,ipv6_addr));}#endif/* Parse an IPv4 CIDR prefix */int ip_parse_cidr(char *token,n_ip_addr_t *net_addr,n_ip_addr_t *net_mask){   char *sl,*tmp,*err;   u_long mask;   /* Find separator */   if ((sl = strchr(token,'/')) == NULL)      return(-1);   /* Get mask */   mask = strtoul(sl+1,&err,0);   if (*err != 0)      return(-1);   /* Ensure that mask has a correct value */   if (mask > N_IP_ADDR_BITS)      return(-1);   if ((tmp = strdup(token)) == NULL)      return(-1);       sl = strchr(tmp,'/');   *sl = 0;   /* Parse IP Address */   if (n_ip_aton(net_addr,tmp) == -1) {      free(tmp);      return(-1);   }   /* Set netmask */   *net_mask = ip_masks[mask];   free(tmp);   return(0);}#if HAS_RFC2553/* Parse an IPv6 CIDR prefix */int ipv6_parse_cidr(char *token,n_ipv6_addr_t *net_addr,u_int *net_mask){   char *sl,*tmp,*err;   u_long mask;   /* Find separator */   if ((sl = strchr(token,'/')) == NULL)      return(-1);   /* Get mask */   mask = strtoul(sl+1,&err,0);   if (*err != 0)      return(-1);   /* Ensure that mask has a correct value */   if (mask > N_IPV6_ADDR_BITS)      return(-1);   if ((tmp = strdup(token)) == NULL)      return(-1);       sl = strchr(tmp,'/');   *sl = 0;   /* Parse IP Address */   if (n_ipv6_aton(net_addr,tmp) <= 0) {      free(tmp);      return(-1);   }   /* Set netmask */   *net_mask = (u_int)mask;   free(tmp);   return(0);}#endif/* Parse a MAC address */int parse_mac_addr(n_eth_addr_t *addr,char *str){   u_int v[N_ETH_ALEN];   int i,res;   /* First try, standard format (00:01:02:03:04:05) */   res = sscanf(str,"%x:%x:%x:%x:%x:%x",&v[0],&v[1],&v[2],&v[3],&v[4],&v[5]);   if (res == 6) {      for(i=0;i<N_ETH_ALEN;i++)         addr->eth_addr_byte[i] = v[i];      return(0);   }   /* Second try, Cisco format (0001.0002.0003) */   res = sscanf(str,"%x.%x.%x",&v[0],&v[1],&v[2]);   if (res == 3) {      addr->eth_addr_byte[0] = (v[0] >> 8) & 0xFF;      addr->eth_addr_byte[1] = v[0] & 0xFF;      addr->eth_addr_byte[2] = (v[1] >> 8) & 0xFF;      addr->eth_addr_byte[3] = v[1] & 0xFF;      addr->eth_addr_byte[4] = (v[2] >> 8) & 0xFF;      addr->eth_addr_byte[5] = v[2] & 0xFF;   }   return(-1);}/* Convert an Ethernet address into a string */char *n_eth_ntoa(char *buffer,n_eth_addr_t *addr,int format){   char *str_format;   if (format == 0) {      str_format = "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x";   } else {      str_format = "%2.2x%2.2x.%2.2x%2.2x.%2.2x%2.2x";   }   sprintf(buffer,str_format,           addr->eth_addr_byte[0],addr->eth_addr_byte[1],           addr->eth_addr_byte[2],addr->eth_addr_byte[3],           addr->eth_addr_byte[4],addr->eth_addr_byte[5]);   return(buffer);}#if HAS_RFC2553/* Create a new socket to connect to specified host */int udp_connect(int local_port,char *remote_host,int remote_port){   struct addrinfo hints,*res,*res0;   struct sockaddr_storage st;   int error, sck = -1;   char port_str[20];   memset(&hints,0,sizeof(hints));   hints.ai_family = PF_UNSPEC;   hints.ai_socktype = SOCK_DGRAM;   snprintf(port_str,sizeof(port_str),"%d",remote_port);   if ((error = getaddrinfo(remote_host,port_str,&hints,&res0)) != 0) {      fprintf(stderr,"%s\n",gai_strerror(error));      return(-1);   }   for(res=res0;res;res=res->ai_next)   {      /* We want only IPv4 or IPv6 */      if ((res->ai_family != PF_INET) && (res->ai_family != PF_INET6))         continue;      /* create new socket */      if ((sck = socket(res->ai_family,SOCK_DGRAM,res->ai_protocol)) < 0) {         perror("udp_connect: socket");         continue;      }      /* bind to the local port */      memset(&st,0,sizeof(st));            switch(res->ai_family) {         case PF_INET: {            struct sockaddr_in *sin = (struct sockaddr_in *)&st;            sin->sin_family = PF_INET;            sin->sin_port = htons(local_port);            break;         }         case PF_INET6: {            struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&st;#ifdef SIN6_LEN            sin6->sin6_len = res->ai_addrlen;#endif            sin6->sin6_family = PF_INET6;            sin6->sin6_port = htons(local_port);            break;         }         default:            /* shouldn't happen */            close(sck);            sck = -1;            continue;      }      /* try to connect to remote host */      if (!bind(sck,(struct sockaddr *)&st,res->ai_addrlen) &&          !connect(sck,res->ai_addr,res->ai_addrlen))         break;      close(sck);      sck = -1;   }   freeaddrinfo(res0);   return(sck);}#else/*  * Create a new socket to connect to specified host. * Version for old systems that do not support RFC 2553 (getaddrinfo()) * * See http://www.faqs.org/rfcs/rfc2553.html for more info. */int udp_connect(int local_port,char *remote_host,int remote_port){    struct sockaddr_in sin;   struct hostent *hp;   int sck;   if (!(hp = gethostbyname(remote_host))) {      fprintf(stderr,"udp_connect: unable to resolve '%s'\n",remote_host);      return(-1);   }   if ((sck = socket(AF_INET,SOCK_DGRAM,0)) < 0) {      perror("udp_connect: socket");      return(-1);   }   /* bind local port */   memset(&sin,0,sizeof(sin));   sin.sin_family = PF_INET;   sin.sin_port = htons(local_port);      if (bind(sck,(struct sockaddr *)&sin,sizeof(sin)) < 0) {      perror("udp_connect: bind");      close(sck);   }   /* try to connect to remote host */   memset(&sin,0,sizeof(sin));   memcpy(&sin.sin_addr,hp->h_addr_list[0],sizeof(struct in_addr));   sin.sin_family = PF_INET;   sin.sin_port = htons(remote_port);   if (connect(sck,(struct sockaddr *)&sin,sizeof(sin)) < 0) {      perror("udp_connect: connect");      close(sck);   }   return(sck);}#endif /* HAS_RFC2553 */#if HAS_RFC2553/* Listen on the specified port */int ip_listen(int port,int sock_type,int max_fd,int fd_array[]){   struct addrinfo hints,*res,*res0;   char port_str[20];   int nsock,error,i;   int reuse = 1;      for(i=0;i<max_fd;i++)      fd_array[i] = -1;   memset(&hints,0,sizeof(hints));   hints.ai_family = PF_UNSPEC;   hints.ai_socktype = sock_type;   hints.ai_flags = AI_PASSIVE;   snprintf(port_str,sizeof(port_str),"%d",port);   if ((error = getaddrinfo(NULL,port_str,&hints,&res0)) != 0) {      fprintf(stderr,"ip_listen: %s", gai_strerror(error));      return(-1);   }   nsock = 0;   for(res=res0;(res && (nsock < max_fd));res=res->ai_next)   {      if ((res->ai_family != PF_INET) && (res->ai_family != PF_INET6))         continue;      fd_array[nsock] = socket(res->ai_family,res->ai_socktype,                               res->ai_protocol);      if (fd_array[nsock] < 0)         continue;            setsockopt(fd_array[nsock],SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));      if ((bind(fd_array[nsock],res->ai_addr,res->ai_addrlen) < 0) ||          (listen(fd_array[nsock],5) < 0))      {         close(fd_array[nsock]);         fd_array[nsock] = -1;         continue;      }      nsock++;   }   freeaddrinfo(res0);   return(nsock);}#else/* Listen on the specified port */int ip_listen(int port,int sock_type,int max_fd,int fd_array[]){   struct sockaddr_in sin;   int i,sck,reuse=1;   for(i=0;i<max_fd;i++)      fd_array[i] = -1;   if ((sck = socket(AF_INET,sock_type,0)) < 0) {      perror("ip_listen: socket");      return(-1);   }   /* bind local port */   memset(&sin,0,sizeof(sin));   sin.sin_family = PF_INET;   sin.sin_port   = htons(port);   setsockopt(fd_array[0],SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));   if (bind(sck,(struct sockaddr *)&sin,sizeof(sin)) < 0) {      perror("ip_listen: bind");      goto error;   }   if (listen(sck,5) < 0) {      perror("ip_listen: listen");      goto error;   }   fd_array[0] = sck;   return(1); error:   close(sck);   return(-1);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -