您当前的位置:首页 > IT编程 > C++
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:C++ udp_hdr函数代码示例

51自学网 2021-06-03 09:06:22
  C++
这篇教程C++ udp_hdr函数代码示例写得很实用,希望能帮到您。

本文整理汇总了C++中udp_hdr函数的典型用法代码示例。如果您正苦于以下问题:C++ udp_hdr函数的具体用法?C++ udp_hdr怎么用?C++ udp_hdr使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。

在下文中一共展示了udp_hdr函数的30个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: udp_gro_complete_segment

static int udp_gro_complete_segment(struct sk_buff *skb){	struct udphdr *uh = udp_hdr(skb);	skb->csum_start = (unsigned char *)uh - skb->head;	skb->csum_offset = offsetof(struct udphdr, check);	skb->ip_summed = CHECKSUM_PARTIAL;	skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;	skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_L4;	return 0;}
开发者ID:AlexShiLucky,项目名称:linux,代码行数:12,


示例2: set_udp_port

static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port){	struct udphdr *uh = udp_hdr(skb);	if (uh->check && skb->ip_summed != CHECKSUM_PARTIAL) {		set_tp_port(skb, port, new_port, &uh->check);		if (!uh->check)			uh->check = CSUM_MANGLED_0;	} else {		*port = new_port;		skb->rxhash = 0;	}}
开发者ID:0xroot,项目名称:Blackphone-BP1-Kernel,代码行数:14,


示例3: prepare_udp_hdr

static void prepare_udp_hdr(struct sk_buff *skb, __be16 src_port,			    __be16 dst_port){	struct udphdr *udph;	__skb_push(skb, sizeof(*udph));	skb_reset_transport_header(skb);	udph = udp_hdr(skb);	udph->dest = dst_port;	udph->source = src_port;	udph->len = htons(skb->len);	udph->check = 0;}
开发者ID:avagin,项目名称:linux,代码行数:14,


示例4: set_udp_port

static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port){	struct udphdr *uh = udp_hdr(skb);	if (uh->check && get_ip_summed(skb) != OVS_CSUM_PARTIAL) {		set_tp_port(skb, port, new_port, &uh->check);		if (!uh->check)			uh->check = CSUM_MANGLED_0;	} else {		*port = new_port;		skb_clear_rxhash(skb);	}}
开发者ID:vthakkar,项目名称:ovs-vxlan,代码行数:14,


示例5: udp6_ufo_send_check

static int udp6_ufo_send_check(struct sk_buff *skb){	const struct ipv6hdr *ipv6h;	struct udphdr *uh;	if (!pskb_may_pull(skb, sizeof(*uh)))		return -EINVAL;	if (likely(!skb->encapsulation)) {		ipv6h = ipv6_hdr(skb);		uh = udp_hdr(skb);		uh->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,					     IPPROTO_UDP, 0);		skb->csum_start = skb_transport_header(skb) - skb->head;		skb->csum_offset = offsetof(struct udphdr, check);		skb->ip_summed = CHECKSUM_PARTIAL;	}
开发者ID:mikuhatsune001,项目名称:linux2.6.32,代码行数:18,


示例6: rpl_udp_set_csum

/* Function to set UDP checksum for an IPv4 UDP packet. This is intended * for the simple case like when setting the checksum for a UDP tunnel. */void rpl_udp_set_csum(bool nocheck, struct sk_buff *skb,		      __be32 saddr, __be32 daddr, int len){	struct udphdr *uh = udp_hdr(skb);	if (nocheck)		uh->check = 0;	else if (skb_is_gso(skb))		uh->check = ~udp_v4_check(len, saddr, daddr, 0);	else {		BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);		skb->ip_summed = CHECKSUM_PARTIAL;		skb->csum_start = skb_transport_header(skb) - skb->head;		skb->csum_offset = offsetof(struct udphdr, check);		uh->check = ~udp_v4_check(len, saddr, daddr, 0);	}}
开发者ID:ALutzG,项目名称:ovs,代码行数:21,


示例7: mlx5e_select_queue_assigned

static u16 mlx5e_select_queue_assigned(struct mlx5e_priv *priv,				       struct sk_buff *skb){	struct mlx5e_sq_flow_map *flow_map;	int sk_ix = sk_tx_queue_get(skb->sk);	u32 key_all, key_dip, key_dport;	u16 dport;	u32 dip;	if (sk_ix >= priv->params.num_channels)		return sk_ix;	if (vlan_get_protocol(skb) == htons(ETH_P_IP)) {		dip = ip_hdr(skb)->daddr;		if (ip_hdr(skb)->protocol == IPPROTO_UDP ||		    ip_hdr(skb)->protocol == IPPROTO_TCP)			dport = udp_hdr(skb)->dest;		else			goto fallback;	} else {		goto fallback;	}	key_all = dip ^ dport;	hash_for_each_possible_rcu(priv->flow_map_hash, flow_map,				   hlist, key_all)		if (flow_map->dst_ip == dip && flow_map->dst_port == dport)			return flow_map->queue_index;	key_dip = dip;	hash_for_each_possible_rcu(priv->flow_map_hash, flow_map,				   hlist, key_dip)		if (flow_map->dst_ip == dip)			return flow_map->queue_index;	key_dport = dport;	hash_for_each_possible_rcu(priv->flow_map_hash, flow_map,				   hlist, key_dport)		if (flow_map->dst_port == dport)			return flow_map->queue_index;fallback:	return 0;}
开发者ID:Mellanox,项目名称:dpdk-dev-mlnx-ofed-kernel,代码行数:44,


示例8: set_udp

