📄 net_io.c
字号:
if (netio_record(nio) == -1) { netio_free(nio,NULL); return NULL; } return nio;}/* * ========================================================================= * TAP devices * ========================================================================= *//* Free a NetIO TAP descriptor */static void netio_tap_free(netio_tap_desc_t *ntd){ if (ntd->fd != -1) close(ntd->fd);}/* Open a TAP device */static int netio_tap_open(char *tap_devname){ #ifdef __linux__ struct ifreq ifr; int fd,err; if ((fd = open("/dev/net/tun",O_RDWR)) < 0) return(-1); memset(&ifr,0,sizeof(ifr)); /* Flags: IFF_TUN - TUN device (no Ethernet headers) * IFF_TAP - TAP device * * IFF_NO_PI - Do not provide packet information */ ifr.ifr_flags = IFF_TAP|IFF_NO_PI; if (*tap_devname) strncpy(ifr.ifr_name,tap_devname,IFNAMSIZ); if ((err = ioctl(fd,TUNSETIFF,(void *)&ifr)) < 0) { close(fd); return err; } strcpy(tap_devname,ifr.ifr_name); return(fd);#else int i,fd = -1; if (*tap_devname) { fd = open(tap_devname,O_RDWR); } else { for(i=0;i<16;i++) { snprintf(tap_devname,NETIO_DEV_MAXLEN,"/dev/tap%d",i); if ((fd = open(tap_devname,O_RDWR)) >= 0) break; } } return(fd);#endif }/* Allocate a new NetIO TAP descriptor */static int netio_tap_create(netio_tap_desc_t *ntd,char *tap_name){ if (strlen(tap_name) >= NETIO_DEV_MAXLEN) { fprintf(stderr,"netio_tap_create: bad TAP device string specified.\n"); return(-1); } memset(ntd,0,sizeof(*ntd)); strcpy(ntd->filename,tap_name); ntd->fd = netio_tap_open(ntd->filename); if (ntd->fd == -1) { fprintf(stderr,"netio_tap_create: unable to open TAP device %s (%s)\n", tap_name,strerror(errno)); return(-1); } return(0);}/* Write a packet to a TAP device */static ssize_t netio_tap_send(netio_tap_desc_t *ntd,void *pkt,size_t pkt_len){ return(write(ntd->fd,pkt,pkt_len));}/* Receive a packet through a TAP device */static ssize_t netio_tap_recv(netio_tap_desc_t *ntd,void *pkt,size_t max_len){ return(read(ntd->fd,pkt,max_len));}/* Save the NIO configuration */static void netio_tap_save_cfg(netio_desc_t *nio,FILE *fd){ netio_tap_desc_t *ntd = nio->dptr; fprintf(fd,"nio create_tap %s %s\n",nio->name,ntd->filename);}/* Create a new NetIO descriptor with TAP method */netio_desc_t *netio_desc_create_tap(char *nio_name,char *tap_name){ netio_tap_desc_t *ntd; netio_desc_t *nio; if (!(nio = netio_create(nio_name))) return NULL; ntd = &nio->u.ntd; if (netio_tap_create(ntd,tap_name) == -1) { netio_free(nio,NULL); return NULL; } nio->type = NETIO_TYPE_TAP; nio->send = (void *)netio_tap_send; nio->recv = (void *)netio_tap_recv; nio->save_cfg = netio_tap_save_cfg; nio->dptr = &nio->u.ntd; if (netio_record(nio) == -1) { netio_free(nio,NULL); return NULL; } return nio;}/* * ========================================================================= * TCP sockets * ========================================================================= *//* Free a NetIO TCP descriptor */static void netio_tcp_free(netio_inet_desc_t *nid){ if (nid->fd != -1) close(nid->fd);}/* * very simple protocol to send packets over tcp * 32 bits in network format - size of packet, then packet itself and so on. */static ssize_t netio_tcp_send(netio_inet_desc_t *nid,void *pkt,size_t pkt_len){ u_long l = htonl(pkt_len); if (write(nid->fd,&l,sizeof(l)) == -1) return(-1); return(write(nid->fd,pkt,pkt_len));}static ssize_t netio_tcp_recv(netio_inet_desc_t *nid,void *pkt,size_t max_len){ u_long l; if (read(nid->fd,&l,sizeof(l)) != sizeof(l)) return(-1); if (ntohl(l) > max_len) return(-1); return(read(nid->fd,pkt,ntohl(l)));}static int netio_tcp_cli_create(netio_inet_desc_t *nid,char *host,char *port){ struct sockaddr_in serv; struct servent *sp; struct hostent *hp; if ((nid->fd = socket(PF_INET,SOCK_STREAM,0)) < 0) { perror("netio_tcp_cli_create: socket"); return(-1); } memset(&serv,0,sizeof(serv)); serv.sin_family = AF_INET; if (atoi(port) == 0) { if (!(sp = getservbyname(port,"tcp"))) { fprintf(stderr,"netio_tcp_cli_create: port %s is neither " "number not service %s\n",port,strerror(errno)); close(nid->fd); return(-1); } serv.sin_port = sp->s_port; } else serv.sin_port = htons(atoi(port)); if (inet_addr(host) == INADDR_NONE) { if (!(hp = gethostbyname(host))) { fprintf(stderr,"netio_tcp_cli_create: no host %s\n",host); close(nid->fd); return(-1); } serv.sin_addr.s_addr = *hp->h_addr; } else serv.sin_addr.s_addr = inet_addr(host); if (connect(nid->fd,(struct sockaddr *)&serv,sizeof(serv)) < 0) { fprintf(stderr,"netio_tcp_cli_create: connect to %s:%s failed %s\n", host,port,strerror(errno)); close(nid->fd); return(-1); } return(0);}/* Create a new NetIO descriptor with TCP_CLI method */netio_desc_t *netio_desc_create_tcp_cli(char *nio_name,char *host,char *port){ netio_desc_t *nio; if (!(nio = netio_create(nio_name))) return NULL; if (netio_tcp_cli_create(&nio->u.nid,host,port) < 0) { netio_free(nio,NULL); return NULL; } nio->type = NETIO_TYPE_TCP_CLI; nio->send = (void *)netio_tcp_send; nio->recv = (void *)netio_tcp_recv; nio->dptr = &nio->u.nid; if (netio_record(nio) == -1) { netio_free(nio,NULL); return NULL; } return nio;}static int netio_tcp_ser_create(netio_inet_desc_t *nid,char *port){ struct sockaddr_in serv; struct servent *sp; int sock_fd; if ((sock_fd = socket(PF_INET,SOCK_STREAM,0)) < 0) { perror("netio_tcp_cli_create: socket\n"); return(-1); } memset(&serv,0,sizeof(serv)); serv.sin_family = AF_INET; serv.sin_addr.s_addr = htonl(INADDR_ANY); if (atoi(port) == 0) { if (!(sp = getservbyname(port,"tcp"))) { fprintf(stderr,"netio_tcp_ser_create: port %s is neither " "number not service %s\n",port,strerror(errno)); close(sock_fd); return(-1); } serv.sin_port = sp->s_port; } else serv.sin_port = htons(atoi(port)); if (bind(sock_fd,(struct sockaddr *)&serv,sizeof(serv)) < 0) { fprintf(stderr,"netio_tcp_ser_create: bind %s failed %s\n", port,strerror(errno)); close(sock_fd); return(-1); } if (listen(sock_fd,1) < 0) { fprintf(stderr,"netio_tcp_ser_create: listen %s failed %s\n", port,strerror(errno)); close(sock_fd); return(-1); } fprintf(stderr,"Waiting connection on port %s...\n",port); if ((nid->fd = accept(sock_fd,NULL,NULL)) < 0) { fprintf(stderr,"netio_tcp_ser_create: accept %s failed %s\n", port,strerror(errno)); close(sock_fd); return(-1); } fprintf(stderr,"Connected\n"); close(sock_fd); return(0);}/* Create a new NetIO descriptor with TCP_SER method */netio_desc_t *netio_desc_create_tcp_ser(char *nio_name,char *port){ netio_desc_t *nio; if (!(nio = netio_create(nio_name))) return NULL; if (netio_tcp_ser_create(&nio->u.nid,port) == -1) { netio_free(nio,NULL); return NULL; } nio->type = NETIO_TYPE_TCP_SER; nio->send = (void *)netio_tcp_send; nio->recv = (void *)netio_tcp_recv; nio->dptr = &nio->u.nid; if (netio_record(nio) == -1) { netio_free(nio,NULL); return NULL; } return nio;}/* * ========================================================================= * UDP sockets * ========================================================================= *//* Free a NetIO UDP descriptor */static void netio_udp_free(netio_inet_desc_t *nid){ if (nid->remote_host) { free(nid->remote_host); nid->remote_host = NULL; } if (nid->fd != -1) close(nid->fd);}/* Write a packet to an UDP socket */static ssize_t netio_udp_send(netio_inet_desc_t *nid,void *pkt,size_t pkt_len){ return(send(nid->fd,pkt,pkt_len,0));}/* Receive a packet from an UDP socket */static ssize_t netio_udp_recv(netio_inet_desc_t *nid,void *pkt,size_t max_len){ return(recvfrom(nid->fd,pkt,max_len,0,NULL,NULL));}/* Save the NIO configuration */static void netio_udp_save_cfg(netio_desc_t *nio,FILE *fd){ netio_inet_desc_t *nid = nio->dptr; fprintf(fd,"nio create_udp %s %d %s %d\n", nio->name,nid->local_port,nid->remote_host,nid->remote_port);}/* Create a new NetIO descriptor with UDP method */netio_desc_t *netio_desc_create_udp(char *nio_name,int local_port, char *remote_host,int remote_port){ netio_inet_desc_t *nid; netio_desc_t *nio; if (!(nio = netio_create(nio_name))) return NULL; nid = &nio->u.nid; nid->local_port = local_port; nid->remote_port = remote_port; if (!(nid->remote_host = strdup(remote_host))) { fprintf(stderr,"netio_desc_create_udp: insufficient memory\n"); goto error; } if ((nid->fd = udp_connect(local_port,remote_host,remote_port)) < 0) { fprintf(stderr,"netio_desc_create_udp: unable to connect to %s:%d\n", remote_host,remote_port); goto error; } nio->type = NETIO_TYPE_UDP; nio->send = (void *)netio_udp_send; nio->recv = (void *)netio_udp_recv; nio->save_cfg = netio_udp_save_cfg; nio->dptr = &nio->u.nid; if (netio_record(nio) == -1) goto error; return nio; error: netio_free(nio,NULL); return NULL;}/* * ========================================================================= * Linux RAW Ethernet driver * ========================================================================= */#ifdef LINUX_ETH/* Free a NetIO raw ethernet descriptor */static void netio_lnxeth_free(netio_lnxeth_desc_t *nled){ if (nled->fd != -1) close(nled->fd);}/* Write a packet to a raw Ethernet socket */static ssize_t netio_lnxeth_send(netio_lnxeth_desc_t *nled, void *pkt,size_t pkt_len){ return(lnx_eth_send(nled->fd,nled->dev_id,pkt,pkt_len));}/* Receive a packet from an raw Ethernet socket */static ssize_t netio_lnxeth_recv(netio_lnxeth_desc_t *nled, void *pkt,size_t max_len){ return(lnx_eth_recv(nled->fd,pkt,max_len));}/* Save the NIO configuration */static void netio_lnxeth_save_cfg(netio_desc_t *nio,FILE *fd){ netio_lnxeth_desc_t *nled = nio->dptr; fprintf(fd,"nio create_linux_eth %s %s\n",nio->name,nled->dev_name);}/* Create a new NetIO descriptor with raw Ethernet method */netio_desc_t *netio_desc_create_lnxeth(char *nio_name,char *dev_name){ netio_lnxeth_desc_t *nled; netio_desc_t *nio; if (!(nio = netio_create(nio_name))) return NULL; nled = &nio->u.nled; if (strlen(dev_name) >= NETIO_DEV_MAXLEN) { fprintf(stderr,"netio_desc_create_lnxeth: bad Ethernet device string " "specified.\n"); netio_free(nio,NULL); return NULL; } strcpy(nled->dev_name,dev_name); nled->fd = lnx_eth_init_socket(dev_name); nled->dev_id = lnx_eth_get_dev_index(dev_name); if (nled->fd < 0) { netio_free(nio,NULL); return NULL; } nio->type = NETIO_TYPE_LINUX_ETH; nio->send = (void *)netio_lnxeth_send; nio->recv = (void *)netio_lnxeth_recv; nio->save_cfg = netio_lnxeth_save_cfg; nio->dptr = &nio->u.nled; if (netio_record(nio) == -1) { netio_free(nio,NULL); return NULL; } return nio;}#endif /* LINUX_ETH *//* * ========================================================================= * Generic RAW Ethernet driver * ========================================================================= */#ifdef GEN_ETH/* Free a NetIO raw ethernet descriptor */static void netio_geneth_free(netio_geneth_desc_t *nged){ gen_eth_close(nged->pcap_dev);}/* Write a packet to an Ethernet device */static ssize_t netio_geneth_send(netio_geneth_desc_t *nged, void *pkt,size_t pkt_len){ return(gen_eth_send(nged->pcap_dev,pkt,pkt_len));}/* Receive a packet from an Ethernet device */static ssize_t netio_geneth_recv(netio_geneth_desc_t *nged, void *pkt,size_t max_len){ return(gen_eth_recv(nged->pcap_dev,pkt,max_len));}/* Save the NIO configuration */static void netio_geneth_save_cfg(netio_desc_t *nio,FILE *fd){ netio_geneth_desc_t *nged = nio->dptr; fprintf(fd,"nio create_gen_eth %s %s\n",nio->name,nged->dev_name);}/* Create a new NetIO descriptor with generic raw Ethernet method */netio_desc_t *netio_desc_create_geneth(char *nio_name,char *dev_name){ netio_geneth_desc_t *nged; netio_desc_t *nio; if (!(nio = netio_create(nio_name))) return NULL; nged = &nio->u.nged; if (strlen(dev_name) >= NETIO_DEV_MAXLEN) { fprintf(stderr,"netio_desc_create_geneth: bad Ethernet device string " "specified.\n"); netio_free(nio,NULL); return NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -