static void do_buf_work(struct pppox_sock *po) { struct timeval tv1,tv2; struct sk_buff *skb; struct pptp_opt *opt=&po->proto.pptp; unsigned int t; spin_lock_bh(&opt->rcv_lock); do_gettimeofday(&tv1); while((skb=skb_dequeue(&opt->skb_buf))){ if (!__pptp_rcv(po,skb,0)){ skb_get_timestamp(skb,&tv2); t=(tv1.tv_sec-tv2.tv_sec)*1000000+(tv1.tv_usec-tv2.tv_usec); if (t<opt->stat->rtt){ skb_queue_head(&opt->skb_buf,skb); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) mod_timer(&opt->buf_timer,t/100*HZ/10000); #else schedule_delayed_work(&opt->buf_work,t/100*HZ/10000); #endif goto exit; } t=get_seq(skb)-1; opt->stat->rx_lost+=t-opt->seq_recv; opt->seq_recv=t; if (log_level>=2) printk(KERN_INFO"PPTP[%i]: unbuffer packet %i\n",opt->src_addr.call_id,t+1); __pptp_rcv(po,skb,0); } } exit: spin_unlock_bh(&opt->rcv_lock); }
static inline void mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) { struct timeval tv; if (_pms(sk)->cmask & MISDN_TIME_STAMP) { skb_get_timestamp(skb, &tv); put_cmsg(msg, SOL_MISDN, MISDN_TIME_STAMP, sizeof(tv), &tv); } }
static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const struct xt_match *match, const void *matchinfo, int offset, unsigned int protoff, int *hotdrop) { const struct ipt_time_info *info = matchinfo; /* match info for rule */ struct timeval tv; struct tm currenttime; /* time human readable */ u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1}; u_int16_t packet_time; /* We might not have a timestamp, get one */ if (skb->tstamp.tv64 == 0) __net_timestamp((struct sk_buff *)skb); skb_get_timestamp(skb, &tv); /* First we make sure we are in the date start-stop boundaries */ if ((tv.tv_sec < info->date_start) || (tv.tv_sec > info->date_stop)) return 0; /* We are outside the date boundaries */ /* Transform the timestamp of the packet, in a human readable form */ localtime(tv.tv_sec, ¤ttime); /* check if we match this timestamp, we start by the days... */ if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday]) return 0; /* the day doesn't match */ /* ... check the time now */ packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min; if (info->time_start < info->time_stop) { if (packet_time < info->time_start || packet_time > info->time_stop) return 0; } else { if (packet_time < info->time_start && packet_time > info->time_stop) return 0; } /* here we match ! */ return 1; }
/* Insert/Update this flow */ int flowmon_hook(struct pna_flowkey *key, int direction, struct sk_buff *skb) { struct flow_entry *flow; struct pna_flow_data data; struct timeval timeval; struct flowtab_info *info; /* get the timestamp on the packet */ skb_get_timestamp(skb, &timeval); if (NULL == (info = flowtab_get(&timeval))) { return -1; } /* now the action -- try to get the key pair */ flow = (struct flow_entry *)hashmap_get(info->map, key); if (flow) { /* success, update packet count */ flow->data.bytes[direction] += skb->len + ETH_OVERHEAD; flow->data.packets[direction] += 1; return 0; } /* no entry, try to put a new key pair (with data) */ memset(&data, 0, sizeof(data)); data.bytes[direction] = skb->len + ETH_OVERHEAD; data.packets[direction] = 1; data.first_tstamp = timeval.tv_sec; data.first_dir = direction; flow = (struct flow_entry *)hashmap_put(info->map, key, &data); if (flow) { /* successful put */ info->nflows++; return 1; } /* couldn't get, couldn't put, it's a drop */ info->nflows_missed++; return -1; }
static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, struct frag_hdr *fhdr, int nhoff) { struct sk_buff *prev, *next; int offset, end; if (fq->last_in & COMPLETE) { DEBUGP("Allready completed\n"); goto err; } offset = ntohs(fhdr->frag_off) & ~0x7; end = offset + (ntohs(skb->nh.ipv6h->payload_len) - ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1))); if ((unsigned int)end > IPV6_MAXPLEN) { DEBUGP("offset is too large.\n"); return -1; } if (skb->ip_summed == CHECKSUM_HW) skb->csum = csum_sub(skb->csum, csum_partial(skb->nh.raw, (u8*)(fhdr + 1) - skb->nh.raw, 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->len || ((fq->last_in & LAST_IN) && end != fq->len)) { DEBUGP("already received last fragment\n"); goto err; } fq->last_in |= LAST_IN; fq->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 */ DEBUGP("the end of this fragment is not rounded to 8 bytes.\n"); return -1; } if (end > fq->len) { /* Some bits beyond end -> corruption. */ if (fq->last_in & LAST_IN) { DEBUGP("last packet already reached.\n"); goto err; } fq->len = end; } } if (end == offset) goto err; /* Point into the IP datagram 'data' part. */ if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) { DEBUGP("queue: message is too short.\n"); goto err; } if (end-offset < skb->len) { if (pskb_trim(skb, end - offset)) { DEBUGP("Can't trim\n"); goto err; } if (skb->ip_summed != CHECKSUM_UNNECESSARY) skb->ip_summed = CHECKSUM_NONE; } /* 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->fragments; next != NULL; next = next->next) { if (NFCT_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 = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset; if (i > 0) { offset += i; if (end <= offset) { DEBUGP("overlap\n"); goto err; } if (!pskb_pull(skb, i)) { DEBUGP("Can't pull\n"); goto err; } if (skb->ip_summed != CHECKSUM_UNNECESSARY) skb->ip_summed = CHECKSUM_NONE; } } /* Look for overlap with succeeding segments. * If we can merge fragments, do it. */ while (next && NFCT_FRAG6_CB(next)->offset < end) { /* overlap is 'i' bytes */ int i = end - NFCT_FRAG6_CB(next)->offset; if (i < next->len) { /* Eat head of the next overlapped fragment * and leave the loop. The next ones cannot overlap. */ DEBUGP("Eat head of the overlapped parts.: %d", i); if (!pskb_pull(next, i)) goto err; /* next fragment */ NFCT_FRAG6_CB(next)->offset += i; fq->meat -= i; if (next->ip_summed != CHECKSUM_UNNECESSARY) next->ip_summed = CHECKSUM_NONE; break; } else { struct sk_buff *free_it = next; /* Old fragmnet is completely overridden with * new one drop it. */ next = next->next; if (prev) prev->next = next; else fq->fragments = next; fq->meat -= free_it->len; frag_kfree_skb(free_it, NULL); } } NFCT_FRAG6_CB(skb)->offset = offset; /* Insert this fragment in the chain of fragments. */ skb->next = next; if (prev) prev->next = skb; else fq->fragments = skb; skb->dev = NULL; skb_get_timestamp(skb, &fq->stamp); fq->meat += skb->len; atomic_add(skb->truesize, &nf_ct_frag6_mem); /* The first fragment. * nhoffset is obtained from the first fragment, of course. */ if (offset == 0) { fq->nhoffset = nhoff; fq->last_in |= FIRST_IN; } write_lock(&nf_ct_frag6_lock); list_move_tail(&fq->lru_list, &nf_ct_frag6_lru_list); write_unlock(&nf_ct_frag6_lock); return 0; err: return -1; }