static int set_udp(struct sk_buff *skb, const struct ovs_key_udp *udp_port_key){	struct udphdr *uh;	int err;	err = make_writable(skb, skb_transport_offset(skb) +				 sizeof(struct udphdr));	if (unlikely(err))		return err;	uh = udp_hdr(skb);	if (udp_port_key->udp_src != uh->source)		set_udp_port(skb, &uh->source, udp_port_key->udp_src);	if (udp_port_key->udp_dst != uh->dest)		set_udp_port(skb, &uh->dest, udp_port_key->udp_dst);	return 0;}
开发者ID:0xroot,项目名称:Blackphone-BP1-Kernel,代码行数:19,


示例9: etherframe_print

static void etherframe_print(u_char *usr, const struct pcap_pkthdr *pkt,			     const u_char *d, uint16_t ethtype){	struct iphdr *ip;	struct tcphdr *th;	struct udphdr *uh;	uint16_t ethtype_le;	ethtype_le = ntohs(ethtype);	switch (ethtype_le) {	case ETH_P_IP:		ip = ip_hdr(d);		sb_append_str(&sb, "IP: ");		iphdr_print(ip, &sb);		switch (ip->protocol) {		case IPPROTO_TCP:			th = tcp_hdr(d + ip_hdrlen(ip));			sb_append_str(&sb, "; TCP: ");			tcp_print(th, &sb);			break;		case IPPROTO_UDP:			uh = udp_hdr(d + ip_hdrlen(ip));			sb_append_str(&sb, "; UDP: ");			udp_print(uh, &sb);			break;		default:			sb_append_char(&sb, ' ');			sb_append_str(&sb, ipproto_str(ip->protocol));		}		break;	default:		/* FIXME: This code is open to buffer overrun errors */		sb_append_str(&sb, "ether type: ");		sb.len += sprintf(sb_curr(&sb), "0x%04x ", ethtype_le);		sb_append_str(&sb, ethertype_to_str(ethtype_le));	}}
开发者ID:cakturk,项目名称:netsniff,代码行数:42,


示例10: rxe_udp_encap_recv

static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb){	struct udphdr *udph;	struct net_device *ndev = skb->dev;	struct net_device *rdev = ndev;	struct rxe_dev *rxe = rxe_get_dev_from_net(ndev);	struct rxe_pkt_info *pkt = SKB_TO_PKT(skb);	if (!rxe && is_vlan_dev(rdev)) {		rdev = vlan_dev_real_dev(ndev);		rxe = rxe_get_dev_from_net(rdev);	}	if (!rxe)		goto drop;	if (skb_linearize(skb)) {		pr_err("skb_linearize failed/n");		ib_device_put(&rxe->ib_dev);		goto drop;	}	udph = udp_hdr(skb);	pkt->rxe = rxe;	pkt->port_num = 1;	pkt->hdr = (u8 *)(udph + 1);	pkt->mask = RXE_GRH_MASK;	pkt->paylen = be16_to_cpu(udph->len) - sizeof(*udph);	rxe_rcv(skb);	/*	 * FIXME: this is in the wrong place, it needs to be done when pkt is	 * destroyed	 */	ib_device_put(&rxe->ib_dev);	return 0;drop:	kfree_skb(skb);	return 0;}
开发者ID:avagin,项目名称:linux,代码行数:42,


示例11: udp6_set_csum

static void udp6_set_csum(bool nocheck, struct sk_buff *skb,			  const struct in6_addr *saddr,			  const struct in6_addr *daddr, int len){	struct udphdr *uh = udp_hdr(skb);	if (nocheck)		uh->check = 0;	else if (skb_is_gso(skb))		uh->check = ~udp_v6_check(len, saddr, daddr, 0);	else if (skb_dst(skb) && skb_dst(skb)->dev &&		 (skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) {		BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);		skb->ip_summed = CHECKSUM_PARTIAL;		skb->csum_start = skb_transport_header(skb) - skb->head;		skb->csum_offset = offsetof(struct udphdr, check);		uh->check = ~udp_v6_check(len, saddr, daddr, 0);	} else {
开发者ID:0day-ci,项目名称:ovs,代码行数:20,


示例12: rpl_udp_tunnel_xmit_skb

int rpl_udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk,			    struct sk_buff *skb, __be32 src, __be32 dst,			    __u8 tos, __u8 ttl, __be16 df, __be16 src_port,			    __be16 dst_port, bool xnet, bool nocheck){	struct udphdr *uh;	__skb_push(skb, sizeof(*uh));	skb_reset_transport_header(skb);	uh = udp_hdr(skb);	uh->dest = dst_port;	uh->source = src_port;	uh->len = htons(skb->len);	udp_set_csum(nocheck, skb, src, dst, skb->len);	return iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP,			     tos, ttl, df, xnet);}
开发者ID:0day-ci,项目名称:ovs,代码行数:20,


示例13: update_ipv6_checksum

static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,				 __be32 addr[4], const __be32 new_addr[4]){	int transport_len = skb->len - skb_transport_offset(skb);	if (l4_proto == IPPROTO_TCP) {		if (likely(transport_len >= sizeof(struct tcphdr)))			inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb,						  addr, new_addr, 1);	} else if (l4_proto == IPPROTO_UDP) {		if (likely(transport_len >= sizeof(struct udphdr))) {			struct udphdr *uh = udp_hdr(skb);			if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) {				inet_proto_csum_replace16(&uh->check, skb,							  addr, new_addr, 1);				if (!uh->check)					uh->check = CSUM_MANGLED_0;			}		}	}}
开发者ID:MohanaPriya26,项目名称:ovs-reviews,代码行数:22,


示例14: udp_tunnel6_xmit_skb

