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

📄 irlan_common.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	irlan_ctrl_data_request(self, skb);}/* * Function irlan_set_multicast_filter (self, status) * *    Make IrLAN provider accept ethernet frames addressed to the multicast *    address. * */void irlan_set_multicast_filter(struct irlan_cb *self, int status){	struct sk_buff *skb;	__u8 *frame;	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +			IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +			IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "MULTICAST") +			/* We may waste one byte here...*/			IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "NONE"),			GFP_ATOMIC);	if (!skb)		return;	/* Reserve space for TTP, LMP, and LAP header */	skb_reserve(skb, self->client.max_header_size);	skb_put(skb, 2);	frame = skb->data;	frame[0] = CMD_FILTER_OPERATION;	frame[1] = 0x03;                 /* Three parameters */	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);	irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");	if (status)		irlan_insert_string_param(skb, "FILTER_MODE", "ALL");	else		irlan_insert_string_param(skb, "FILTER_MODE", "NONE");	irlan_ctrl_data_request(self, skb);}/* * Function irlan_get_unicast_addr (self) * *    Retrieves the unicast address from the IrLAN provider. This address *    will be inserted into the devices structure, so the ethernet layer *    can construct its packets. * */static void irlan_get_unicast_addr(struct irlan_cb *self){	struct sk_buff *skb;	__u8 *frame;	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +			IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +			IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +			IRLAN_STRING_PARAMETER_LEN("FILTER_OPERATION",						   "DYNAMIC"),			GFP_ATOMIC);	if (!skb)		return;	/* Reserve space for TTP, LMP, and LAP header */	skb_reserve(skb, self->client.max_header_size);	skb_put(skb, 2);	frame = skb->data;	frame[0] = CMD_FILTER_OPERATION;	frame[1] = 0x03;                 /* Three parameters */	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);	irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");	irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC");	irlan_ctrl_data_request(self, skb);}/* * Function irlan_get_media_char (self) * * * */void irlan_get_media_char(struct irlan_cb *self){	struct sk_buff *skb;	__u8 *frame;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +			IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3"),			GFP_ATOMIC);	if (!skb)		return;	/* Reserve space for TTP, LMP, and LAP header */	skb_reserve(skb, self->client.max_header_size);	skb_put(skb, 2);	frame = skb->data;	/* Build frame */	frame[0] = CMD_GET_MEDIA_CHAR;	frame[1] = 0x01; /* One parameter */	irlan_insert_string_param(skb, "MEDIA", "802.3");	irlan_ctrl_data_request(self, skb);}/* * Function insert_byte_param (skb, param, value) * *    Insert byte parameter into frame * */int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value){	return __irlan_insert_param(skb, param, IRLAN_BYTE, value, 0, NULL, 0);}int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value){	return __irlan_insert_param(skb, param, IRLAN_SHORT, 0, value, NULL, 0);}/* * Function insert_string (skb, param, value) * *    Insert string parameter into frame * */int irlan_insert_string_param(struct sk_buff *skb, char *param, char *string){	int string_len = strlen(string);	return __irlan_insert_param(skb, param, IRLAN_ARRAY, 0, 0, string,				    string_len);}/* * Function insert_array_param(skb, param, value, len_value) * *    Insert array parameter into frame * */int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *array,			     __u16 array_len){	return __irlan_insert_param(skb, name, IRLAN_ARRAY, 0, 0, array,				    array_len);}/* * Function insert_param (skb, param, value, byte) * *    Insert parameter at end of buffer, structure of a parameter is: * *    ----------------------------------------------------------------------- *    | Name Length[1] | Param Name[1..255] | Val Length[2] | Value[0..1016]| *    ----------------------------------------------------------------------- */static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,				__u8 value_byte, __u16 value_short,				__u8 *value_array, __u16 value_len){	__u8 *frame;	__u8 param_len;	__le16 tmp_le; /* Temporary value in little endian format */	int n=0;	if (skb == NULL) {		IRDA_DEBUG(2, "%s(), Got NULL skb\n", __FUNCTION__ );		return 0;	}	param_len = strlen(param);	switch (type) {	case IRLAN_BYTE:		value_len = 1;		break;	case IRLAN_SHORT:		value_len = 2;		break;	case IRLAN_ARRAY:		IRDA_ASSERT(value_array != NULL, return 0;);		IRDA_ASSERT(value_len > 0, return 0;);		break;	default:		IRDA_DEBUG(2, "%s(), Unknown parameter type!\n", __FUNCTION__ );		return 0;		break;	}	/* Insert at end of sk-buffer */	frame = skb_tail_pointer(skb);	/* Make space for data */	if (skb_tailroom(skb) < (param_len+value_len+3)) {		IRDA_DEBUG(2, "%s(), No more space at end of skb\n", __FUNCTION__ );		return 0;	}	skb_put(skb, param_len+value_len+3);	/* Insert parameter length */	frame[n++] = param_len;	/* Insert parameter */	memcpy(frame+n, param, param_len); n += param_len;	/* Insert value length (2 byte little endian format, LSB first) */	tmp_le = cpu_to_le16(value_len);	memcpy(frame+n, &tmp_le, 2); n += 2; /* To avoid alignment problems */	/* Insert value */	switch (type) {	case IRLAN_BYTE:		frame[n++] = value_byte;		break;	case IRLAN_SHORT:		tmp_le = cpu_to_le16(value_short);		memcpy(frame+n, &tmp_le, 2); n += 2;		break;	case IRLAN_ARRAY:		memcpy(frame+n, value_array, value_len); n+=value_len;		break;	default:		break;	}	IRDA_ASSERT(n == (param_len+value_len+3), return 0;);	return param_len+value_len+3;}/* * Function irlan_extract_param (buf, name, value, len) * *    Extracts a single parameter name/value pair from buffer and updates *    the buffer pointer to point to the next name/value pair. */int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len){	__u8 name_len;	__u16 val_len;	int n=0;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );	/* get length of parameter name (1 byte) */	name_len = buf[n++];	if (name_len > 254) {		IRDA_DEBUG(2, "%s(), name_len > 254\n", __FUNCTION__ );		return -RSP_INVALID_COMMAND_FORMAT;	}	/* get parameter name */	memcpy(name, buf+n, name_len);	name[name_len] = '\0';	n+=name_len;	/*	 *  Get length of parameter value (2 bytes in little endian	 *  format)	 */	memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */	le16_to_cpus(&val_len); n+=2;	if (val_len > 1016) {		IRDA_DEBUG(2, "%s(), parameter length to long\n", __FUNCTION__ );		return -RSP_INVALID_COMMAND_FORMAT;	}	*len = val_len;	/* get parameter value */	memcpy(value, buf+n, val_len);	value[val_len] = '\0';	n+=val_len;	IRDA_DEBUG(4, "Parameter: %s ", name);	IRDA_DEBUG(4, "Value: %s\n", value);	return n;}#ifdef CONFIG_PROC_FS/* * Start of reading /proc entries. * Return entry at pos, *	or start_token to indicate print header line *	or NULL if end of file */static void *irlan_seq_start(struct seq_file *seq, loff_t *pos){	int i = 1;	struct irlan_cb *self;	rcu_read_lock();	if (*pos == 0)		return SEQ_START_TOKEN;	list_for_each_entry(self, &irlans, dev_list) {		if (*pos == i)			return self;		++i;	}	return NULL;}/* Return entry after v, and increment pos */static void *irlan_seq_next(struct seq_file *seq, void *v, loff_t *pos){	struct list_head *nxt;	++*pos;	if (v == SEQ_START_TOKEN)		nxt = irlans.next;	else		nxt = ((struct irlan_cb *)v)->dev_list.next;	return (nxt == &irlans) ? NULL		: list_entry(nxt, struct irlan_cb, dev_list);}/* End of reading /proc file */static void irlan_seq_stop(struct seq_file *seq, void *v){	rcu_read_unlock();}/* * Show one entry in /proc file. */static int irlan_seq_show(struct seq_file *seq, void *v){	if (v == SEQ_START_TOKEN)		seq_puts(seq, "IrLAN instances:\n");	else {		struct irlan_cb *self = v;		IRDA_ASSERT(self != NULL, return -1;);		IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);		seq_printf(seq,"ifname: %s,\n",			       self->dev->name);		seq_printf(seq,"client state: %s, ",			       irlan_state[ self->client.state]);		seq_printf(seq,"provider state: %s,\n",			       irlan_state[ self->provider.state]);		seq_printf(seq,"saddr: %#08x, ",			       self->saddr);		seq_printf(seq,"daddr: %#08x\n",			       self->daddr);		seq_printf(seq,"version: %d.%d,\n",			       self->version[1], self->version[0]);		seq_printf(seq,"access type: %s\n",			       irlan_access[self->client.access_type]);		seq_printf(seq,"media: %s\n",			       irlan_media[self->media]);		seq_printf(seq,"local filter:\n");		seq_printf(seq,"remote filter: ");		irlan_print_filter(seq, self->client.filter_type);		seq_printf(seq,"tx busy: %s\n",			       netif_queue_stopped(self->dev) ? "TRUE" : "FALSE");		seq_putc(seq,'\n');	}	return 0;}static const struct seq_operations irlan_seq_ops = {	.start = irlan_seq_start,	.next  = irlan_seq_next,	.stop  = irlan_seq_stop,	.show  = irlan_seq_show,};static int irlan_seq_open(struct inode *inode, struct file *file){	return seq_open(file, &irlan_seq_ops);}#endifMODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");MODULE_DESCRIPTION("The Linux IrDA LAN protocol");MODULE_LICENSE("GPL");module_param(eth, bool, 0);MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)");module_param(access, int, 0);MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3");module_init(irlan_init);module_exit(irlan_cleanup);

⌨️ 快捷键说明

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