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

📄 af_ax25.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 4 页
字号:
		return -ENODEV;	if (ax25_ctl.digi_count > AX25_MAX_DIGIS)		return -EINVAL;	digi.ndigi = ax25_ctl.digi_count;	for (k = 0; k < digi.ndigi; k++)		digi.calls[k] = ax25_ctl.digi_addr[k];	if ((ax25 = ax25_find_cb(&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev)) == NULL)		return -ENOTCONN;	switch (ax25_ctl.cmd) {		case AX25_KILL:			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);#ifdef CONFIG_AX25_DAMA_SLAVE			if (ax25_dev->dama.slave && ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_DAMA_SLAVE)				ax25_dama_off(ax25);#endif			ax25_disconnect(ax25, ENETRESET);			break;	  	case AX25_WINDOW:	  		if (ax25->modulus == AX25_MODULUS) {	  			if (ax25_ctl.arg < 1 || ax25_ctl.arg > 7)	  				return -EINVAL;	  		} else {	  			if (ax25_ctl.arg < 1 || ax25_ctl.arg > 63)	  				return -EINVAL;	  		}	  		ax25->window = ax25_ctl.arg;	  		break;	  	case AX25_T1:  			if (ax25_ctl.arg < 1)  				return -EINVAL;  			ax25->rtt = (ax25_ctl.arg * HZ) / 2;  			ax25->t1  = ax25_ctl.arg * HZ;  			break;	  	case AX25_T2:	  		if (ax25_ctl.arg < 1)	  			return -EINVAL;	  		ax25->t2 = ax25_ctl.arg * HZ;	  		break;	  	case AX25_N2:	  		if (ax25_ctl.arg < 1 || ax25_ctl.arg > 31)	  			return -EINVAL;	  		ax25->n2count = 0;	  		ax25->n2 = ax25_ctl.arg;	  		break;	  	case AX25_T3:	  		if (ax25_ctl.arg < 0)	  			return -EINVAL;	  		ax25->t3 = ax25_ctl.arg * HZ;	  		break;	  	case AX25_IDLE:	  		if (ax25_ctl.arg < 0)	  			return -EINVAL;	  		ax25->idle = ax25_ctl.arg * 60 * HZ;	  		break;	  	case AX25_PACLEN:	  		if (ax25_ctl.arg < 16 || ax25_ctl.arg > 65535)	  			return -EINVAL;	  		ax25->paclen = ax25_ctl.arg;	  		break;	  	default:	  		return -EINVAL;	  }	  return 0;}/* *	Fill in a created AX.25 created control block with the default *	values for a particular device. */void ax25_fillin_cb(ax25_cb *ax25, ax25_dev *ax25_dev){	ax25->ax25_dev = ax25_dev;	if (ax25->ax25_dev != NULL) {		ax25->rtt     = ax25_dev->values[AX25_VALUES_T1] / 2;		ax25->t1      = ax25_dev->values[AX25_VALUES_T1];		ax25->t2      = ax25_dev->values[AX25_VALUES_T2];		ax25->t3      = ax25_dev->values[AX25_VALUES_T3];		ax25->n2      = ax25_dev->values[AX25_VALUES_N2];		ax25->paclen  = ax25_dev->values[AX25_VALUES_PACLEN];		ax25->idle    = ax25_dev->values[AX25_VALUES_IDLE];		ax25->backoff = ax25_dev->values[AX25_VALUES_BACKOFF];		if (ax25_dev->values[AX25_VALUES_AXDEFMODE]) {			ax25->modulus = AX25_EMODULUS;			ax25->window  = ax25_dev->values[AX25_VALUES_EWINDOW];		} else {			ax25->modulus = AX25_MODULUS;			ax25->window  = ax25_dev->values[AX25_VALUES_WINDOW];		}	} else {		ax25->rtt     = AX25_DEF_T1 / 2;		ax25->t1      = AX25_DEF_T1;		ax25->t2      = AX25_DEF_T2;		ax25->t3      = AX25_DEF_T3;		ax25->n2      = AX25_DEF_N2;		ax25->paclen  = AX25_DEF_PACLEN;		ax25->idle    = AX25_DEF_IDLE;		ax25->backoff = AX25_DEF_BACKOFF;		if (AX25_DEF_AXDEFMODE) {			ax25->modulus = AX25_EMODULUS;			ax25->window  = AX25_DEF_EWINDOW;		} else {			ax25->modulus = AX25_MODULUS;			ax25->window  = AX25_DEF_WINDOW;		}	}}/* * Create an empty AX.25 control block. */ax25_cb *ax25_create_cb(void){	ax25_cb *ax25;	if ((ax25 = kmalloc(sizeof(*ax25), GFP_ATOMIC)) == NULL)		return NULL;	MOD_INC_USE_COUNT;	memset(ax25, 0x00, sizeof(*ax25));	skb_queue_head_init(&ax25->write_queue);	skb_queue_head_init(&ax25->frag_queue);	skb_queue_head_init(&ax25->ack_queue);	skb_queue_head_init(&ax25->reseq_queue);	init_timer(&ax25->timer);	init_timer(&ax25->t1timer);	init_timer(&ax25->t2timer);	init_timer(&ax25->t3timer);	init_timer(&ax25->idletimer);	ax25_fillin_cb(ax25, NULL);	ax25->state = AX25_STATE_0;	return ax25;}/* *	Handling for system calls applied via the various interfaces to an *	AX25 socket object */static int ax25_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen){	struct sock *sk = sock->sk;	struct net_device *dev;	char devname[IFNAMSIZ];	int opt;	if (level != SOL_AX25)		return -ENOPROTOOPT;	if (optlen < sizeof(int))		return -EINVAL;	if (get_user(opt, (int *)optval))		return -EFAULT;	switch (optname) {		case AX25_WINDOW:			if (sk->protinfo.ax25->modulus == AX25_MODULUS) {				if (opt < 1 || opt > 7)					return -EINVAL;			} else {				if (opt < 1 || opt > 63)					return -EINVAL;			}			sk->protinfo.ax25->window = opt;			return 0;		case AX25_T1:			if (opt < 1)				return -EINVAL;			sk->protinfo.ax25->rtt = (opt * HZ) / 2;			sk->protinfo.ax25->t1  = opt * HZ;			return 0;		case AX25_T2:			if (opt < 1)				return -EINVAL;			sk->protinfo.ax25->t2 = opt * HZ;			return 0;		case AX25_N2:			if (opt < 1 || opt > 31)				return -EINVAL;			sk->protinfo.ax25->n2 = opt;			return 0;		case AX25_T3:			if (opt < 1)				return -EINVAL;			sk->protinfo.ax25->t3 = opt * HZ;			return 0;		case AX25_IDLE:			if (opt < 0)				return -EINVAL;			sk->protinfo.ax25->idle = opt * 60 * HZ;			return 0;		case AX25_BACKOFF:			if (opt < 0 || opt > 2)				return -EINVAL;			sk->protinfo.ax25->backoff = opt;			return 0;		case AX25_EXTSEQ:			sk->protinfo.ax25->modulus = opt ? AX25_EMODULUS : AX25_MODULUS;			return 0;		case AX25_PIDINCL:			sk->protinfo.ax25->pidincl = opt ? 1 : 0;			return 0;		case AX25_IAMDIGI:			sk->protinfo.ax25->iamdigi = opt ? 1 : 0;			return 0;		case AX25_PACLEN:			if (opt < 16 || opt > 65535)				return -EINVAL;			sk->protinfo.ax25->paclen = opt;			return 0;		case SO_BINDTODEVICE:			if (optlen > IFNAMSIZ) optlen=IFNAMSIZ;			if (copy_from_user(devname, optval, optlen))				return -EFAULT;			dev = dev_get_by_name(devname);			if (dev == NULL) return -ENODEV;			if (sk->type == SOCK_SEQPACKET && 			   (sock->state != SS_UNCONNECTED || sk->state == TCP_LISTEN))				return -EADDRNOTAVAIL;					sk->protinfo.ax25->ax25_dev = ax25_dev_ax25dev(dev);			ax25_fillin_cb(sk->protinfo.ax25, sk->protinfo.ax25->ax25_dev);			return 0;		default:			return -ENOPROTOOPT;	}}static int ax25_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen){	struct sock *sk = sock->sk;	struct ax25_dev *ax25_dev;	char devname[IFNAMSIZ];	void *valptr;	int val = 0;	int maxlen, length;	if (level != SOL_AX25)		return -ENOPROTOOPT;	if (get_user(maxlen, optlen))		return -EFAULT;			if (maxlen < 1)		return -EFAULT;	valptr = (void *) &val;	length = min_t(unsigned int, maxlen, sizeof(int));	switch (optname) {		case AX25_WINDOW:			val = sk->protinfo.ax25->window;			break;		case AX25_T1:			val = sk->protinfo.ax25->t1 / HZ;			break;		case AX25_T2:			val = sk->protinfo.ax25->t2 / HZ;			break;		case AX25_N2:			val = sk->protinfo.ax25->n2;			break;		case AX25_T3:			val = sk->protinfo.ax25->t3 / HZ;			break;		case AX25_IDLE:			val = sk->protinfo.ax25->idle / (60 * HZ);			break;		case AX25_BACKOFF:			val = sk->protinfo.ax25->backoff;			break;		case AX25_EXTSEQ:			val = (sk->protinfo.ax25->modulus == AX25_EMODULUS);			break;		case AX25_PIDINCL:			val = sk->protinfo.ax25->pidincl;			break;		case AX25_IAMDIGI:			val = sk->protinfo.ax25->iamdigi;			break;		case AX25_PACLEN:			val = sk->protinfo.ax25->paclen;			break;					case SO_BINDTODEVICE:			ax25_dev = sk->protinfo.ax25->ax25_dev;			if (ax25_dev != NULL && ax25_dev->dev != NULL) {				strncpy(devname, ax25_dev->dev->name, IFNAMSIZ);				length = min_t(unsigned int, strlen(ax25_dev->dev->name)+1, maxlen);				devname[length-1] = '\0';			} else {				*devname = '\0';				length = 1;			}			valptr = (void *) devname;			break;		default:			return -ENOPROTOOPT;	}	if (put_user(length, optlen))		return -EFAULT;	return copy_to_user(optval, valptr, length) ? -EFAULT : 0;}static int ax25_listen(struct socket *sock, int backlog){	struct sock *sk = sock->sk;	if (sk->type == SOCK_SEQPACKET && sk->state != TCP_LISTEN) {		sk->max_ack_backlog = backlog;		sk->state           = TCP_LISTEN;		return 0;	}	return -EOPNOTSUPP;}int ax25_create(struct socket *sock, int protocol){	struct sock *sk;	ax25_cb *ax25;	switch (sock->type) {		case SOCK_DGRAM:			if (protocol == 0 || protocol == PF_AX25)				protocol = AX25_P_TEXT;			break;		case SOCK_SEQPACKET:			switch (protocol) {				case 0:				case PF_AX25:	/* For CLX */					protocol = AX25_P_TEXT;					break;				case AX25_P_SEGMENT:#ifdef CONFIG_INET				case AX25_P_ARP:				case AX25_P_IP:#endif#ifdef CONFIG_NETROM				case AX25_P_NETROM:#endif#ifdef CONFIG_ROSE				case AX25_P_ROSE:#endif					return -ESOCKTNOSUPPORT;#ifdef CONFIG_NETROM_MODULE				case AX25_P_NETROM:					if (ax25_protocol_is_registered(AX25_P_NETROM))						return -ESOCKTNOSUPPORT;#endif#ifdef CONFIG_ROSE_MODULE				case AX25_P_ROSE:					if (ax25_protocol_is_registered(AX25_P_ROSE))						return -ESOCKTNOSUPPORT;#endif				default:					break;			}			break;		case SOCK_RAW:			break;		default:			return -ESOCKTNOSUPPORT;	}	if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, 1)) == NULL)		return -ENOMEM;	if ((ax25 = ax25_create_cb()) == NULL) {		sk_free(sk);		return -ENOMEM;	}	sock_init_data(sock, sk);	sk->destruct = ax25_free_sock;	sock->ops    = &ax25_proto_ops;	sk->protocol = protocol;	ax25->sk          = sk;	sk->protinfo.ax25 = ax25;	return 0;}struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev){	struct sock *sk;	ax25_cb *ax25;	if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, 1)) == NULL)		return NULL;	if ((ax25 = ax25_create_cb()) == NULL) {		sk_free(sk);		return NULL;	}	switch (osk->type) {		case SOCK_DGRAM:			break;		case SOCK_SEQPACKET:			break;		default:			sk_free(sk);			ax25_free_cb(ax25);			return NULL;	}	sock_init_data(NULL, sk);	sk->destruct = ax25_free_sock;	sk->type     = osk->type;	sk->socket   = osk->socket;	sk->priority = osk->priority;	sk->protocol = osk->protocol;	sk->rcvbuf   = osk->rcvbuf;	sk->sndbuf   = osk->sndbuf;	sk->debug    = osk->debug;	sk->state    = TCP_ESTABLISHED;

⌨️ 快捷键说明

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