int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,                         struct sk_buff *skb,                         struct net_device *dev, struct in6_addr *saddr,                         struct in6_addr *daddr,                         __u8 prio, __u8 ttl, __be16 src_port,                         __be16 dst_port, bool nocheck){    struct udphdr *uh;    struct ipv6hdr *ip6h;    __skb_push(skb, sizeof(*uh));    skb_reset_transport_header(skb);    uh = udp_hdr(skb);    uh->dest = dst_port;    uh->source = src_port;    uh->len = htons(skb->len);    memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));    IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED                          | IPSKB_REROUTED);    skb_dst_set(skb, dst);    udp6_set_csum(nocheck, skb, saddr, daddr, skb->len);    __skb_push(skb, sizeof(*ip6h));    skb_reset_network_header(skb);    ip6h		  = ipv6_hdr(skb);    ip6_flow_hdr(ip6h, prio, htonl(0));    ip6h->payload_len = htons(skb->len);    ip6h->nexthdr     = IPPROTO_UDP;    ip6h->hop_limit   = ttl;    ip6h->daddr	  = *daddr;    ip6h->saddr	  = *saddr;    ip6tunnel_xmit(sk, skb, dev);    return 0;}
开发者ID:coderkan,项目名称:linux,代码行数:39,


示例15: udp_rcv

static int udp_rcv(struct sk_buff *skb) {	struct sock *sk;	assert(skb != NULL);	assert(ip_check_version(ip_hdr(skb))			|| ip6_check_version(ip6_hdr(skb)));	/* Check CRC */	if (MODOPS_VERIFY_CHKSUM) {		uint16_t old_check;		old_check = skb->h.uh->check;		udp_set_check_field(skb->h.uh, skb->nh.raw);		if (old_check != skb->h.uh->check) {			return 0; /* error: bad checksum */		}	}	sk = sock_lookup(NULL, udp_sock_ops,			ip_check_version(ip_hdr(skb))				? udp4_rcv_tester : udp6_rcv_tester,			skb);	if (sk != NULL) {		if (ip_check_version(ip_hdr(skb))				? udp4_accept_dst(sk, skb)				: udp6_accept_dst(sk, skb)) {			sock_rcv(sk, skb, skb->h.raw + UDP_HEADER_SIZE,					udp_data_length(udp_hdr(skb)));		}		else {			skb_free(skb);		}	}	else {		icmp_discard(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH);	}	return 0;}
开发者ID:AleksandraButrova,项目名称:embox,代码行数:38,


示例16: invert_packet

static boolinvert_packet(struct xlation *state, struct sk_buff **skb){	struct iphdr *hdr4;	struct udphdr *uhdr;	if (create_skb4_udp("1.1.1.1", 1111, "2.2.2.2", 2222, 100, 32, skb))		return false;	if (invert_tuple(state))		return false;	hdr4 = ip_hdr(*skb);	uhdr = udp_hdr(*skb);	hdr4->saddr = state->in.tuple.src.addr4.l3.s_addr;	uhdr->source = cpu_to_be16(state->in.tuple.src.addr4.l4);	hdr4->daddr = state->in.tuple.dst.addr4.l3.s_addr;	uhdr->dest = cpu_to_be16(state->in.tuple.dst.addr4.l4);	if (pkt_init_ipv4(state, *skb))		return false;	return true;}
开发者ID:NICMx,项目名称:Jool,代码行数:23,


示例17: vxlan_udp_encap_recv

/* Callback from net/ipv4/udp.c to receive packets */static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb){	struct vxlan_sock *vs;	struct vxlanhdr *vxh;	/* Need Vxlan and inner Ethernet header to be present */	if (!pskb_may_pull(skb, VXLAN_HLEN))		goto error;	/* Return packets with reserved bits set */	vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);	if (vxh->vx_flags != htonl(VXLAN_FLAGS) ||	    (vxh->vx_vni & htonl(0xff))) {		pr_warn("invalid vxlan flags=%#x vni=%#x/n",			ntohl(vxh->vx_flags), ntohl(vxh->vx_vni));		goto error;	}	if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))		goto drop;	vs = rcu_dereference_sk_user_data(sk);	if (!vs)		goto drop;	vs->rcv(vs, skb, vxh->vx_vni);	return 0;drop:	/* Consume bad packet */	kfree_skb(skb);	return 0;error:	/* Return non vxlan pkt */	return 1;}
开发者ID:Altiscale,项目名称:ovs,代码行数:38,


示例18: vxlan_gso

static void vxlan_gso(struct sk_buff *skb){	int udp_offset = skb_transport_offset(skb);	struct udphdr *uh;	uh = udp_hdr(skb);	uh->len = htons(skb->len - udp_offset);	/* csum segment if tunnel sets skb with csum. */	if (unlikely(uh->check)) {		struct iphdr *iph = ip_hdr(skb);		uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,					       skb->len - udp_offset,					       IPPROTO_UDP, 0);		uh->check = csum_fold(skb_checksum(skb, udp_offset,				      skb->len - udp_offset, 0));		if (uh->check == 0)			uh->check = CSUM_MANGLED_0;	}	skb->ip_summed = CHECKSUM_NONE;}
开发者ID:Altiscale,项目名称:ovs,代码行数:24,


示例19: lisp_input

