本文整理汇总了C++中skb_make_writable函数的典型用法代码示例。如果您正苦于以下问题:C++ skb_make_writable函数的具体用法?C++ skb_make_writable怎么用?C++ skb_make_writable使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了skb_make_writable函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: xtnu_skb_make_writable
int xtnu_skb_make_writable(struct sk_buff **pskb, unsigned int len)
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
return skb_make_writable(pskb, len);
#else
return skb_make_writable(*pskb, len);
#endif
}
开发者ID:DigitalPig,项目名称:west-chamber-scholar-zhang,代码行数:8,代码来源:compat_xtables.c
示例2: nf_nat_ipv4_manip_pkt
static bool nf_nat_ipv4_manip_pkt(struct sk_buff *skb,
unsigned int iphdroff,
const struct nf_nat_l4proto *l4proto,
const struct nf_conntrack_tuple *target,
enum nf_nat_manip_type maniptype)
{
struct iphdr *iph;
unsigned int hdroff;
if (!skb_make_writable(skb, iphdroff + sizeof(*iph)))
return false;
iph = (void *)skb->data + iphdroff;
hdroff = iphdroff + iph->ihl * 4;
if (!l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv4, iphdroff, hdroff,
target, maniptype))
return false;
iph = (void *)skb->data + iphdroff;
if (maniptype == NF_NAT_MANIP_SRC) {
csum_replace4(&iph->check, iph->saddr, target->src.u3.ip);
iph->saddr = target->src.u3.ip;
} else {
csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip);
iph->daddr = target->dst.u3.ip;
}
return true;
}
开发者ID:ReneNyffenegger,项目名称:linux,代码行数:29,代码来源:nf_nat_l3proto_ipv4.c
示例3: ebt_target_snat
static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
const struct ebt_nat_info *info = data;
if (!skb_make_writable(skb, 0))
return EBT_DROP;
memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
if (!(info->target & NAT_ARP_BIT) &&
eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
const struct arphdr *ap;
struct arphdr _ah;
ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
if (ap == NULL)
return EBT_DROP;
if (ap->ar_hln != ETH_ALEN)
goto out;
if (skb_store_bits(skb, sizeof(_ah), info->mac,ETH_ALEN))
return EBT_DROP;
}
out:
return info->target | ~EBT_VERDICT_BITS;
}
开发者ID:274914765,项目名称:C,代码行数:26,代码来源:ebt_snat.c
示例4: set_ect_tcp
/* Return 0 if there was an error. */
static inline int
set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{
struct tcphdr _tcph, *tcph;
__be16 oldval;
/* Not enought header? */
tcph = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
sizeof(_tcph), &_tcph);
if (!tcph)
return 0;
if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) ||
tcph->ece == einfo->proto.tcp.ece) &&
((!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
tcph->cwr == einfo->proto.tcp.cwr)))
return 1;
if (!skb_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph)))
return 0;
tcph = (void *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl*4;
oldval = ((__be16 *)tcph)[6];
if (einfo->operation & IPT_ECN_OP_SET_ECE)
tcph->ece = einfo->proto.tcp.ece;
if (einfo->operation & IPT_ECN_OP_SET_CWR)
tcph->cwr = einfo->proto.tcp.cwr;
nf_proto_csum_replace2(&tcph->check, *pskb,
oldval, ((__be16 *)tcph)[6], 0);
return 1;
}
开发者ID:WiseMan787,项目名称:ralink_sdk,代码行数:33,代码来源:ipt_ECN.c
示例5: udpencap_insert_header
static bool udpencap_insert_header(struct sk_buff *skb, const struct xt_udpencap_tginfo *info)
{
struct udphdr *uh;
if (!skb_make_writable(&skb, skb_transport_offset(skb)))
return false;
if (skb->len + sizeof(struct udphdr) > 65535)
return false;
if (skb_cow(skb, sizeof(struct udphdr) + LL_RESERVED_SPACE(skb_dst(skb)->dev)))
return false;
memmove(skb->data - sizeof(struct udphdr), skb->data, skb_transport_offset(skb));
__skb_push(skb, sizeof(struct udphdr));
skb->network_header -= sizeof(struct udphdr);
skb->transport_header -= sizeof(struct udphdr);
uh = udp_hdr(skb);
uh->source = info->sport;
uh->dest = info->dport;
uh->len = htons(skb->len - skb_transport_offset(skb));
uh->check = 0;
return true;
}
开发者ID:MRchildNEO,项目名称:scholarzhang,代码行数:25,代码来源:xt_UDPENCAP.c
示例6: hl_tg6
static unsigned int
hl_tg6(struct sk_buff *skb, const struct xt_action_param *par)
{
struct ipv6hdr *ip6h;
const struct ip6t_HL_info *info = par->targinfo;
int new_hl;
if (!skb_make_writable(skb, skb->len))
return NF_DROP;
ip6h = ipv6_hdr(skb);
switch (info->mode) {
case IP6T_HL_SET:
new_hl = info->hop_limit;
break;
case IP6T_HL_INC:
new_hl = ip6h->hop_limit + info->hop_limit;
if (new_hl > 255)
new_hl = 255;
break;
case IP6T_HL_DEC:
new_hl = ip6h->hop_limit - info->hop_limit;
if (new_hl < 0)
new_hl = 0;
break;
default:
new_hl = ip6h->hop_limit;
break;
}
ip6h->hop_limit = new_hl;
return XT_CONTINUE;
}
开发者ID:AlexShiLucky,项目名称:linux,代码行数:35,代码来源:xt_HL.c
示例7: target
static unsigned int
target(struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo,
void *userinfo)
{
const struct ipt_tos_target_info *tosinfo = targinfo;
if (((*pskb)->nh.iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
u_int16_t diffs[2];
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
return NF_DROP;
diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
(*pskb)->nh.iph->tos
= ((*pskb)->nh.iph->tos & IPTOS_PREC_MASK)
| tosinfo->tos;
diffs[1] = htons((*pskb)->nh.iph->tos);
(*pskb)->nh.iph->check
= csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
(*pskb)->nh.iph->check
^0xFFFF));
}
return IPT_CONTINUE;
}
开发者ID:OSLL,项目名称:ns3psm,代码行数:30,代码来源:ipt_TOS.c
示例8: ebt_snat_tg
static unsigned int
ebt_snat_tg(struct sk_buff *skb, const struct xt_action_param *par) {
const struct ebt_nat_info *info = par->targinfo;
if (!skb_make_writable(skb, 0)) {
return EBT_DROP;
}
memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
if (!(info->target & NAT_ARP_BIT) &&
eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
const struct arphdr *ap;
struct arphdr _ah;
ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
if (ap == NULL) {
return EBT_DROP;
}
if (ap->ar_hln != ETH_ALEN) {
goto out;
}
if (skb_store_bits(skb, sizeof(_ah), info->mac,ETH_ALEN)) {
return EBT_DROP;
}
}
out:
return info->target | ~EBT_VERDICT_BITS;
}
开发者ID:tidatida,项目名称:lagopus,代码行数:28,代码来源:ebt_snat.c
示例9: gre_manip_pkt
static bool
gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
const struct gre_hdr *greh;
struct gre_hdr_pptp *pgreh;
const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
unsigned int hdroff = iphdroff + iph->ihl * 4;
if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8))
return false;
greh = (void *)skb->data + hdroff;
pgreh = (struct gre_hdr_pptp *)greh;
if (maniptype != NF_NAT_MANIP_DST)
return true;
switch (greh->version) {
case GRE_VERSION_1701:
break;
case GRE_VERSION_PPTP:
pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
pgreh->call_id = tuple->dst.u.gre.key;
break;
default:
pr_debug("can't nat unknown GRE version\n");
return false;
}
return true;
}
开发者ID:Albinoman887,项目名称:pyramid-3.4.10,代码行数:31,代码来源:nf_nat_proto_gre.c
示例10: nf_nat_ipv6_manip_pkt
static bool nf_nat_ipv6_manip_pkt(struct sk_buff *skb,
unsigned int iphdroff,
const struct nf_nat_l4proto *l4proto,
const struct nf_conntrack_tuple *target,
enum nf_nat_manip_type maniptype)
{
struct ipv6hdr *ipv6h;
__be16 frag_off;
int hdroff;
u8 nexthdr;
if (!skb_make_writable(skb, iphdroff + sizeof(*ipv6h)))
return false;
ipv6h = (void *)skb->data + iphdroff;
nexthdr = ipv6h->nexthdr;
hdroff = ipv6_skip_exthdr(skb, iphdroff + sizeof(*ipv6h),
&nexthdr, &frag_off);
if (hdroff < 0)
goto manip_addr;
if ((frag_off & htons(~0x7)) == 0 &&
!l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff,
target, maniptype))
return false;
manip_addr:
if (maniptype == NF_NAT_MANIP_SRC)
ipv6h->saddr = target->src.u3.in6;
else
ipv6h->daddr = target->dst.u3.in6;
return true;
}
开发者ID:383530895,项目名称:linux,代码行数:33,代码来源:nf_nat_l3proto_ipv6.c
示例11: sctp_manip_pkt
static bool
sctp_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
sctp_sctphdr_t *hdr;
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
return false;
hdr = (struct sctphdr *)(skb->data + hdroff);
if (maniptype == NF_NAT_MANIP_SRC) {
/* Get rid of src port */
hdr->source = tuple->src.u.sctp.port;
} else {
/* Get rid of dst port */
hdr->dest = tuple->dst.u.sctp.port;
}
hdr->checksum = sctp_compute_cksum(skb, hdroff);
return true;
}
开发者ID:mikuhatsune001,项目名称:linux2.6.32,代码行数:26,代码来源:nf_nat_proto_sctp.c
示例12: set_ect_tcp
/* Return false if there was an error. */
static inline bool
set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
{
struct tcphdr _tcph, *tcph;
__be16 oldval;
/* Not enought header? */
tcph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
if (!tcph)
return false;
if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) ||
tcph->ece == einfo->proto.tcp.ece) &&
(!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
tcph->cwr == einfo->proto.tcp.cwr))
return true;
if (!skb_make_writable(skb, ip_hdrlen(skb) + sizeof(*tcph)))
return false;
tcph = (void *)ip_hdr(skb) + ip_hdrlen(skb);
oldval = ((__be16 *)tcph)[6];
if (einfo->operation & IPT_ECN_OP_SET_ECE)
tcph->ece = einfo->proto.tcp.ece;
if (einfo->operation & IPT_ECN_OP_SET_CWR)
tcph->cwr = einfo->proto.tcp.cwr;
nf_proto_csum_replace2(&tcph->check, skb,
oldval, ((__be16 *)tcph)[6], 0);
return true;
}
开发者ID:dycforever,项目名称:sourceReading,代码行数:32,代码来源:ipt_ECN.c
示例13: udplite_manip_pkt
static bool
udplite_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
struct udphdr *hdr;
__be16 *portptr, newport;
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
return false;
hdr = (struct udphdr *)(skb->data + hdroff);
if (maniptype == NF_NAT_MANIP_SRC) {
/* Get rid of source port */
newport = tuple->src.u.udp.port;
portptr = &hdr->source;
} else {
/* Get rid of dst port */
newport = tuple->dst.u.udp.port;
portptr = &hdr->dest;
}
l3proto->csum_update(skb, iphdroff, &hdr->check, tuple, maniptype);
inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport, false);
if (!hdr->check)
hdr->check = CSUM_MANGLED_0;
*portptr = newport;
return true;
}
开发者ID:Ayokunle,项目名称:linux,代码行数:33,代码来源:nf_nat_proto_udplite.c
示例14: nf_nat_mangle_udp_packet
/* Generic function for mangling variable-length address changes inside
* NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
* command in the Amanda protocol)
*
* Takes care about all the nasty sequence number changes, checksumming,
* skb enlargement, ...
*
* XXX - This function could be merged with nf_nat_mangle_tcp_packet which
* should be fairly easy to do.
*/
int
nf_nat_mangle_udp_packet(struct sk_buff **pskb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
unsigned int match_len,
const char *rep_buffer,
unsigned int rep_len)
{
struct iphdr *iph;
struct udphdr *udph;
int datalen, oldlen;
/* UDP helpers might accidentally mangle the wrong packet */
iph = (*pskb)->nh.iph;
if ((*pskb)->len < iph->ihl*4 + sizeof(*udph) +
match_offset + match_len)
return 0;
if (!skb_make_writable(pskb, (*pskb)->len))
return 0;
if (rep_len > match_len &&
rep_len - match_len > skb_tailroom(*pskb) &&
!enlarge_skb(pskb, rep_len - match_len))
return 0;
iph = (*pskb)->nh.iph;
udph = (void *)iph + iph->ihl*4;
oldlen = (*pskb)->len - iph->ihl*4;
mangle_contents(*pskb, iph->ihl*4 + sizeof(*udph),
match_offset, match_len, rep_buffer, rep_len);
/* update the length of the UDP packet */
datalen = (*pskb)->len - iph->ihl*4;
udph->len = htons(datalen);
/* fix udp checksum if udp checksum was previously calculated */
if (!udph->check && (*pskb)->ip_summed != CHECKSUM_PARTIAL)
return 1;
if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
udph->check = 0;
udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
datalen, IPPROTO_UDP,
csum_partial((char *)udph,
datalen, 0));
if (!udph->check)
udph->check = CSUM_MANGLED_0;
} else
nf_proto_csum_replace2(&udph->check, *pskb,
htons(oldlen), htons(datalen), 1);
return 1;
}
开发者ID:StephenMacras,项目名称:dsl-n55u-bender,代码行数:66,代码来源:nf_nat_helper.c
示例15: synproxy_tstamp_adjust
unsigned int synproxy_tstamp_adjust(struct sk_buff *skb,
unsigned int protoff,
struct tcphdr *th,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
const struct nf_conn_synproxy *synproxy)
{
unsigned int optoff, optend;
u32 *ptr, old;
if (synproxy->tsoff == 0)
return 1;
optoff = protoff + sizeof(struct tcphdr);
optend = protoff + th->doff * 4;
if (!skb_make_writable(skb, optend))
return 0;
while (optoff < optend) {
unsigned char *op = skb->data + optoff;
switch (op[0]) {
case TCPOPT_EOL:
return 1;
case TCPOPT_NOP:
optoff++;
continue;
default:
if (optoff + 1 == optend ||
optoff + op[1] > optend ||
op[1] < 2)
return 0;
if (op[0] == TCPOPT_TIMESTAMP &&
op[1] == TCPOLEN_TIMESTAMP) {
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
ptr = (u32 *)&op[2];
old = *ptr;
*ptr = htonl(ntohl(*ptr) -
synproxy->tsoff);
} else {
ptr = (u32 *)&op[6];
old = *ptr;
*ptr = htonl(ntohl(*ptr) +
synproxy->tsoff);
}
inet_proto_csum_replace4(&th->check, skb,
old, *ptr, 0);
return 1;
}
optoff += op[1];
}
}
return 1;
}
开发者ID:BozkurTR,项目名称:kernel,代码行数:55,代码来源:nf_synproxy_core.c
示例16: clear_ecn
//Clear ECN marking
inline void clear_ecn(struct sk_buff *skb)
{
struct iphdr *iph=ip_hdr(skb);
if(likely(iph!=NULL))
{
if(skb_make_writable(skb, sizeof(struct iphdr)))
{
ipv4_change_dsfield(iph, 0xff, iph->tos & ~0x3);
}
}
}
开发者ID:baiwei0427,项目名称:PIAS,代码行数:12,代码来源:network.c
示例17: ebt_dnat_tg
static unsigned int
ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct ebt_nat_info *info = par->targinfo;
if (!skb_make_writable(skb, 0))
return EBT_DROP;
memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
return info->target;
}
开发者ID:CSCLOG,项目名称:beaglebone,代码行数:11,代码来源:ebt_dnat.c
示例18: tse6_seq_adjust
int tse6_seq_adjust(struct sk_buff **pskb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
struct tcphdr *tcph;
int dir;
int protoff = 0;
__be32 newseq, newack;
u8 pnum = (*pskb)->nh.ipv6h->nexthdr;
struct nf_conn_nat *nat = &ct->nat;
struct nf_nat_seq *this_way, *other_way;
dir = CTINFO2DIR(ctinfo);
this_way = &nat->info.seq[dir];
other_way = &nat->info.seq[!dir];
protoff = tse6_skip_exthdr(*pskb, sizeof(struct ipv6hdr), &pnum, (*pskb)->len - sizeof(struct ipv6hdr));
if ((protoff < 0) || (protoff > (*pskb)->len) || (pnum != IPPROTO_TCP)) {
return -NF_ACCEPT;
}
tcph = (void *)(*pskb)->nh.ipv6h + protoff;
if (!skb_make_writable(pskb, protoff+sizeof(*tcph)))
return 0;
tcph = (void *)(*pskb)->data + protoff;
if (after(ntohl(tcph->seq), this_way->correction_pos))
newseq = htonl(ntohl(tcph->seq) + this_way->offset_after);
else
newseq = htonl(ntohl(tcph->seq) + this_way->offset_before);
if (after(ntohl(tcph->ack_seq) - other_way->offset_before,
other_way->correction_pos))
newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_after);
else
newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
tcph->seq = newseq;
tcph->ack_seq = newack;
if (!tse6_sack_adjust(pskb, tcph, ct, ctinfo, protoff)) {
return 0;
}
nf_conntrack_tcp_update(*pskb, protoff, ct, dir);
return 1;
}
开发者ID:millken,项目名称:zhuxianB30,代码行数:53,代码来源:tsession6_chain.c
示例19: ebt_target_dnat
static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
struct ebt_nat_info *info = (struct ebt_nat_info *)data;
if (!skb_make_writable(skb, 0))
return EBT_DROP;
memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
return info->target;
}
开发者ID:IgnasD,项目名称:Tomato-RAF,代码行数:12,代码来源:ebt_dnat.c
示例20: nf_nat_mangle_tcp_packet
/* Generic function for mangling variable-length address changes inside
* NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX
* command in FTP).
*
* Takes care about all the nasty sequence number changes, checksumming,
* skb enlargement, ...
*
* */
int
nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
unsigned int match_len,
const char *rep_buffer,
unsigned int rep_len)
{
struct iphdr *iph;
struct tcphdr *tcph;
int oldlen, datalen;
if (!skb_make_writable(pskb, (*pskb)->len))
return 0;
if (rep_len > match_len &&
rep_len - match_len > skb_tailroom(*pskb) &&
!enlarge_skb(pskb, rep_len - match_len))
return 0;
SKB_LINEAR_ASSERT(*pskb);
iph = (*pskb)->nh.iph;
tcph = (void *)iph + iph->ihl*4;
oldlen = (*pskb)->len - iph->ihl*4;
mangle_contents(*pskb, iph->ihl*4 + tcph->doff*4,
match_offset, match_len, rep_buffer, rep_len);
datalen = (*pskb)->len - iph->ihl*4;
if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
tcph->check = 0;
tcph->check = tcp_v4_check(datalen,
iph->saddr, iph->daddr,
csum_partial((char *)tcph,
datalen, 0));
} else
nf_proto_csum_replace2(&tcph->check, *pskb,
htons(oldlen), htons(datalen), 1);
if (rep_len != match_len) {
set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
adjust_tcp_sequence(ntohl(tcph->seq),
(int)rep_len - (int)match_len,
ct, ctinfo);
/* Tell TCP window tracking about seq change */
nf_conntrack_tcp_update(*pskb, (*pskb)->nh.iph->ihl*4,
ct, CTINFO2DIR(ctinfo));
}
return 1;
}
开发者ID:StephenMacras,项目名称:dsl-n55u-bender,代码行数:60,代码来源:nf_nat_helper.c
注:本文中的skb_make_writable函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论