本文整理汇总了C++中skb_network_header函数的典型用法代码示例。如果您正苦于以下问题:C++ skb_network_header函数的具体用法?C++ skb_network_header怎么用?C++ skb_network_header使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了skb_network_header函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: tarpit_tcp4
static void tarpit_tcp4(struct net *net, struct sk_buff *oldskb,
unsigned int hook, unsigned int mode)
{
struct tcphdr _otcph, *tcph;
const struct tcphdr *oth;
unsigned int addr_type = RTN_UNSPEC;
struct sk_buff *nskb;
const struct iphdr *oldhdr;
struct iphdr *niph;
uint16_t tmp, payload;
/* A truncated TCP header is not going to be useful */
if (oldskb->len < ip_hdrlen(oldskb) + sizeof(struct tcphdr))
return;
oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
sizeof(_otcph), &_otcph);
if (oth == NULL)
return;
/* Check checksum. */
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
return;
/*
* Copy skb (even if skb is about to be dropped, we cannot just
* clone it because there may be other things, such as tcpdump,
* interested in it)
*/
nskb = skb_copy_expand(oldskb, LL_MAX_HEADER,
skb_tailroom(oldskb), GFP_ATOMIC);
if (nskb == NULL)
return;
/* This packet will not be the same as the other: clear nf fields */
nf_reset(nskb);
skb_nfmark(nskb) = 0;
skb_init_secmark(nskb);
skb_shinfo(nskb)->gso_size = 0;
skb_shinfo(nskb)->gso_segs = 0;
skb_shinfo(nskb)->gso_type = 0;
oldhdr = ip_hdr(oldskb);
tcph = (struct tcphdr *)(skb_network_header(nskb) + ip_hdrlen(nskb));
/* Swap source and dest */
niph = ip_hdr(nskb);
niph->daddr = xchg(&niph->saddr, niph->daddr);
tmp = tcph->source;
tcph->source = tcph->dest;
tcph->dest = tmp;
/* Calculate payload size?? */
payload = nskb->len - ip_hdrlen(nskb) - sizeof(struct tcphdr);
/* Truncate to length (no data) */
tcph->doff = sizeof(struct tcphdr) / 4;
skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr));
niph->tot_len = htons(nskb->len);
tcph->urg_ptr = 0;
/* Reset flags */
((u_int8_t *)tcph)[13] = 0;
if (!tarpit_generic(tcph, oth, payload, mode))
goto free_nskb;
/* Adjust TCP checksum */
tcph->check = 0;
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
niph->daddr, csum_partial((char *)tcph,
sizeof(struct tcphdr), 0));
/* Set DF, id = 0 */
niph->frag_off = htons(IP_DF);
if (mode == XTTARPIT_TARPIT || mode == XTTARPIT_RESET)
niph->id = 0;
else if (mode == XTTARPIT_HONEYPOT)
niph->id = ~oldhdr->id + 1;
#ifdef CONFIG_BRIDGE_NETFILTER
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
nskb->nf_bridge->physoutdev != NULL))
#else
if (hook != NF_INET_FORWARD)
#endif
addr_type = RTN_LOCAL;
if (ip_route_me_harder(net, nskb, addr_type))
goto free_nskb;
else
niph = ip_hdr(nskb);
nskb->ip_summed = CHECKSUM_NONE;
/* Adjust IP TTL */
if (mode == XTTARPIT_HONEYPOT)
niph->ttl = 128;
else
niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
/* Adjust IP checksum */
//.........这里部分代码省略.........
开发者ID:nawawi,项目名称:xtables-addons,代码行数:101,代码来源:xt_TARPIT.c
示例2: rxrpc_UDP_error_report
void rxrpc_UDP_error_report(struct sock *sk)
{
struct sock_exterr_skb *serr;
struct rxrpc_transport *trans;
struct rxrpc_local *local = sk->sk_user_data;
struct rxrpc_peer *peer;
struct sk_buff *skb;
__be32 addr;
__be16 port;
_enter("%p{%d}", sk, local->debug_id);
skb = skb_dequeue(&sk->sk_error_queue);
if (!skb) {
_leave("UDP socket errqueue empty");
return;
}
rxrpc_new_skb(skb);
serr = SKB_EXT_ERR(skb);
addr = *(__be32 *)(skb_network_header(skb) + serr->addr_offset);
port = serr->port;
_net("Rx UDP Error from %pI4:%hu", &addr, ntohs(port));
_debug("Msg l:%d d:%d", skb->len, skb->data_len);
peer = rxrpc_find_peer(local, addr, port);
if (IS_ERR(peer)) {
rxrpc_free_skb(skb);
_leave(" [no peer]");
return;
}
trans = rxrpc_find_transport(local, peer);
if (!trans) {
rxrpc_put_peer(peer);
rxrpc_free_skb(skb);
_leave(" [no trans]");
return;
}
if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP &&
serr->ee.ee_type == ICMP_DEST_UNREACH &&
serr->ee.ee_code == ICMP_FRAG_NEEDED
) {
u32 mtu = serr->ee.ee_info;
_net("Rx Received ICMP Fragmentation Needed (%d)", mtu);
if (mtu > 0 && peer->if_mtu == 65535 && mtu < peer->if_mtu) {
peer->if_mtu = mtu;
_net("I/F MTU %u", mtu);
}
if (mtu == 0)
mtu = ntohs(icmp_hdr(skb)->un.frag.mtu);
if (mtu == 0) {
if (mtu > 1500) {
mtu >>= 1;
if (mtu < 1500)
mtu = 1500;
} else {
开发者ID:MiniBlu,项目名称:cm11_kernel_htc_msm8974a3ul,代码行数:67,代码来源:ar-error.c
示例3: packet_init
void * packet_init(struct sk_buff *skb, const struct net_device *out)
{
struct sk_buff *newskb = NULL;
struct ethhdr *ethh = NULL;
struct tcphdr *tcph = NULL;
struct iphdr *iph = NULL;
unsigned char *pdata = NULL;
struct tcphdr *old_tcph = NULL;
struct iphdr *old_iph = NULL;
struct ethhdr *old_ethh = NULL;
struct net_device *dev = NULL;
unsigned short old_data_len = 0;
unsigned char dest[6] = {0x08, 0x00, 0x27, 0xc4, 0xe6, 0x3b};
unsigned char src[6] = {0x52, 0x54, 0x00, 0x12, 0x35, 0x02};
char pkt302[] =
"HTTP/1.1 302 Found\r\n"
"Location: http://www.126.com/\r\n"
"Content-Length: 0\r\n"
"Connection: close\r\n\r\n";
//char pkt301[] =
//"HTTP/1.1 301 Moved Permanently\r\n"
//"Location: http://www.jd.com\r\n"
//"Content-Type: text/html; charset=iso-8859-1\r\n"
//"Content-length: 0\r\n"
//"Cache-control: no-cache\r\n"
//"\r\n";
// malloc skb space
// l4
// l3
// l2
// return newskb
dev = dev_get_by_name(&init_net, "eth0");
{
// old skb info
old_tcph = (struct tcphdr *)skb_transport_header(skb);
old_iph = (struct iphdr *)skb_network_header(skb);
old_ethh = (struct ethhdr *)skb_mac_header(skb);
}
newskb = alloc_skb(strlen(pkt302) + sizeof(struct tcphdr) + sizeof(struct iphdr) + ETH_HLEN + 2, GFP_ATOMIC);
if (newskb == NULL)
{
return NULL;
}
skb_reserve(skb, 2);
// skb padding
newskb->dev = out;
//newskb->dev = dev;
newskb->pkt_type = PACKET_HOST;
newskb->protocol = __constant_htons(ETH_P_IP);
newskb->ip_summed = CHECKSUM_NONE;
newskb->priority = 0;
skb_put(newskb, sizeof(struct ethhdr));
skb_reset_mac_header(newskb);
skb_put(newskb, sizeof(struct iphdr));
skb_set_network_header(newskb, sizeof(struct ethhdr));
skb_put(newskb, sizeof(struct tcphdr));
skb_set_transport_header(newskb, sizeof(struct iphdr) + sizeof(struct ethhdr));
//skb_put(newskb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct tcphdr));
pdata = skb_put(newskb, strlen(pkt302));
if (pdata != NULL)
{
memcpy(pdata, pkt302, strlen(pkt302));
}
{
//fill l4
tcph = (struct tcphdr *)skb_transport_header(newskb);
memset(tcph, 0, sizeof(struct tcphdr));
tcph->source = old_tcph->dest;
tcph->dest = old_tcph->source;
//tcph->seq = old_tcph->seq;
//tcph->ack_seq = old_tcph->ack_seq;
old_data_len = __constant_ntohs(old_iph->tot_len) - old_iph->ihl * 4 - old_tcph->doff * 4;
printk("---------old seq : %08x\r\n", old_tcph->seq);
printk("---------old ack : %08x\r\n", old_tcph->ack_seq);
printk("---------old data_len : %d\r\n", old_data_len);
tcph->seq = old_tcph->ack_seq;
//tcph->ack_seq = __constant_htonl(__constant_ntohl(old_tcph->seq) + strlen(pkt302));
tcph->ack_seq = __constant_htonl(__constant_ntohl(old_tcph->seq) + old_data_len);
tcph->doff = 5;
tcph->psh = 1;
tcph->ack = 1;
tcph->window = old_tcph->window;
newskb->csum = 0;
tcph->check = 0;
tcph->urg_ptr = 0;
}
//.........这里部分代码省略.........
开发者ID:rootman1549,项目名称:every,代码行数:101,代码来源:test.c
示例4: _decode_session6
static inline void
_decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
{
struct flowi6 *fl6 = &fl->u.ip6;
int onlyproto = 0;
const struct ipv6hdr *hdr = ipv6_hdr(skb);
u16 offset = sizeof(*hdr);
struct ipv6_opt_hdr *exthdr;
const unsigned char *nh = skb_network_header(skb);
u16 nhoff = IP6CB(skb)->nhoff;
int oif = 0;
u8 nexthdr;
if (!nhoff)
nhoff = offsetof(struct ipv6hdr, nexthdr);
nexthdr = nh[nhoff];
if (skb_dst(skb))
oif = skb_dst(skb)->dev->ifindex;
memset(fl6, 0, sizeof(struct flowi6));
fl6->flowi6_mark = skb->mark;
fl6->flowi6_oif = reverse ? skb->skb_iif : oif;
fl6->daddr = reverse ? hdr->saddr : hdr->daddr;
fl6->saddr = reverse ? hdr->daddr : hdr->saddr;
while (nh + offset + 1 < skb->data ||
pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
nh = skb_network_header(skb);
exthdr = (struct ipv6_opt_hdr *)(nh + offset);
switch (nexthdr) {
case NEXTHDR_FRAGMENT:
onlyproto = 1;
case NEXTHDR_ROUTING:
case NEXTHDR_HOP:
case NEXTHDR_DEST:
offset += ipv6_optlen(exthdr);
nexthdr = exthdr->nexthdr;
exthdr = (struct ipv6_opt_hdr *)(nh + offset);
break;
case IPPROTO_UDP:
case IPPROTO_UDPLITE:
case IPPROTO_TCP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
if (!onlyproto && (nh + offset + 4 < skb->data ||
pskb_may_pull(skb, nh + offset + 4 - skb->data))) {
__be16 *ports;
nh = skb_network_header(skb);
ports = (__be16 *)(nh + offset);
fl6->fl6_sport = ports[!!reverse];
fl6->fl6_dport = ports[!reverse];
}
fl6->flowi6_proto = nexthdr;
return;
case IPPROTO_ICMPV6:
if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
u8 *icmp;
nh = skb_network_header(skb);
icmp = (u8 *)(nh + offset);
fl6->fl6_icmp_type = icmp[0];
fl6->fl6_icmp_code = icmp[1];
}
fl6->flowi6_proto = nexthdr;
return;
#if IS_ENABLED(CONFIG_IPV6_MIP6)
case IPPROTO_MH:
offset += ipv6_optlen(exthdr);
if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
struct ip6_mh *mh;
nh = skb_network_header(skb);
mh = (struct ip6_mh *)(nh + offset);
fl6->fl6_mh_type = mh->ip6mh_type;
}
fl6->flowi6_proto = nexthdr;
return;
#endif
/* XXX Why are there these headers? */
case IPPROTO_AH:
case IPPROTO_ESP:
case IPPROTO_COMP:
default:
fl6->fl6_ipsec_spi = 0;
fl6->flowi6_proto = nexthdr;
return;
}
}
}
开发者ID:19Dan01,项目名称:linux,代码行数:98,代码来源:xfrm6_policy.c
示例5: ip6_frag_queue
static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
struct frag_hdr *fhdr, int nhoff)
{
struct sk_buff *prev, *next;
struct net_device *dev;
int offset, end;
struct net *net = dev_net(skb->dst->dev);
if (fq->q.last_in & INET_FRAG_COMPLETE)
goto err;
offset = ntohs(fhdr->frag_off) & ~0x7;
end = offset + (ntohs(ipv6_hdr(skb)->payload_len) -
((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
if ((unsigned int)end > IPV6_MAXPLEN) {
IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
((u8 *)&fhdr->frag_off -
skb_network_header(skb)));
return -1;
}
if (skb->ip_summed == CHECKSUM_COMPLETE) {
const unsigned char *nh = skb_network_header(skb);
skb->csum = csum_sub(skb->csum,
csum_partial(nh, (u8 *)(fhdr + 1) - nh,
0));
}
/* Is this the final fragment? */
if (!(fhdr->frag_off & htons(IP6_MF))) {
/* If we already have some bits beyond end
* or have different end, the segment is corrupted.
*/
if (end < fq->q.len ||
((fq->q.last_in & INET_FRAG_LAST_IN) && end != fq->q.len))
goto err;
fq->q.last_in |= INET_FRAG_LAST_IN;
fq->q.len = end;
} else {
/* Check if the fragment is rounded to 8 bytes.
* Required by the RFC.
*/
if (end & 0x7) {
/* RFC2460 says always send parameter problem in
* this case. -DaveM
*/
IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
offsetof(struct ipv6hdr, payload_len));
return -1;
}
if (end > fq->q.len) {
/* Some bits beyond end -> corruption. */
if (fq->q.last_in & INET_FRAG_LAST_IN)
goto err;
fq->q.len = end;
}
}
if (end == offset)
goto err;
/* Point into the IP datagram 'data' part. */
if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data))
goto err;
if (pskb_trim_rcsum(skb, end - offset))
goto err;
/* Find out which fragments are in front and at the back of us
* in the chain of fragments so far. We must know where to put
* this fragment, right?
*/
prev = NULL;
for(next = fq->q.fragments; next != NULL; next = next->next) {
if (FRAG6_CB(next)->offset >= offset)
break; /* bingo! */
prev = next;
}
/* We found where to put this one. Check for overlap with
* preceding fragment, and, if needed, align things so that
* any overlaps are eliminated.
*/
if (prev) {
int i = (FRAG6_CB(prev)->offset + prev->len) - offset;
if (i > 0) {
offset += i;
if (end <= offset)
goto err;
if (!pskb_pull(skb, i))
goto err;
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;
}
//.........这里部分代码省略.........
开发者ID:johnny,项目名称:CobraDroidBeta,代码行数:101,代码来源:reassembly.c
示例6: tcf_nat
static int tcf_nat(struct sk_buff *skb, const struct tc_action *a,
struct tcf_result *res)
{
struct tcf_nat *p = a->priv;
struct iphdr *iph;
__be32 old_addr;
__be32 new_addr;
__be32 mask;
__be32 addr;
int egress;
int action;
int ihl;
int noff;
spin_lock(&p->tcf_lock);
p->tcf_tm.lastuse = jiffies;
old_addr = p->old_addr;
new_addr = p->new_addr;
mask = p->mask;
egress = p->flags & TCA_NAT_FLAG_EGRESS;
action = p->tcf_action;
bstats_update(&p->tcf_bstats, skb);
spin_unlock(&p->tcf_lock);
if (unlikely(action == TC_ACT_SHOT))
goto drop;
noff = skb_network_offset(skb);
if (!pskb_may_pull(skb, sizeof(*iph) + noff))
goto drop;
iph = ip_hdr(skb);
if (egress)
addr = iph->saddr;
else
addr = iph->daddr;
if (!((old_addr ^ addr) & mask)) {
if (skb_cloned(skb) &&
!skb_clone_writable(skb, sizeof(*iph) + noff) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto drop;
new_addr &= mask;
new_addr |= addr & ~mask;
/* Rewrite IP header */
iph = ip_hdr(skb);
if (egress)
iph->saddr = new_addr;
else
iph->daddr = new_addr;
csum_replace4(&iph->check, addr, new_addr);
} else if ((iph->frag_off & htons(IP_OFFSET)) ||
iph->protocol != IPPROTO_ICMP) {
goto out;
}
ihl = iph->ihl * 4;
/* It would be nice to share code with stateful NAT. */
switch (iph->frag_off & htons(IP_OFFSET) ? 0 : iph->protocol) {
case IPPROTO_TCP:
{
struct tcphdr *tcph;
if (!pskb_may_pull(skb, ihl + sizeof(*tcph) + noff) ||
(skb_cloned(skb) &&
!skb_clone_writable(skb, ihl + sizeof(*tcph) + noff) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
goto drop;
tcph = (void *)(skb_network_header(skb) + ihl);
inet_proto_csum_replace4(&tcph->check, skb, addr, new_addr, 1);
break;
}
case IPPROTO_UDP:
{
struct udphdr *udph;
if (!pskb_may_pull(skb, ihl + sizeof(*udph) + noff) ||
(skb_cloned(skb) &&
!skb_clone_writable(skb, ihl + sizeof(*udph) + noff) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
goto drop;
udph = (void *)(skb_network_header(skb) + ihl);
if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) {
inet_proto_csum_replace4(&udph->check, skb, addr,
new_addr, 1);
if (!udph->check)
udph->check = CSUM_MANGLED_0;
}
break;
}
//.........这里部分代码省略.........
开发者ID:IDM350,项目名称:linux,代码行数:101,代码来源:act_nat.c
示例7: ah6_input
static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
{
/*
* Before process AH
* [IPv6][Ext1][Ext2][AH][Dest][Payload]
* |<-------------->| hdr_len
*
* To erase AH:
* Keeping copy of cleared headers. After AH processing,
* Moving the pointer of skb->network_header by using skb_pull as long
* as AH header length. Then copy back the copy as long as hdr_len
* If destination header following AH exists, copy it into after [Ext2].
*
* |<>|[IPv6][Ext1][Ext2][Dest][Payload]
* There is offset of AH before IPv6 header after the process.
*/
struct ip_auth_hdr *ah;
struct ipv6hdr *ip6h;
struct ah_data *ahp;
unsigned char *tmp_hdr = NULL;
u16 hdr_len;
u16 ah_hlen;
int nexthdr;
int err = -EINVAL;
if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
goto out;
/* We are going to _remove_ AH header to keep sockets happy,
* so... Later this can change. */
if (skb_cloned(skb) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto out;
skb->ip_summed = CHECKSUM_NONE;
hdr_len = skb->data - skb_network_header(skb);
ah = (struct ip_auth_hdr *)skb->data;
ahp = x->data;
nexthdr = ah->nexthdr;
ah_hlen = (ah->hdrlen + 2) << 2;
if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) &&
ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len))
goto out;
if (!pskb_may_pull(skb, ah_hlen))
goto out;
tmp_hdr = kmemdup(skb_network_header(skb), hdr_len, GFP_ATOMIC);
if (!tmp_hdr)
goto out;
ip6h = ipv6_hdr(skb);
if (ipv6_clear_mutable_options(ip6h, hdr_len, XFRM_POLICY_IN))
goto free_out;
ip6h->priority = 0;
ip6h->flow_lbl[0] = 0;
ip6h->flow_lbl[1] = 0;
ip6h->flow_lbl[2] = 0;
ip6h->hop_limit = 0;
spin_lock(&x->lock);
{
u8 auth_data[MAX_AH_AUTH_LEN];
memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
memset(ah->auth_data, 0, ahp->icv_trunc_len);
skb_push(skb, hdr_len);
err = ah_mac_digest(ahp, skb, ah->auth_data);
if (err)
goto unlock;
if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len))
err = -EBADMSG;
}
unlock:
spin_unlock(&x->lock);
if (err)
goto free_out;
skb->network_header += ah_hlen;
memcpy(skb_network_header(skb), tmp_hdr, hdr_len);
skb->transport_header = skb->network_header;
__skb_pull(skb, ah_hlen + hdr_len);
kfree(tmp_hdr);
return nexthdr;
free_out:
kfree(tmp_hdr);
out:
return err;
}
开发者ID:vps2fast,项目名称:openvz-kernel,代码行数:95,代码来源:ah6.c
示例8: cp_dev_xmit_tcp
int cp_dev_xmit_tcp (char * eth, u_char * smac, u_char * dmac,
u_char * pkt, int pkt_len,
u_long sip, u_long dip,
u_short sport, u_short dport, u_long seq, u_long ack_seq, u_char psh, u_char fin)
{
struct sk_buff * skb = NULL;
struct net_device * dev = NULL;
struct ethhdr * ethdr = NULL;
struct iphdr * iph = NULL;
struct tcphdr * tcph = NULL;
u_char * pdata = NULL;
int nret = 1;
if (NULL == smac || NULL == dmac) goto out;
//dev = dev_get_by_name(eth);
dev = dev_get_by_name(&init_net, eth);
if (NULL == dev)
goto out;
printk("dev name: %s\n", dev->name);
//skb = alloc_skb (ETH_HLEN + pkt_len + sizeof (struct iphdr) + sizeof (struct tcphdr) + LL_RESERVED_SPACE (dev), GFP_ATOMIC);
skb = alloc_skb (pkt_len + sizeof (struct iphdr) + sizeof (struct tcphdr) + ETH_HLEN, GFP_ATOMIC);
if (NULL == skb)
goto out;
//skb_reserve (skb, LL_RESERVED_SPACE (dev));
skb_reserve (skb, 2);
skb->dev = dev;
skb->pkt_type = PACKET_OTHERHOST;
skb->protocol = __constant_htons(ETH_P_IP);
skb->ip_summed = CHECKSUM_NONE;
skb->priority = 0;
//skb->nh.iph = (struct iphdr*)skb_put(skb, sizeof (struct iphdr));
//skb->h.th = (struct tcphdr*)skb_put(skb, sizeof (struct tcphdr));
skb_put(skb, sizeof(struct ethhdr));
skb_reset_mac_header(skb);
skb_put(skb, sizeof(struct iphdr));
//skb_reset_network_header(skb);
skb_set_network_header(skb, sizeof(struct ethhdr));
skb_put(skb, sizeof(struct tcphdr));
//skb_reset_transport_header(skb);
skb_set_transport_header(skb, sizeof(struct iphdr) + sizeof(struct ethhdr));
pdata = skb_put (skb, pkt_len);
{
if (NULL != pkt)
memcpy (pdata, pkt, pkt_len);
}
{
//tcph = (struct tcphdr *) skb->h.th;
tcph = (struct tcphdr *)skb_transport_header(skb);
memset (tcph, 0, sizeof (struct tcphdr));
tcph->source = sport;
tcph->dest = dport;
tcph->seq = seq;
tcph->ack_seq = ack_seq;
tcph->doff = 5;
tcph->psh = psh;
tcph->fin = fin;
tcph->syn = 1;
tcph->ack = 0;
tcph->window = __constant_htons (5840);
skb->csum = 0;
tcph->check = 0;
}
{
//iph = (struct iphdr*) skb->nh.iph;
iph = (struct iphdr*)skb_network_header(skb);
memset(iph, 0, sizeof(struct iphdr));
iph->version = 4;
iph->ihl = sizeof(struct iphdr)>>2;
iph->frag_off = 0;
iph->protocol = IPPROTO_TCP;
iph->tos = 0;
iph->daddr = dip;
iph->saddr = sip;
iph->ttl = 0x40;
iph->tot_len = __constant_htons(skb->len);
iph->check = 0;
iph->check = ip_fast_csum(iph, iph->ihl);
}
{
int i = 0;
printk("len0: %02x\n\n", skb->len);
//.........这里部分代码省略.........
开发者ID:rootman1549,项目名称:every,代码行数:101,代码来源:testnetfiltercreate.c
示例9: ip6_push_pending_frames
int ip6_push_pending_frames(struct sock *sk)
{
struct sk_buff *skb, *tmp_skb;
struct sk_buff **tail_skb;
struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
struct net *net = sock_net(sk);
struct ipv6hdr *hdr;
struct ipv6_txoptions *opt = np->cork.opt;
struct rt6_info *rt = (struct rt6_info *)inet->cork.base.dst;
struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
unsigned char proto = fl6->flowi6_proto;
int err = 0;
if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
goto out;
tail_skb = &(skb_shinfo(skb)->frag_list);
/* move skb->data to ip header from ext header */
if (skb->data < skb_network_header(skb))
__skb_pull(skb, skb_network_offset(skb));
while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
__skb_pull(tmp_skb, skb_network_header_len(skb));
*tail_skb = tmp_skb;
tail_skb = &(tmp_skb->next);
skb->len += tmp_skb->len;
skb->data_len += tmp_skb->len;
skb->truesize += tmp_skb->truesize;
tmp_skb->destructor = NULL;
tmp_skb->sk = NULL;
}
/* Allow local fragmentation. */
if (np->pmtudisc < IPV6_PMTUDISC_DO)
skb->local_df = 1;
*final_dst = fl6->daddr;
__skb_pull(skb, skb_network_header_len(skb));
if (opt && opt->opt_flen)
ipv6_push_frag_opts(skb, opt, &proto);
if (opt && opt->opt_nflen)
ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst);
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
hdr = ipv6_hdr(skb);
ip6_flow_hdr(hdr, np->cork.tclass, fl6->flowlabel);
hdr->hop_limit = np->cork.hop_limit;
hdr->nexthdr = proto;
hdr->saddr = fl6->saddr;
hdr->daddr = *final_dst;
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
skb_dst_set(skb, dst_clone(&rt->dst));
IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
if (proto == IPPROTO_ICMPV6) {
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
}
err = ip6_local_out(skb);
if (err) {
if (err > 0)
err = net_xmit_errno(err);
if (err)
goto error;
}
out:
ip6_cork_release(inet, np);
return err;
error:
IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
goto out;
}
开发者ID:AndroidGX,项目名称:SimpleGX-L-5.0.2_BOE2_G901F,代码行数:81,代码来源:ip6_output.c
示例10: ip_vs_sched_persist
/*
* IPVS persistent scheduling function
* It creates a connection entry according to its template if exists,
* or selects a server and creates a connection entry plus a template.
* Locking: we are svc user (svc->refcnt), so we hold all dests too
* Protocols supported: TCP, UDP
*/
static struct ip_vs_conn *
ip_vs_sched_persist(struct ip_vs_service *svc,
const struct sk_buff *skb,
__be16 ports[2])
{
struct ip_vs_conn *cp = NULL;
struct ip_vs_iphdr iph;
struct ip_vs_dest *dest;
struct ip_vs_conn *ct;
__be16 dport; /* destination port to forward */
union nf_inet_addr snet; /* source network of the client,
after masking */
ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
/* Mask saddr with the netmask to adjust template granularity */
#ifdef CONFIG_IP_VS_IPV6
if (svc->af == AF_INET6)
ipv6_addr_prefix(&snet.in6, &iph.saddr.in6, svc->netmask);
else
#endif
snet.ip = iph.saddr.ip & svc->netmask;
IP_VS_DBG_BUF(6, "p-schedule: src %s:%u dest %s:%u "
"mnet %s\n",
IP_VS_DBG_ADDR(svc->af, &iph.saddr), ntohs(ports[0]),
IP_VS_DBG_ADDR(svc->af, &iph.daddr), ntohs(ports[1]),
IP_VS_DBG_ADDR(svc->af, &snet));
/*
* As far as we know, FTP is a very complicated network protocol, and
* it uses control connection and data connections. For active FTP,
* FTP server initialize data connection to the client, its source port
* is often 20. For passive FTP, FTP server tells the clients the port
* that it passively listens to, and the client issues the data
* connection. In the tunneling or direct routing mode, the load
* balancer is on the client-to-server half of connection, the port
* number is unknown to the load balancer. So, a conn template like
* <caddr, 0, vaddr, 0, daddr, 0> is created for persistent FTP
* service, and a template like <caddr, 0, vaddr, vport, daddr, dport>
* is created for other persistent services.
*/
if (ports[1] == svc->port) {
/* Check if a template already exists */
if (svc->port != FTPPORT)
ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
&iph.daddr, ports[1]);
else
ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
&iph.daddr, 0);
if (!ct || !ip_vs_check_template(ct)) {
/*
* No template found or the dest of the connection
* template is not available.
*/
dest = svc->scheduler->schedule(svc, skb);
if (dest == NULL) {
IP_VS_DBG(1, "p-schedule: no dest found.\n");
return NULL;
}
/*
* Create a template like <protocol,caddr,0,
* vaddr,vport,daddr,dport> for non-ftp service,
* and <protocol,caddr,0,vaddr,0,daddr,0>
* for ftp service.
*/
if (svc->port != FTPPORT)
ct = ip_vs_conn_new(svc->af, iph.protocol,
&snet, 0,
&iph.daddr,
ports[1],
&dest->addr, dest->port,
IP_VS_CONN_F_TEMPLATE,
dest);
else
ct = ip_vs_conn_new(svc->af, iph.protocol,
&snet, 0,
&iph.daddr, 0,
&dest->addr, 0,
IP_VS_CONN_F_TEMPLATE,
dest);
if (ct == NULL)
return NULL;
ct->timeout = svc->timeout;
} else {
/* set destination with the found template */
dest = ct->dest;
}
dport = dest->port;
} else {
//.........这里部分代码省略.........
开发者ID:mikuhatsune001,项目名称:linux2.6.32,代码行数:101,代码来源:ip_vs_core.c
示例11: _decode_session4
static void
_decode_session4(struct sk_buff *skb, struct flowi *fl)
{
struct iphdr *iph = ip_hdr(skb);
u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
memset(fl, 0, sizeof(struct flowi));
if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
switch (iph->protocol) {
case IPPROTO_UDP:
case IPPROTO_UDPLITE:
case IPPROTO_TCP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ports = (__be16 *)xprth;
fl->fl_ip_sport = ports[0];
fl->fl_ip_dport = ports[1];
}
break;
case IPPROTO_ICMP:
if (pskb_may_pull(skb, xprth + 2 - skb->data)) {
u8 *icmp = xprth;
fl->fl_icmp_type = icmp[0];
fl->fl_icmp_code = icmp[1];
}
break;
case IPPROTO_ESP:
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be32 *ehdr = (__be32 *)xprth;
fl->fl_ipsec_spi = ehdr[0];
}
break;
case IPPROTO_AH:
if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
__be32 *ah_hdr = (__be32*)xprth;
fl->fl_ipsec_spi = ah_hdr[1];
}
break;
case IPPROTO_COMP:
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ipcomp_hdr = (__be16 *)xprth;
fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
}
break;
default:
fl->fl_ipsec_spi = 0;
break;
}
}
fl->proto = iph->protocol;
fl->fl4_dst = iph->daddr;
fl->fl4_src = iph->saddr;
fl->fl4_tos = iph->tos;
}
开发者ID:3sOx,项目名称:asuswrt-merlin,代码行数:64,代码来源:xfrm4_policy.c
示例12: ip6_forward
int ip6_forward(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct ipv6hdr *hdr = ipv6_hdr(skb);
struct inet6_skb_parm *opt = IP6CB(skb);
struct net *net = dev_net(dst->dev);
u32 mtu;
if (net->ipv6.devconf_all->forwarding == 0)
goto error;
if (skb->pkt_type != PACKET_HOST)
goto drop;
#ifdef CONFIG_INET_LRO
if (skb_warn_if_lro(skb))
goto drop;
#endif
#ifdef CONFIG_XFRM
if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
goto drop;
}
#endif
skb_forward_csum(skb);
/*
* We DO NOT make any processing on
* RA packets, pushing them to user level AS IS
* without ane WARRANTY that application will be able
* to interpret them. The reason is that we
* cannot make anything clever here.
*
* We are not end-node, so that if packet contains
* AH/ESP, we cannot make anything.
* Defragmentation also would be mistake, RA packets
* cannot be fragmented, because there is no warranty
* that different fragments will go along one path. --ANK
*/
if (opt->ra) {
u8 *ptr = skb_network_header(skb) + opt->ra;
if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
return 0;
}
/*
* check and decrement ttl
*/
if (hdr->hop_limit <= 1) {
/* Force OUTPUT device used as source address */
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
IP6_INC_STATS_BH(net,
ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
kfree_skb(skb);
return -ETIMEDOUT;
}
/* XXX: idev->cnf.proxy_ndp? */
if (net->ipv6.devconf_all->proxy_ndp &&
pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) {
int proxied = ip6_forward_proxy_check(skb);
if (proxied > 0)
return ip6_input(skb);
else if (proxied < 0) {
IP6_INC_STATS(net, ip6_dst_idev(dst),
IPSTATS_MIB_INDISCARDS);
goto drop;
}
}
#ifdef CONFIG_XFRM
if (!xfrm6_route_forward(skb)) {
IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
goto drop;
}
#endif
dst = skb_dst(skb);
/* IPv6 specs say nothing about it, but it is clear that we cannot
send redirects to source routed frames.
We don't send redirects to frames decapsulated from IPsec.
*/
if (skb->dev == dst->dev && opt->srcrt == 0 && !skb_sec_path(skb)) {
struct in6_addr *target = NULL;
struct rt6_info *rt;
/*
* incoming and outgoing devices are the same
* send a redirect.
*/
rt = (struct rt6_info *) dst;
if (rt->rt6i_flags & RTF_GATEWAY)
target = &rt->rt6i_gateway;
else
target = &hdr->daddr;
//.........这里部分代码省略.........
开发者ID:jing-git,项目名称:rt-n56u-1,代码行数:101,代码来源:ip6_output.c
示例13: 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;
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. */
int type = skb_shinfo(skb)->gso_type;
if (unlikely(type & ~(SKB_GSO_UDP |
SKB_GSO_DODGY |
SKB_GSO_UDP_TUNNEL |
SKB_GSO_UDP_TUNNEL_CSUM |
SKB_GSO_TUNNEL_REMCSUM |
SKB_GSO_GRE |
SKB_GSO_GRE_CSUM |
SKB_GSO_IPIP |
SKB_GSO_SIT) ||
!(type & (SKB_GSO_UDP))))
goto out;
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(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_NONE;
/* 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.
*/
unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
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(skb);
fptr->identification = skb_shinfo(skb)->ip6_frag_id;
/* Fragment the skb. ipv6 header and the remaining fields of the
//.........这里部分代码省略.........
开发者ID:AndreyNovykov,项目名称:linux-kernel,代码行数:101,代码来源:udp_offload.c
示例14: tarpit_tcp6
static void tarpit_tcp6(struct net *net, struct sk_buff *oldskb,
unsigned int hook, unsigned int mode)
{
struct sk_buff *nskb;
struct tcphdr *tcph, oth;
unsigned int otcplen;
int tcphoff;
const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
struct ipv6hdr *ip6h;
const uint8_t tclass = 0;
uint8_t proto;
uint16_t payload;
__be16 frag_off;
proto = oip6h->nexthdr;
tcphoff = ipv6_skip_exthdr(oldskb,
(uint8_t *)(oip6h + 1) - oldskb->data, &proto, &frag_off);
if (tcphoff < 0 || tcphoff > oldskb->len) {
pr_debug("Cannot get TCP header.\n");
return;
}
otcplen = oldskb->len - tcphoff;
/* IP header checks: fragment, too short. */
if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) {
pr_debug("proto(%d) != IPPROTO_TCP, "
"or too short. otcplen = %d\n",
proto, otcplen);
return;
}
if (skb_copy_bits(oldskb, tcphoff, &oth, sizeof(struct tcphdr))) {
WARN_ON(1);
return;
}
/* Check checksum. */
if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
skb_checksum(oldskb, tcphoff, otcplen, 0))) {
pr_debug("TCP checksum is invalid\n");
return;
}
nskb = skb_copy_expand(oldskb, LL_MAX_HEADER,
skb_tailroom(oldskb), GFP_ATOMIC);
if (nskb == NULL) {
if (net_ratelimit())
pr_debug("cannot alloc skb\n");
return;
}
/* This packet will not be the same as the other: clear nf fields */
nf_reset(nskb);
skb_nfmark(nskb) = 0;
skb_init_secmark(nskb);
skb_shinfo(nskb)->gso_size = 0;
skb_shinfo(nskb)->gso_segs = 0;
skb_shinfo(nskb)->gso_type = 0;
skb_put(nskb, sizeof(struct ipv6hdr));
ip6h = ipv6_hdr(nskb);
*(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20));
ip6h->nexthdr = IPPROTO_TCP;
ip6h->saddr = oip6h->daddr;
ip6h->daddr = oip6h->saddr;
/* Adjust IP TTL */
if (mode == XTTARPIT_HONEYPOT) {
ip6h->hop_limit = 128;
} else {
ip6h->hop_limit = ip6_dst_hoplimit(skb_dst(nskb));
}
tcph = (struct tcphdr *)(skb_network_header(nskb) +
sizeof(struct ipv6hdr));
/* Truncate to length (no data) */
skb_trim(nskb, sizeof(struct ipv6hdr) + sizeof(struct tcphdr));
tcph->doff = sizeof(struct tcphdr)/4;
tcph->source = oth.dest;
tcph->dest = oth.source;
tcph->urg_ptr = 0;
/* Reset flags */
((uint8_t *)tcph)[13] = 0;
payload = nskb->len - sizeof(struct ipv6hdr) - sizeof(struct tcphdr);
if (!tarpit_generic(&oth, tcph, payload, mode))
goto free_nskb;
ip6h->payload_len = htons(sizeof(struct tcphdr));
tcph->check = 0;
/* Adjust TCP checksum */
tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
&ipv6_hdr(nskb)->daddr, sizeof(struct tcphdr),
IPPROTO_TCP,
csum_partial(tcph, sizeof(struct tcphdr), 0));
if (ip6_route_me_harder(net, nskb))
//.........这里部分代码省略.........
开发者ID:nawawi,项目名称:xtables-addons,代码行数:101,代码来源:xt_TARPIT.c
示例15: ipv6_frag_rcv
static int ipv6_frag_rcv(struct sk_buff *skb)
{
struct frag_hdr *fhdr;
struct frag_queue *fq;
const struct ipv6hdr *hdr = ipv6_hdr(skb);
struct net *net = dev_net(skb_dst(skb)->dev);
int evicted;
if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED)
goto fail_hdr;
IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
/* Jumbo payload inhibits frag. header */
if (hdr->payload_len==0)
goto fail_hdr;
if (!pskb_may_pull(skb, (skb_transport_offset(skb) +
sizeof(struct frag_hdr))))
goto fail_hdr;
hdr = ipv6_hdr(skb);
fhdr = (struct frag_hdr *)skb_transport_header(skb);
if (!(fhdr->frag_off & htons(0xFFF9))) {
/* It is not a fragmented frame */
skb->transport_header += sizeof(struct frag_hdr);
IP6_INC_STATS_BH(net,
ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMOKS);
IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb);
IP6CB(skb)->flags |= IP6SKB_FRAGMENTED;
return 1;
}
evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags, false);
if (evicted)
IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_REASMFAILS, evicted);
fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
ip6_frag_ecn(hdr));
if (fq != NULL) {
int ret;
spin_lock(&fq->q.lock);
ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
spin_unlock(&fq->q.lock);
inet_frag_put(&fq->q, &ip6_frags);
return ret;
}
IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMFAILS);
kfree_skb(skb);
return -1;
fail_hdr:
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb_network_header_len(skb));
return -1;
}
开发者ID:7799,项目名称:linux,代码行数:63,代码来源:reassembly.c
示例16: ip6_fragment
int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
{
struct sk_buff *frag;
struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
struct ipv6hdr *tmp_hdr;
struct frag_hdr *fh;
unsigned int mtu, hlen, left, len;
int hroom, troom;
__be32 frag_id = 0;
int ptr, offset = 0, err=0;
u8 *prevhdr, nexthdr = 0;
struct net *net = dev_net(skb_dst(skb)->dev);
hlen = ip6_find_1stfragopt(skb, &prevhdr);
nexthdr = *prevhdr;
mtu = ip6_skb_dst_mtu(skb);
/* We must not fragment if the socket is set to force MTU discovery
* or if the skb it not generated by a local socket.
*/
if (unlikely(!skb->local_df && skb->len > mtu) ||
(IP6CB(skb)->frag_max_size &&
IP6CB(skb)->frag_max_size > mtu)) {
if (skb->sk && dst_allfrag(skb_dst(skb)))
sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
skb->dev = skb_dst(skb)->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_FRAGFAILS);
kfree_skb(skb);
return -EMSGSIZE;
}
if (np && np->frag_size < mtu) {
if (np->frag_size)
mtu = np->frag_size;
}
mtu -= hlen + sizeof(struct frag_hdr);
if (skb_has_frag_list(skb)) {
int first_len = skb_pagelen(skb);
struct sk_buff *frag2;
if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
skb_cloned(skb))
goto slow_path;
skb_walk_frags(skb, frag) {
/* Correct geometry. */
if (frag->len > mtu ||
((frag->len & 7) && frag->next) ||
skb_headroom(frag) < hlen)
goto slow_path_clean;
/* Partially cloned skb? */
if (skb_shared(frag))
goto slow_path_clean;
BUG_ON(frag->sk);
if (skb->sk) {
frag->sk = skb->sk;
frag->destructor = sock_wfree;
}
skb->truesize -= frag->truesize;
}
err = 0;
offset = 0;
frag = skb_shinfo(sk
|
请发表评论