/* * lisp_input() * * Packet entry point into LISP processing. Since all packets * will come here, we must be efficient at disposing of non-LISP * destined datagrams. */unsigned int lisp_input(unsigned int hooknum, struct sk_buff *packet_buf,			const struct net_device *input_dev,			const struct net_device *output_dev,			int (*okfunc)(struct sk_buff*)){  struct iphdr *iph;  struct ipv6hdr *ip6;  struct udphdr *udh;  struct lisphdr *lisp_hdr;  char   first_byte;  int source_locator;  /*   * PN: net_device corresponding to LISP_EID_INTERFACE   */  struct net_device *eid_int = NULL;  /*   * Get the IP header   */  iph = ip_hdr(packet_buf);  if (!iph) {    printk(KERN_INFO "Odd, no IP header/n");    return NF_ACCEPT;  }  source_locator = iph->saddr;#ifdef DEBUG_PACKETS  printk(KERN_INFO "In LISP Input with packet from %pI4 for %pI4/n",         &(source_locator), &(iph->daddr));#endif  /*   * Certain things should never be LISP examined:   * locally loopback sourced.   */  if (packet_buf->pkt_type == PACKET_LOOPBACK) {      return NF_ACCEPT;  }  /*   * Check for UDP   */  if (iph->protocol == IPPROTO_UDP) {    // Move past the ip header    skb_pull(packet_buf, sizeof(struct iphdr));    skb_reset_transport_header(packet_buf);    udh = udp_hdr(packet_buf);     first_byte= *((char *)udh + sizeof(struct udphdr));#ifdef DEBUG_PACKETS    printk(KERN_INFO "  Proto is UDP, src port: %d dest port: %d/n",	   ntohs(udh->source), ntohs(udh->dest));    printk(KERN_INFO "  First byte: 0x%x", first_byte);#endif    // Detect non-encapsulated lisp control messages    if (ntohs(udh->dest) == globals.udp_encap_port &&        ntohs(udh->source) != LISP_CONTROL_PORT &&        (first_byte != echo_signature)) {      // LISP header      lisp_hdr = (struct lisphdr *)skb_pull(packet_buf, sizeof(struct udphdr));      skb_reset_transport_header(packet_buf);#ifdef DEBUG_PACKETS      printk(KERN_INFO "   LISP packet received: dest %d, len: %d/n", ntohs(udh->dest),	     ntohs(udh->len));      printk(KERN_INFO "       rflags: %d, e: %d, l: %d, n: %d, lsb: 0x%x",             lisp_hdr->rflags, lisp_hdr->echo_nonce, lisp_hdr->lsb,             lisp_hdr->nonce_present, lisp_hdr->lsb_bits);#endif      // Decapsulate      skb_pull(packet_buf, sizeof(struct lisphdr));      skb_reset_transport_header(packet_buf);      skb_reset_network_header(packet_buf);      iph = ip_hdr(packet_buf);      if (iph->version == 4) {#ifdef DEBUG_PACKETS      printk(KERN_INFO "   Inner packet src:%pI4 dst:%pI4, type: %d/n", &(iph->saddr),             &(iph->daddr), iph->protocol);#endif      // Check the LSB's.      check_locator_bits(lisp_hdr, iph, AF_INET, source_locator);      eid_int = dev_get_by_name (&init_net, LISP_EID_INTERFACE);      if (eid_int) {//.........这里部分代码省略.........
开发者ID:jjsarton,项目名称:lispmob,代码行数:101,


示例20: return

static inline struct lisphdr *lisp_hdr(const struct sk_buff *skb){	return (struct lisphdr *)(udp_hdr(skb) + 1);}
开发者ID:0day-ci,项目名称:ovs,代码行数:4,


示例21: test_hairpin

static bool test_hairpin(l4_protocol l4_proto, skb_creator create_skb_fn){	struct sk_buff *skb_in = NULL;	struct sk_buff *skb_out = NULL;	struct sk_buff *skb_tmp = NULL;	struct bib_entry *static_bib = NULL;	struct bib_entry *dynamic_bib = NULL;	struct session_entry *static_session = NULL;	struct session_entry *dynamic_session = NULL;	struct tuple tuple6;	bool success = true;	static_bib = bib_create_str(SERVER_ADDR6, SERVER_PORT6,			NAT64_POOL4, SERVER_PORT6,			l4_proto);	dynamic_bib = bib_create_str(CLIENT_ADDR, CLIENT_PORT,			NAT64_POOL4, DYNAMIC_BIB_IPV4_PORT,			l4_proto);	static_session = session_create_str(			SERVER_ADDR6, SERVER_PORT6,			SERVER_HAIRPIN_ADDR, DYNAMIC_BIB_IPV4_PORT,			NAT64_POOL4, SERVER_PORT6,			NAT64_POOL4, DYNAMIC_BIB_IPV4_PORT,			l4_proto);	dynamic_session = session_create_str(CLIENT_ADDR, CLIENT_PORT,			SERVER_HAIRPIN_ADDR, SERVER_PORT6,			NAT64_POOL4, DYNAMIC_BIB_IPV4_PORT,			NAT64_POOL4, SERVER_PORT6,			l4_proto);	if (!static_bib || !dynamic_bib || !static_session || !dynamic_session)		goto fail;	/* Send the request. */	if (is_error(init_ipv6_tuple(&tuple6,			CLIENT_ADDR, CLIENT_PORT,			SERVER_HAIRPIN_ADDR, SERVER_PORT6,			l4_proto)))		goto fail;	if (is_error(create_skb_fn(&tuple6, &skb_in, 40, 32)))		goto fail;	success &= send(skb_in);	success &= BIB_ASSERT(l4_proto, static_bib, dynamic_bib);	success &= SESSION_ASSERT(l4_proto, static_session, dynamic_session);	skb_out = skb_tmp = get_sent_skb();	success &= assert_not_null(skb_out, "Request packet");	if (!success)		goto fail;	do {		success &= assert_equals_ipv6_str(SERVER_HAIRPIN_ADDR, &ipv6_hdr(skb_tmp)->saddr, "out src");		success &= assert_equals_ipv6_str(SERVER_ADDR6, &ipv6_hdr(skb_tmp)->daddr, "out dst");		skb_tmp = skb_tmp->next;	} while (skb_tmp);	switch (l4_proto) {	case L4PROTO_UDP:		success &= assert_equals_u16(DYNAMIC_BIB_IPV4_PORT,				be16_to_cpu(udp_hdr(skb_out)->source),				"out's src port");		success &= assert_equals_u16(SERVER_PORT6,				be16_to_cpu(udp_hdr(skb_out)->dest),				"out's dst port");		break;	case L4PROTO_TCP:		success &= assert_equals_u16(DYNAMIC_BIB_IPV4_PORT,				be16_to_cpu(tcp_hdr(skb_out)->source),				"out's src port");		success &= assert_equals_u16(SERVER_PORT6,				be16_to_cpu(tcp_hdr(skb_out)->dest),				"out's dst port");		break;	case L4PROTO_ICMP:	case L4PROTO_OTHER:		log_err("Test is not designed for protocol %d.", l4_proto);		success = false;		break;	}	if (!success)		goto fail;	kfree_skb(skb_out);	/* Send the response. */	if (is_error(init_ipv6_tuple(&tuple6,			SERVER_ADDR6, SERVER_PORT6,			SERVER_HAIRPIN_ADDR, DYNAMIC_BIB_IPV4_PORT,			l4_proto)))		goto fail;	if (is_error(create_skb_fn(&tuple6, &skb_in, 100, 32)))		goto fail;	success &= send(skb_in);	/* The module should have reused the entries, so the database shouldn't have changed. */	success &= BIB_ASSERT(l4_proto, static_bib, dynamic_bib);	success &= SESSION_ASSERT(l4_proto, static_session, dynamic_session);	skb_out = skb_tmp = get_sent_skb();//.........这里部分代码省略.........
开发者ID:patybarron,项目名称:NAT64,代码行数:101,


示例22: netvsc_start_xmit

//.........这里部分代码省略.........	if ((skb->ip_summed == CHECKSUM_NONE) ||	    (skb->ip_summed == CHECKSUM_UNNECESSARY))		goto do_send;	rndis_msg_size += NDIS_CSUM_PPI_SIZE;	ppi = init_ppi_data(rndis_msg, NDIS_CSUM_PPI_SIZE,			    TCPIP_CHKSUM_PKTINFO);	csum_info = (struct ndis_tcp_ip_checksum_info *)((void *)ppi +			ppi->ppi_offset);	if (net_trans_info & (INFO_IPV4 << 16))		csum_info->transmit.is_ipv4 = 1;	else		csum_info->transmit.is_ipv6 = 1;	if (net_trans_info & INFO_TCP) {		csum_info->transmit.tcp_checksum = 1;		csum_info->transmit.tcp_header_offset = hdr_offset;	} else if (net_trans_info & INFO_UDP) {		/* UDP checksum offload is not supported on ws2008r2.		 * Furthermore, on ws2012 and ws2012r2, there are some		 * issues with udp checksum offload from Linux guests.		 * (these are host issues).		 * For now compute the checksum here.		 */		struct udphdr *uh;		u16 udp_len;		ret = skb_cow_head(skb, 0);		if (ret)			goto drop;		uh = udp_hdr(skb);		udp_len = ntohs(uh->len);		uh->check = 0;		uh->check = csum_tcpudp_magic(ip_hdr(skb)->saddr,					      ip_hdr(skb)->daddr,					      udp_len, IPPROTO_UDP,#if defined(RHEL_RELEASE_VERSION) && (RHEL_RELEASE_CODE <= 1291)					      csum_partial((unsigned char *)uh, udp_len, 0));#else					      csum_partial(uh, udp_len, 0));#endif		if (uh->check == 0)			uh->check = CSUM_MANGLED_0;		csum_info->transmit.udp_checksum = 0;	}	goto do_send;do_lso:	rndis_msg_size += NDIS_LSO_PPI_SIZE;	ppi = init_ppi_data(rndis_msg, NDIS_LSO_PPI_SIZE,			    TCP_LARGESEND_PKTINFO);	lso_info = (struct ndis_tcp_lso_info *)((void *)ppi +			ppi->ppi_offset);	lso_info->lso_v2_transmit.type = NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE;	if (net_trans_info & (INFO_IPV4 << 16)) {		lso_info->lso_v2_transmit.ip_version =			NDIS_TCP_LARGE_SEND_OFFLOAD_IPV4;		ip_hdr(skb)->tot_len = 0;		ip_hdr(skb)->check = 0;		tcp_hdr(skb)->check =
开发者ID:ayiyaliing,项目名称:lis-next,代码行数:67,


示例23: validate_frag6

static bool validate_frag6(struct sk_buff *skb, bool is_first, bool is_last, u16 offset,		u16 payload_len, u16 payload_offset, struct tuple *tuple, l4_protocol l4proto,		u16 total_payload){	size_t l4hdr_size;	u16 l4_next_hdr;	u16 mf = is_last ? 0 : IP6_MF;	u16 hdr_payload_len;	switch (l4proto) {	case (L4PROTO_TCP):		l4hdr_size = sizeof(struct tcphdr);		l4_next_hdr = NEXTHDR_TCP;		break;	case (L4PROTO_UDP):		l4hdr_size = sizeof(struct udphdr);		l4_next_hdr = NEXTHDR_UDP;		break;	case (L4PROTO_ICMP):		l4hdr_size = sizeof(struct icmp6hdr);		l4_next_hdr = NEXTHDR_ICMP;		break;	default:		log_debug("Invalid l4 protocol: %u", l4proto);		return false;	}	hdr_payload_len = sizeof(struct frag_hdr) + (is_first ? l4hdr_size : 0)	+ payload_len;	if (!skb) {		log_err("The skb is NULL.");		return false;	}	if (!validate_cb_l3(skb, L3PROTO_IPV6, sizeof(struct ipv6hdr) + sizeof(struct frag_hdr)))		return false;	if (!validate_cb_l4(skb, l4proto, is_first ? l4hdr_size : 0))		return false;	if (!validate_cb_payload(skb, payload_len))		return false;	if (!validate_ipv6_hdr(ipv6_hdr(skb), hdr_payload_len, NEXTHDR_FRAGMENT, tuple))		return false;	if (!validate_frag_hdr(get_extension_header(ipv6_hdr(skb), NEXTHDR_FRAGMENT), offset, mf,			l4_next_hdr))		return false;	switch (l4proto) {	case (L4PROTO_TCP):		if (is_first && !validate_tcp_hdr(tcp_hdr(skb), tuple))			return false;		break;	case (L4PROTO_UDP):		if (is_first && !validate_udp_hdr(udp_hdr(skb), total_payload, tuple))			return false;		break;	case (L4PROTO_ICMP):		/*id field is not used in the validate_icmp6_hdr function.*/		if (is_first && !validate_icmp6_hdr(icmp6_hdr(skb), 1234, tuple))			return false;		break;	}	if (!validate_payload(skb_payload(skb), payload_len, payload_offset))		return false;	return true;}
开发者ID:magg,项目名称:NAT64,代码行数:66,


示例24: skb_shinfo

struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,				  netdev_features_t features){	struct sock *sk = gso_skb->sk;	unsigned int sum_truesize = 0;	struct sk_buff *segs, *seg;	struct udphdr *uh;	unsigned int mss;	bool copy_dtor;	__sum16 check;	__be16 newlen;	mss = skb_shinfo(gso_skb)->gso_size;	if (gso_skb->len <= sizeof(*uh) + mss)		return ERR_PTR(-EINVAL);	skb_pull(gso_skb, sizeof(*uh));	/* clear destructor to avoid skb_segment assigning it to tail */	copy_dtor = gso_skb->destructor == sock_wfree;	if (copy_dtor)		gso_skb->destructor = NULL;	segs = skb_segment(gso_skb, features);	if (unlikely(IS_ERR_OR_NULL(segs))) {		if (copy_dtor)			gso_skb->destructor = sock_wfree;		return segs;	}	/* GSO partial and frag_list segmentation only requires splitting	 * the frame into an MSS multiple and possibly a remainder, both	 * cases return a GSO skb. So update the mss now.	 */	if (skb_is_gso(segs))		mss *= skb_shinfo(segs)->gso_segs;	seg = segs;	uh = udp_hdr(seg);	/* compute checksum adjustment based on old length versus new */	newlen = htons(sizeof(*uh) + mss);	check = csum16_add(csum16_sub(uh->check, uh->len), newlen);	for (;;) {		if (copy_dtor) {			seg->destructor = sock_wfree;			seg->sk = sk;			sum_truesize += seg->truesize;		}		if (!seg->next)			break;		uh->len = newlen;		uh->check = check;		if (seg->ip_summed == CHECKSUM_PARTIAL)			gso_reset_checksum(seg, ~check);		else			uh->check = gso_make_checksum(seg, ~check) ? :				    CSUM_MANGLED_0;		seg = seg->next;		uh = udp_hdr(seg);	}	/* last packet can be partial gso_size, account for that in checksum */	newlen = htons(skb_tail_pointer(seg) - skb_transport_header(seg) +		       seg->data_len);	check = csum16_add(csum16_sub(uh->check, uh->len), newlen);	uh->len = newlen;	uh->check = check;	if (seg->ip_summed == CHECKSUM_PARTIAL)		gso_reset_checksum(seg, ~check);	else		uh->check = gso_make_checksum(seg, ~check) ? : CSUM_MANGLED_0;	/* update refcount for the packet */	if (copy_dtor) {		int delta = sum_truesize - gso_skb->truesize;		/* In some pathological cases, delta can be negative.		 * We need to either use refcount_add() or refcount_sub_and_test()		 */		if (likely(delta >= 0))			refcount_add(delta, &sk->sk_wmem_alloc);		else			WARN_ON_ONCE(refcount_sub_and_test(-delta, &sk->sk_wmem_alloc));	}	return segs;}
开发者ID:AlexShiLucky,项目名称:linux,代码行数:94,


示例25: xfrm4_udp_encap_rcv

int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb){	struct udp_sock *up = udp_sk(sk);	struct udphdr *uh;	struct iphdr *iph;	int iphlen, len;	__u8 *udpdata;	__be32 *udpdata32;	__u16 encap_type = up->encap_type;	/* if this is not encapsulated socket, then just return now */	if (!encap_type)		return 1;	/* If this is a paged skb, make sure we pull up	 * whatever data we need to look at. */	len = skb->len - sizeof(struct udphdr);	if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))		return 1;	/* Now we can get the pointers */	uh = udp_hdr(skb);	udpdata = (__u8 *)uh + sizeof(struct udphdr);	udpdata32 = (__be32 *)udpdata;	switch (encap_type) {	default:	case UDP_ENCAP_ESPINUDP:		/* Check if this is a keepalive packet.  If so, eat it. */		if (len == 1 && udpdata[0] == 0xff) {			goto drop;		} else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {			/* ESP Packet without Non-ESP header */			len = sizeof(struct udphdr);		} else			/* Must be an IKE packet.. pass it through */			return 1;		break;	case UDP_ENCAP_ESPINUDP_NON_IKE:		/* Check if this is a keepalive packet.  If so, eat it. */		if (len == 1 && udpdata[0] == 0xff) {			goto drop;		} else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&			   udpdata32[0] == 0 && udpdata32[1] == 0) {			/* ESP Packet with Non-IKE marker */			len = sizeof(struct udphdr) + 2 * sizeof(u32);		} else			/* Must be an IKE packet.. pass it through */			return 1;		break;	}	/* At this point we are sure that this is an ESPinUDP packet,	 * so we need to remove 'len' bytes from the packet (the UDP	 * header and optional ESP marker bytes) and then modify the	 * protocol to ESP, and then call into the transform receiver.	 */	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))		goto drop;	/* Now we can update and verify the packet length... */	iph = ip_hdr(skb);	iphlen = iph->ihl << 2;	iph->tot_len = htons(ntohs(iph->tot_len) - len);	if (skb->len < iphlen + len) {		/* packet is too small!?! */		goto drop;	}	/* pull the data buffer up to the ESP header and set the	 * transport header to point to ESP.  Keep UDP on the stack	 * for later.	 */	__skb_pull(skb, len);	skb_reset_transport_header(skb);	/* process ESP */	return xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);drop:	kfree_skb(skb);	return 0;}
开发者ID:flwh,项目名称:Alcatel_OT_985_kernel,代码行数:85,


