Ejemplo n.º 1
0
static int tcpdiag_get_exact(struct sk_buff *in_skb, struct nlmsghdr *nlh)
{
	int err;
	struct sock *sk;
	struct tcpdiagreq *req = NLMSG_DATA(nlh);
	struct sk_buff *rep;

	if (req->tcpdiag_family == AF_INET) {
		sk = tcp_v4_lookup(req->id.tcpdiag_dst[0], req->id.tcpdiag_dport,
				   req->id.tcpdiag_src[0], req->id.tcpdiag_sport,
				   req->id.tcpdiag_if);
	}
#ifdef CONFIG_IPV6
	else if (req->tcpdiag_family == AF_INET6) {
		sk = tcp_v6_lookup((struct in6_addr*)req->id.tcpdiag_dst, req->id.tcpdiag_dport,
				   (struct in6_addr*)req->id.tcpdiag_src, req->id.tcpdiag_sport,
				   req->id.tcpdiag_if);
	}
#endif
	else {
		return -EINVAL;
	}

	if (sk == NULL)
		return -ENOENT;

	err = -ESTALE;
	if ((req->id.tcpdiag_cookie[0] != TCPDIAG_NOCOOKIE ||
	     req->id.tcpdiag_cookie[1] != TCPDIAG_NOCOOKIE) &&
	    sk != *((struct sock **)&req->id.tcpdiag_cookie[0]))
		goto out;

	err = -ENOMEM;
	rep = alloc_skb(NLMSG_SPACE(sizeof(struct tcpdiagmsg)+
				    sizeof(struct tcpdiag_meminfo)+
				    sizeof(struct tcp_info)+64), GFP_KERNEL);
	if (!rep)
		goto out;

	if (tcpdiag_fill(rep, sk, req->tcpdiag_ext,
			 NETLINK_CB(in_skb).pid,
			 nlh->nlmsg_seq) <= 0)
		BUG();

	err = netlink_unicast(tcpnl, rep, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
	if (err > 0)
		err = 0;

out:
	if (sk) {
		if (sk->state == TCP_TIME_WAIT)
			tcp_tw_put((struct tcp_tw_bucket*)sk);
		else
			sock_put(sk);
	}
	return err;
}
Ejemplo n.º 2
0
int icmp_chkaddr(struct sk_buff *skb)
{
	struct icmphdr *icmph=(struct icmphdr *)(skb->h.raw + skb->h.iph->ihl*4);
	struct iphdr *iph = (struct iphdr *) (icmph + 1);
	void (*handler)(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len) = icmp_pointers[icmph->type].handler;

	if (handler == icmp_unreach || handler == icmp_redirect) {
		struct sock *sk;

		switch (iph->protocol) {
		case IPPROTO_TCP:
			{
			struct tcphdr *th = (struct tcphdr *)(((unsigned char *)iph)+(iph->ihl<<2));

			sk = tcp_v4_lookup(iph->saddr, th->source, iph->daddr, th->dest, skb->dev);
			if (!sk) return 0;
			if (sk->saddr != iph->saddr) return 0;
			if (sk->daddr != iph->daddr) return 0;
			if (sk->dummy_th.dest != th->dest) return 0;
			/*
			 * This packet came from us.
			 */
			return 1;
			}
		case IPPROTO_UDP:
			{
			struct udphdr *uh = (struct udphdr *)(((unsigned char *)iph)+(iph->ihl<<2));

			sk = udp_v4_lookup(iph->saddr, uh->source, iph->daddr, uh->dest, skb->dev);
			if (!sk) return 0;
			if (sk->saddr != iph->saddr && ip_chk_addr(iph->saddr) != IS_MYADDR)
				return 0;
			/*
			 * This packet may have come from us.
			 * Assume it did.
			 */
			return 1;
			}
		}
	}
	return 0;
}
Ejemplo n.º 3
0
int icmp_chkaddr(struct sk_buff *skb)
{
	struct icmphdr *icmph=(struct icmphdr *)(skb->nh.raw + skb->nh.iph->ihl*4);
	struct iphdr *iph = (struct iphdr *) (icmph + 1);
	void (*handler)(struct icmphdr *icmph, struct sk_buff *skb, int len) = icmp_pointers[icmph->type].handler;

	if (handler == icmp_unreach || handler == icmp_redirect) {
		struct sock *sk;

		switch (iph->protocol) {
		case IPPROTO_TCP:
			{
			struct tcphdr *th = (struct tcphdr *)(((unsigned char *)iph)+(iph->ihl<<2));

			sk = tcp_v4_lookup(iph->daddr, th->dest, iph->saddr, th->source, skb->dev->ifindex);
			if (!sk || (sk->state == TCP_LISTEN))
				return 0;
			/*
			 * This packet came from us.
			 */
			return 1;
			}
		case IPPROTO_UDP:
			{
			struct udphdr *uh = (struct udphdr *)(((unsigned char *)iph)+(iph->ihl<<2));

			sk = udp_v4_lookup(iph->daddr, uh->dest, iph->saddr, uh->source, skb->dev->ifindex);
			if (!sk) return 0;
			if (sk->saddr != iph->saddr && inet_addr_type(iph->saddr) != RTN_LOCAL)
				return 0;
			/*
			 * This packet may have come from us.
			 * Assume it did.
			 */
			return 1;
			}
		}
	}
	return 0;
}