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

📄 xti.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    break;  }  /*   *	Update XTI state tables   *     * Update internal tables + kernel before blowing   * away endpoint   *   */    table(fd).event = XTI_CLOSED;  if (update_XTI_state(fd, -1, old_state) == -1) {    t_errno = TOUTSTATE;    return(-1);  }    table(fd).active_flag = -1; /* no longer valid */  table(fd).sequence = 0;   table(fd).qlen = 0;    if (close(fd) < 0) {    map_err_to_XTI(errno,&t_errno);          return (-1);  }    return (0);}/* *	T_CONNECT - establish a connection with another transport endpoint */int t_connect (fd, sndcall, rcvcall)     int fd;     struct t_call *sndcall;     struct t_call *rcvcall;{#ifdef XTINSP  struct accessdata_dn nsp_accessdata;#endif  int status;  int optl;  int old_state;  struct xti_evtinfo evtinfo;  int buffer_overflow = 0;    if (!(check_xtifd(fd))) {    t_errno = TBADF;    return(-1);  }  if (d_table.dcb == T_NULL) { /* must make sure we have dynamic table built */    t_errno = TBADF;    return(-1);  }  old_state = table(fd).state;    if ( (check_XTI_state(fd, XTI_CONNECT1) == -1) &&      (check_XTI_state(fd, XTI_CONNECT2) == -1) ) {    t_errno = TOUTSTATE;    return(-1);  }    if (table(fd).info.servtype != T_COTS &&       table(fd).info.servtype != T_COTS_ORD) {    t_errno = TNOTSUPPORT;    return(-1);  }  /*   * check for any incoming T_DISCONNECT's or T_LISTEN's   */    status = xti_peek(fd, &evtinfo);    if (status == -1) return(-1);  if (evtinfo.evtarray[ffs(T_LISTEN)] ||      evtinfo.evtarray[ffs(T_DISCONNECT)]) {    t_errno = TLOOK;    return(-1);  }  /* check address */  if (table(fd).info.addr != -1 && table(fd).info.addr != -2)    if (sndcall->addr.len > table(fd).info.addr) {      t_errno = TBADADDR;      return(-1);    }  /*   * Send USER DATA   */  if (sndcall->udata.len > 0) {    if (table(fd).info.connect == T_NOTSUPPORTED) {      t_errno = TBADDATA;      return(-1);    }    if (sndcall->udata.len > table(fd).info.connect) {      t_errno = TBADDATA;      return(-1);    }    switch (table(fd).family) {#ifdef XTIOSI    case AF_OSI:      {	char *usrdat;	int usrdatlen = table(fd).info.connect;	usrdat = (char *)malloc(usrdatlen);	if (usrdat == NULL) {	  t_errno = TSYSERR;	  errno = ENOBUFS;	  return(-1);	}	bzero(usrdat, usrdatlen);	bcopy(sndcall->udata.buf, usrdat, sndcall->udata.len);	status = setsockopt(fd, OSIPROTO_COTS, TOPT_OPTCONDATA, 			    usrdat, sndcall->udata.len);	free(usrdat);	if (status == -1) {	  map_err_to_XTI(errno,&t_errno);	  return(-1);	}	break;      }#endif    case AF_INET:      break;#ifdef XTINSP    case AF_DECnet:      status = setsockopt(fd, DNPROTO_NSP, DSO_CONDATA, 			  sndcall->udata.buf,			  sndcall->udata.len );            if (status == -1) {	map_err_to_XTI(errno,&t_errno);	return(-1);      }      break;#endif    }; /* end switch */  }  /* end user data */  /*   * Send option data (if any)    */  if (sndcall->opt.len > 0) {    if (table(fd).info.options == T_NOTSUPPORTED) {      t_errno = TNOTSUPPORT;      return(-1);    }    if (sndcall->opt.len > table(fd).info.options) {      t_errno = TBADOPT;      return(-1);    }    switch(table(fd).family) {#ifdef XTIOSI    case AF_OSI:      {	int tmp_len;	tmp_len = sndcall->opt.len;	status = setsockopt(fd, OSIPROTO_COTS, TOPT_XTICONOPTS,			    sndcall->opt.buf,			    tmp_len );	if (status == -1) {	  map_err_to_XTI(errno,&t_errno);	  if (t_errno == TNOTSUPPORT) t_errno = TBADOPT; /* re-map */	  return(-1);	}      }      break;#endif    case AF_INET:      if (table(fd).xti_proto == IPPROTO_TCP) {	int tmp_len;	tmp_len = sndcall->opt.len;	status = setsockopt(fd, IPPROTO_TCP, TCP_CONOPT,			    sndcall->opt.buf,			    tmp_len );#ifdef XTISECURE#define SECURE_OPT_SIZE_ALIGN 12	{	  char *tmp;	  char *tmp1;	  struct tcp_options tmp_tcpopt;	  short security;	  short compartment;	  short handling;	  long tcc;	  int tmp_stat;	  bcopy(sndcall->opt.buf, &tmp_tcpopt, 		sizeof(struct tcp_options));	  security = htons(tmp_tcpopt.secopt.security);	  compartment = htons(tmp_tcpopt.secopt.compartment);	  handling = htons(tmp_tcpopt.secopt.handling);	  tcc = htonl(tmp_tcpopt.secopt.tcc);	  	  if (!(security == T_UNUSED &&	      compartment == T_UNUSED &&	      handling == T_UNUSED &&	      tcc == T_UNUSED)) {	    tmp = (char *)malloc(SECURE_OPT_SIZE_ALIGN); 	    tmp1 = tmp;	    *tmp++ = 130; /* SECURITY */	    *tmp++ = SECURE_OPT_SIZE_ALIGN -1;	  	    bcopy(&security, tmp, sizeof(short));	    tmp += sizeof(short);	    bcopy(&compartment, tmp, sizeof(short));	    tmp += sizeof(short);	    bcopy(&handling, tmp, sizeof(short));	    tmp += sizeof(short);	    bcopy(&tcc, tmp, sizeof(long));	    tmp += sizeof(long) - 1;	    *tmp = 0;	    tmp_stat = setsockopt(fd, IPPROTO_IP, IP_OPTIONS, 				  tmp1, SECURE_OPT_SIZE_ALIGN);      	    if (tmp_stat == -1) {	      map_err_to_XTI(errno,&t_errno);	      return(-1);	    }	    /* 	   * force success for CONOPT because security options 	   * will cause error 	   */	  status = 0; 	  }	}#endif	if (status == -1) {	  map_err_to_XTI(errno,&t_errno);	  if (t_errno == TNOTSUPPORT) t_errno = TBADOPT; /* re-map */	  return(-1);	}      }      break;#ifdef XTINSP    case AF_DECnet:            bcopy(sndcall->opt.buf,(char *) &nsp_accessdata, sndcall->opt.len);      optl = sizeof(struct accessdata_dn);      status = setsockopt(fd, DNPROTO_NSP, DSO_CONACCESS, 			  (char *) &nsp_accessdata, 			  optl );            if (status == -1) {	map_err_to_XTI(errno,&t_errno);	return(-1);      }      break;#endif    };  } /*  * Initialize rcvcall if specified  */  if (rcvcall) {    rcvcall->addr.len = 0;    rcvcall->opt.len = 0;    rcvcall->udata.len = 0;  }  if ((connect(fd, (struct sockaddr *) sndcall->addr.buf,	       (int) sndcall->addr.len)) == -1) {    map_err_to_XTI(errno,&t_errno);        if (t_errno == TNODATA) {      if (rcvcall) {	rcvcall->addr.len = sndcall->addr.len;		rcvcall->addr.buf = sndcall->addr.buf;	rcvcall->opt.buf = 0;	rcvcall->udata.buf = 0;      }      /*       *	Update XTI state tables       *       */            table(fd).event = XTI_CONNECT2;      if (update_XTI_state(fd, -1, old_state) == -1) {	t_errno = TOUTSTATE;	return(-1);      }      return (-1);    }          /*     * Check for user (disconnect) data     */        if (rcvcall)      if (rcvcall->udata.maxlen > 0) {	if (table(fd).info.discon == T_NOTSUPPORTED) {	  t_errno = TNOTSUPPORT;	  return(-1);	}		if (rcvcall)	  switch (table(fd).family) {#ifdef XTIOSI	  case AF_OSI:	    optl = rcvcall->udata.maxlen;	    status = getsockopt(fd, OSIPROTO_COTS, TOPT_OPTDISDATA, 				(char *) rcvcall->udata.buf, 				&optl );	    	    if (status == -1) {	      map_err_to_XTI(errno,&t_errno);	      return(-1);	    }	    	    rcvcall->udata.len = optl;	    break;#endif	    	  case AF_INET:	    break;#ifdef XTINSP	  case AF_DECnet:		    optl = rcvcall->udata.maxlen;	    status = getsockopt(fd, DNPROTO_NSP, DSO_DISDATA, 				rcvcall->udata.buf, 				&optl );	    	    if (status == -1) {	      map_err_to_XTI(errno,&t_errno);	      return(-1);	    }	    	    rcvcall->udata.len = optl;	    break;#endif		  };      }    return (-1);  } /* end of connect error */  else {    if (rcvcall) {      if (rcvcall->addr.maxlen >= sndcall->addr.len) {        rcvcall->addr.len = sndcall->addr.len;        bcopy(sndcall->addr.buf, rcvcall->addr.buf,              rcvcall->addr.maxlen);      }	else {        buffer_overflow = 1;      }      if (rcvcall->udata.maxlen > 0) {	switch(table(fd).family) {#ifdef XTIOSI	case AF_OSI:	  {            char *usrdat;	    int usrdatlen = table(fd).info.connect;	    usrdat = (char *)malloc(usrdatlen);	    if (usrdat == NULL) {	      t_errno = TSYSERR;	      errno = ENOBUFS;	      return(-1);	    }	    bzero(usrdat, usrdatlen);	    status = getsockopt(fd, OSIPROTO_COTS, TOPT_OPTCONDATA,				usrdat, &usrdatlen);	    if (status == -1) {	      free(usrdat);	      map_err_to_XTI(errno,&t_errno);	      return(-1);	    }	    if (rcvcall->udata.maxlen < usrdatlen) {	      buffer_overflow = 1;	    }	    if (!buffer_overflow) {              bcopy(usrdat, rcvcall->udata.buf, usrdatlen);	      rcvcall->udata.len = usrdatlen;            }	    free(usrdat);	    break;	  }#endif	case AF_INET:	  break;#ifdef XTINSP	case AF_DECnet:	    	  optl = rcvcall->udata.maxlen;	  status = getsockopt(fd, DNPROTO_NSP, DSO_CONDATA,			      rcvcall->udata.buf,			      &optl );	  if (status == -1) {	    map_err_to_XTI(errno,&t_errno);	    return(-1);	  }		  rcvcall->udata.len = optl;	  break;#endif	};      }    } /* if rcvcall */    if (rcvcall)      if (rcvcall->opt.maxlen > 0) {        if (rcvcall->opt.maxlen < table(fd).info.options) {          buffer_overflow = 1;        }      	if (!buffer_overflow) {          switch(table(fd).family) {	  case AF_INET:		    if (table(fd).xti_proto == IPPROTO_TCP) {	      int tmp_len;	    	      /* here we go, let's get it from the kernel */	  	      tmp_len = rcvcall->opt.maxlen;	      status = getsockopt(fd, IPPROTO_TCP, TCP_CONOPT,				  rcvcall->opt.buf,				  &tmp_len );	  	      rcvcall->opt.len = tmp_len;	    	      if (status == -1) {	        map_err_to_XTI(errno,&t_errno);	        return(-1);	      }	    }	  	    break;#ifdef XTIOSI	  case AF_OSI:	    {	      int tmp_len;	    	      tmp_len = rcvcall->opt.maxlen;	      status = getsockopt(fd, OSIPROTO_COTS, TOPT_XTICONOPTS,				  rcvcall->opt.buf,				  &tmp_len );	  	      rcvcall->opt.len = tmp_len;	    	      if (status == -1) {	        map_err_to_XTI(errno,&t_errno);	        return(-1);	      }	    }	    break;#endif	  #ifdef XTINSP	  case AF_DECnet:	    break;#endif	  };        }      }        /*     *	Update XTI state tables     *     */        table(fd).event = XTI_CONNECT1;        if (update_XTI_state(fd, -1, old_state) == -1) {      t_errno = TOUTSTATE;      return(-1);    }    if (buffer_overflow) {      t_errno = TBUFOVFLW;      return(-1);    }    return (0);  }}/* *	T_ERROR - produce error message (optional) */char *t_errlist[] = {  "Error 0",  "Incorrect addr. format",		/* TBADADDR	1  */	  "Incorrect option format",		/* TBADOPT	2  */	  "Incorrect permissions",		/* TACCES	3  */	  "Illegal transport fd",      		/* TBADF	4  */	  "Couldn't allocate addr",		/* TNOADDR	5  */	  "Out of state",	       		/* TOUTSTATE	6  */	  "Bad call sequence number",		/* TBADSEQ	7  */	  "System error",	       		/* TSYSERR	8  */	  "Event requires attention",		/* TLOOK	9  */	  "Illegal amount of data",		/* TBADDATA	10 */	  "Buffer not large enough",		/* TBUFOVFLW	11 */	  "Flow control",	       		/* TFLOW	12 */	  "No data",				/* TNODATA	13 */	  "Discon_ind not found on q",		/* TNODIS	14 */ 	  "Unitdata error not found",		/* TNOUDERR	15 */	  "Bad flags",				/* TBADFLAG	16 */	  "No ord rel found on q",		/* TNOREL	17 */	  "Primitive not supported",		/* TNOTSUPPORT	18 */	  "State is in process of changing",	/* TSTATECHNG	19 */	  "Unsupported struc-type requested",	/* TNOSTRUCTYPE	20 */	  "Invalid transport provider name",	/* TBADNAME	21 */	  "Qlen is zero",	                /* TBADQLEN	22 */	  "Address in use",	                /* TADDRBUSY	23 */	  };	int t_nerr = (sizeof t_errlist / sizeof t_errlist[0]);int t_errno;   /* definition for t_errno */intt_error (errmsg)char *errmsg;{  extern int t_errno;  extern char *t_errlist[];  extern int t_nerr;  if (t_errno <0 || t_errno > t_nerr) {	t_errno=TSYSERR;	errno=EINVAL;	return(-1); /* protect ourselves */  }  write(2,errmsg,strlen(errmsg));  write(2,":\t",strlen(":\t"));  write(2,t_errlist[t_errno],strlen(t_errlist[t_errno]));  write(2,"\n",sizeof("\n"));  if (t_errno == TSYSERR) {    perror("");  }  return(0);}/* *	T_FREE - free a library structure (optional) */int t_free (ptr, struct_type)char *ptr;int struct_type;{    if (ptr == T_NULL) {    t_errno = TSYSERR;    errno = EINVAL;    return(-1);  }  switch(struct_type) {      case T_BIND_STR:    if (((struct t_bind *)ptr)->addr.buf)       free(((struct t_bind *)ptr)->addr.buf);    free(ptr);    break;  case T_OPTMGMT_STR:    if (((struct t_optmgmt *)ptr)->opt.buf)       free(((struct t_optmgmt *)ptr)->opt.buf);    free(ptr);    break;      case T_CALL_STR:    if (((struct t_call *)ptr)->addr.buf)      free(((struct t_call *)ptr)->addr.buf);

⌨️ 快捷键说明

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