示例26: init_skb_for_test

struct sk_buff* init_skb_for_test(  struct tuple *tuple, u_int8_t protocol ){    __u32 l3_len;    __u32 l4_len;    struct tcphdr *tcp_header;    struct udphdr *udp_header;    struct icmphdr *icmp_header;    struct iphdr *ip_header = NULL;        struct sk_buff *skb;    switch(protocol)    {        case IPPROTO_TCP:            l4_len = sizeof(struct tcphdr);            break;        case IPPROTO_UDP:            l4_len = sizeof(struct udphdr);            break;        case IPPROTO_ICMP:            l4_len = sizeof(struct icmphdr);            break;        default:            log_warning("Invalid protocol 1: %u", protocol);            return NULL;    }    l3_len = sizeof(struct iphdr);    skb = alloc_skb(LL_MAX_HEADER + l3_len + l4_len + SKB_PAYLOAD, GFP_ATOMIC);    if (!skb)    {        log_warning("  New packet allocation failed.");        return NULL;    }    skb_reserve(skb, LL_MAX_HEADER);    skb_put(skb, l3_len + l4_len + SKB_PAYLOAD);    skb_reset_mac_header(skb);    skb_reset_network_header(skb);    skb_set_transport_header(skb, l3_len);    ip_header = ip_hdr(skb);    memset(ip_header, 0, sizeof(struct iphdr));    switch(protocol)    {        case IPPROTO_TCP:            tcp_header = tcp_hdr(skb);            memset(tcp_header, 0, l4_len);            tcp_header->source = tuple->src.l4_id;            tcp_header->dest = tuple->dst.l4_id;            break;        case IPPROTO_UDP:            udp_header = udp_hdr(skb);            memset(udp_header, 0, l4_len);                        udp_header->source = tuple->src.l4_id;            udp_header->dest = tuple->dst.l4_id;            udp_header->len = htons(sizeof(struct udphdr) + SKB_PAYLOAD);            udp_header->check = 0;            break;        case IPPROTO_ICMP:            icmp_header = icmp_hdr(skb);            memset(icmp_header, 0, l4_len);			icmp_header->type = ICMP_ECHO;			/* icmp_header->type = ICMP_ECHOREPLY; */			/* icmp6_header->icmp6_type = ICMPV6_ECHO_REQUEST; */			/* icmp6_header->icmp6_type = ICMPV6_ECHO_REPLY; */            break;        default:            log_warning("Invalid protocol 2: %u", protocol);            kfree_skb(skb);            return NULL;    }    ip_header->version = 4;    ip_header->ihl = (sizeof(struct iphdr)) /4 ;    ip_header->tos = 0;    ip_header->tot_len = htons(l3_len + l4_len + SKB_PAYLOAD);    ip_header->id = htons(111);    ip_header->frag_off = 0;    ip_header->ttl = 64;    ip_header->protocol = protocol;    ip_header->check = 0;    /* skb_forward_csum(skb); */    ip_header->saddr = tuple->src.addr.ipv4.s_addr;    ip_header->daddr = tuple->dst.addr.ipv4.s_addr;    skb->protocol = htons(ETH_P_IP);    return skb;}
开发者ID:kuldeepin,项目名称:NAT64,代码行数:96,


示例27: ERR_PTR

static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,					 netdev_features_t features){	struct sk_buff *segs = ERR_PTR(-EINVAL);	unsigned int mss;	unsigned int unfrag_ip6hlen, unfrag_len;	struct frag_hdr *fptr;	u8 *packet_start, *prevhdr;	u8 nexthdr;	u8 frag_hdr_sz = sizeof(struct frag_hdr);	__wsum csum;	int tnl_hlen;	int err;	mss = skb_shinfo(skb)->gso_size;	if (unlikely(skb->len <= mss))		goto out;	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {		/* Packet is from an untrusted source, reset gso_segs. */		skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);		/* Set the IPv6 fragment id if not set yet */		if (!skb_shinfo(skb)->ip6_frag_id)			ipv6_proxy_select_ident(dev_net(skb->dev), skb);		segs = NULL;		goto out;	}	if (skb->encapsulation && skb_shinfo(skb)->gso_type &	    (SKB_GSO_UDP_TUNNEL|SKB_GSO_UDP_TUNNEL_CSUM))		segs = skb_udp_tunnel_segment(skb, features, true);	else {		const struct ipv6hdr *ipv6h;		struct udphdr *uh;		if (!pskb_may_pull(skb, sizeof(struct udphdr)))			goto out;		/* Do software UFO. Complete and fill in the UDP checksum as HW cannot		 * do checksum of UDP packets sent as multiple IP fragments.		 */		uh = udp_hdr(skb);		ipv6h = ipv6_hdr(skb);		uh->check = 0;		csum = skb_checksum(skb, 0, skb->len, 0);		uh->check = udp_v6_check(skb->len, &ipv6h->saddr,					  &ipv6h->daddr, csum);		if (uh->check == 0)			uh->check = CSUM_MANGLED_0;		skb->ip_summed = CHECKSUM_UNNECESSARY;		/* If there is no outer header we can fake a checksum offload		 * due to the fact that we have already done the checksum in		 * software prior to segmenting the frame.		 */		if (!skb->encap_hdr_csum)			features |= NETIF_F_HW_CSUM;		/* Check if there is enough headroom to insert fragment header. */		tnl_hlen = skb_tnl_header_len(skb);		if (skb->mac_header < (tnl_hlen + frag_hdr_sz)) {			if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz))				goto out;		}		/* Find the unfragmentable header and shift it left by frag_hdr_sz		 * bytes to insert fragment header.		 */		err = ip6_find_1stfragopt(skb, &prevhdr);		if (err < 0)			return ERR_PTR(err);		unfrag_ip6hlen = err;		nexthdr = *prevhdr;		*prevhdr = NEXTHDR_FRAGMENT;		unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) +			     unfrag_ip6hlen + tnl_hlen;		packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset;		memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len);		SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz;		skb->mac_header -= frag_hdr_sz;		skb->network_header -= frag_hdr_sz;		fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen);		fptr->nexthdr = nexthdr;		fptr->reserved = 0;		if (!skb_shinfo(skb)->ip6_frag_id)			ipv6_proxy_select_ident(dev_net(skb->dev), skb);		fptr->identification = skb_shinfo(skb)->ip6_frag_id;		/* Fragment the skb. ipv6 header and the remaining fields of the		 * fragment header are updated in ipv6_gso_segment()		 */		segs = skb_segment(skb, features);//.........这里部分代码省略.........
开发者ID:mdamt,项目名称:linux,代码行数:101,


示例28: rxrpc_reject_packets

void rxrpc_reject_packets(struct work_struct *work){	union {		struct sockaddr sa;		struct sockaddr_in sin;	} sa;	struct rxrpc_skb_priv *sp;	struct rxrpc_header hdr;	struct rxrpc_local *local;	struct sk_buff *skb;	struct msghdr msg;	struct kvec iov[2];	size_t size;	__be32 code;	local = container_of(work, struct rxrpc_local, rejecter);	rxrpc_get_local(local);	_enter("%d", local->debug_id);	iov[0].iov_base = &hdr;	iov[0].iov_len = sizeof(hdr);	iov[1].iov_base = &code;	iov[1].iov_len = sizeof(code);	size = sizeof(hdr) + sizeof(code);	msg.msg_name = &sa;	msg.msg_control = NULL;	msg.msg_controllen = 0;	msg.msg_flags = 0;	memset(&sa, 0, sizeof(sa));	sa.sa.sa_family = local->srx.transport.family;	switch (sa.sa.sa_family) {	case AF_INET:		msg.msg_namelen = sizeof(sa.sin);		break;	default:		msg.msg_namelen = 0;		break;	}	memset(&hdr, 0, sizeof(hdr));	hdr.type = RXRPC_PACKET_TYPE_ABORT;	while ((skb = skb_dequeue(&local->reject_queue))) {		sp = rxrpc_skb(skb);		switch (sa.sa.sa_family) {		case AF_INET:			sa.sin.sin_port = udp_hdr(skb)->source;			sa.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;			code = htonl(skb->priority);			hdr.epoch = sp->hdr.epoch;			hdr.cid = sp->hdr.cid;			hdr.callNumber = sp->hdr.callNumber;			hdr.serviceId = sp->hdr.serviceId;			hdr.flags = sp->hdr.flags;			hdr.flags ^= RXRPC_CLIENT_INITIATED;			hdr.flags &= RXRPC_CLIENT_INITIATED;			kernel_sendmsg(local->socket, &msg, iov, 2, size);			break;		default:			break;		}		rxrpc_free_skb(skb);		rxrpc_put_local(local);	}	rxrpc_put_local(local);	_leave("");}
开发者ID:flwh,项目名称:Alcatel_OT_985_kernel,代码行数:75,


示例29: key_extract

//.........这里部分代码省略.........		nh = ip_hdr(skb);		key->ipv4.addr.src = nh->saddr;		key->ipv4.addr.dst = nh->daddr;		key->ip.proto = nh->protocol;		key->ip.tos = nh->tos;		key->ip.ttl = nh->ttl;		offset = nh->frag_off & htons(IP_OFFSET);		if (offset) {			key->ip.frag = OVS_FRAG_TYPE_LATER;			return 0;		}		if (nh->frag_off & htons(IP_MF) ||			skb_shinfo(skb)->gso_type & SKB_GSO_UDP)			key->ip.frag = OVS_FRAG_TYPE_FIRST;		else			key->ip.frag = OVS_FRAG_TYPE_NONE;		/* Transport layer. */		if (key->ip.proto == IPPROTO_TCP) {			if (tcphdr_ok(skb)) {				struct tcphdr *tcp = tcp_hdr(skb);				key->tp.src = tcp->source;				key->tp.dst = tcp->dest;				key->tp.flags = TCP_FLAGS_BE16(tcp);			} else {				memset(&key->tp, 0, sizeof(key->tp));			}		} else if (key->ip.proto == IPPROTO_UDP) {			if (udphdr_ok(skb)) {				struct udphdr *udp = udp_hdr(skb);				key->tp.src = udp->source;				key->tp.dst = udp->dest;			} else {				memset(&key->tp, 0, sizeof(key->tp));			}		} else if (key->ip.proto == IPPROTO_SCTP) {			if (sctphdr_ok(skb)) {				struct sctphdr *sctp = sctp_hdr(skb);				key->tp.src = sctp->source;				key->tp.dst = sctp->dest;			} else {				memset(&key->tp, 0, sizeof(key->tp));			}		} else if (key->ip.proto == IPPROTO_ICMP) {			if (icmphdr_ok(skb)) {				struct icmphdr *icmp = icmp_hdr(skb);				/* The ICMP type and code fields use the 16-bit				 * transport port fields, so we need to store				 * them in 16-bit network byte order.				 */				key->tp.src = htons(icmp->type);				key->tp.dst = htons(icmp->code);			} else {				memset(&key->tp, 0, sizeof(key->tp));			}		}	} else if (key->eth.type == htons(ETH_P_ARP) ||		   key->eth.type == htons(ETH_P_RARP)) {		struct arp_eth_header *arp;		bool arp_available = arphdr_ok(skb);
开发者ID:TCSOpenVSwitch,项目名称:ovs,代码行数:66,


示例30: return

static inline struct genevehdr *geneve_hdr(const struct sk_buff *skb){    return (struct genevehdr *)(udp_hdr(skb) + 1);}
开发者ID:umbs,项目名称:ops-openvswitch,代码行数:4,



注:本文中的udp_hdr函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


C++ udp_init函数代码示例
C++ udp_disconnect函数代码示例
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。