Example #1
0
/***
 *  common reply function
 */
static void rt_icmp_send_reply(struct icmp_bxm *icmp_param, struct rtskb *skb)
{
    struct dest_route   rt;
    int                 err;


    icmp_param->head.icmph.checksum = 0;
    icmp_param->csum = 0;

    /* route back to the source address via the incoming device */
    if (rt_ip_route_output(&rt, skb->nh.iph->saddr,
			   skb->rtdev->local_ip) != 0)
	return;

    rt_socket_reference(icmp_socket);
    err = rt_ip_build_xmit(icmp_socket, rt_icmp_glue_reply_bits, icmp_param,
			   sizeof(struct icmphdr) + icmp_param->data_len,
			   &rt, MSG_DONTWAIT);
    if (err)
	    rt_socket_dereference(icmp_socket);

    rtdev_dereference(rt.rtdev);

    RTNET_ASSERT(err == 0,
		 rtdm_printk("RTnet: %s() error in xmit\n", __FUNCTION__););
Example #2
0
/***
 *  common reply function
 */
static void rt_icmp_send_reply(struct icmp_bxm *icmp_param, struct rtskb *skb)
{
    struct dest_route   rt;
    u32                 daddr;
    int                 err;


    daddr = skb->nh.iph->saddr;

    icmp_param->head.icmph.checksum = 0;
    icmp_param->csum = 0;

    if (rt_ip_route_output(&rt, daddr) != 0)
        return;

    err = rt_ip_build_xmit(&icmp_socket, rt_icmp_glue_reply_bits, icmp_param,
                           sizeof(struct icmphdr) + icmp_param->data_len,
                           &rt, MSG_DONTWAIT);

    rtdev_dereference(rt.rtdev);

    RTNET_ASSERT(err == 0,
                 rtos_print("RTnet: %s() error in xmit\n", __FUNCTION__););
Example #3
0
/***
 *  rt_udp_sendmsg
 */
ssize_t rt_udp_sendmsg(struct rtdm_dev_context *context, int call_flags,
                       const struct msghdr *msg, int msg_flags)
{
    struct rtsocket     *sock = (struct rtsocket *)&context->dev_private;
    size_t              len   = rt_iovec_len(msg->msg_iov, msg->msg_iovlen);
    int                 ulen  = len + sizeof(struct udphdr);
    struct sockaddr_in  *usin;
    struct udpfakehdr   ufh;
    struct dest_route   rt;
    u32                 saddr;
    u32                 daddr;
    u16                 dport;
    int                 err;
    unsigned long       flags;


    if ((len < 0) || (len > 0xFFFF-sizeof(struct iphdr)-sizeof(struct udphdr)))
        return -EMSGSIZE;

    if (msg_flags & MSG_OOB)   /* Mirror BSD error message compatibility */
        return -EOPNOTSUPP;

    if (msg_flags & ~(MSG_DONTROUTE|MSG_DONTWAIT) )
        return -EINVAL;

    if ((msg->msg_name) && (msg->msg_namelen==sizeof(struct sockaddr_in))) {
        usin = (struct sockaddr_in*) msg->msg_name;

        if ((usin->sin_family != AF_INET) && (usin->sin_family != AF_UNSPEC))
            return -EINVAL;

        daddr = usin->sin_addr.s_addr;
        dport = usin->sin_port;

        rtos_spin_lock_irqsave(&sock->param_lock, flags);
    } else {
        rtos_spin_lock_irqsave(&sock->param_lock, flags);

        if (sock->prot.inet.state != TCP_ESTABLISHED)
            return -ENOTCONN;

        daddr = sock->prot.inet.daddr;
        dport = sock->prot.inet.dport;
    }
    saddr         = sock->prot.inet.saddr;
    ufh.uh.source = sock->prot.inet.sport;

    rtos_spin_unlock_irqrestore(&sock->param_lock, flags);

    if ((daddr | dport) == 0)
        return -EINVAL;

    /* get output route */
    err = rt_ip_route_output(&rt, daddr);
    if (err)
        return err;

    /* check if specified source address fits */
    if ((saddr != INADDR_ANY) && (saddr != rt.rtdev->local_ip)) {
        rtdev_dereference(rt.rtdev);
        return -EHOSTUNREACH;
    }

    /* we found a route, remember the routing dest-addr could be the netmask */
    ufh.saddr     = rt.rtdev->local_ip;
    ufh.daddr     = daddr;
    ufh.uh.dest   = dport;
    ufh.uh.len    = htons(ulen);
    ufh.uh.check  = 0;
    ufh.iov       = msg->msg_iov;
    ufh.iovlen    = msg->msg_iovlen;
    ufh.wcheck    = 0;

    err = rt_ip_build_xmit(sock, rt_udp_getfrag, &ufh, ulen, &rt, msg_flags);

    rtdev_dereference(rt.rtdev);

    if (!err)
        return len;
    else
        return err;
}
Example #4
0
/***
 *  rt_udp_sendmsg
 */
int rt_udp_sendmsg(struct rtsocket *s, const struct msghdr *msg, size_t len, int flags)
{
    int ulen = len + sizeof(struct udphdr);

    struct udpfakehdr ufh;
    struct rt_rtable *rt = NULL;

    u32 daddr;
    u16 dport;
    int err;

    if ((len < 0) || (len > 0xFFFF-sizeof(struct iphdr)-sizeof(struct udphdr)))
        return -EMSGSIZE;

    if (flags & MSG_OOB)   /* Mirror BSD error message compatibility */
        return -EOPNOTSUPP;

    if (flags & ~(MSG_DONTROUTE|MSG_DONTWAIT) )
        return -EINVAL;

    if ((msg->msg_name) && (msg->msg_namelen==sizeof(struct sockaddr_in))) {
        struct sockaddr_in *usin = (struct sockaddr_in*) msg->msg_name;

        if ((usin->sin_family!=AF_INET) && (usin->sin_family!=AF_UNSPEC))
            return -EINVAL;

        daddr = usin->sin_addr.s_addr;
        dport = usin->sin_port;
    } else {
        if (s->state != TCP_ESTABLISHED)
            return -ENOTCONN;

        daddr = s->prot.inet.daddr;
        dport = s->prot.inet.dport;
    }

#ifdef DEBUG
    rtos_print("sendmsg to %x:%d\n", ntohl(daddr), ntohs(dport));
#endif
    if ((daddr==0) || (dport==0))
        return -EINVAL;

    err = rt_ip_route_output(&rt, daddr, s->prot.inet.saddr);
    if (err)
        goto out;

    /* we found a route, remember the routing dest-addr could be the netmask */
    ufh.saddr     = rt->rt_src;
    ufh.daddr     = daddr;
    ufh.uh.source = s->prot.inet.sport;
    ufh.uh.dest   = dport;
    ufh.uh.len    = htons(ulen);
    ufh.uh.check  = 0;
    ufh.iov       = msg->msg_iov;
    ufh.iovlen    = msg->msg_iovlen;
    ufh.wcheck    = 0;

    err = rt_ip_build_xmit(s, rt_udp_getfrag, &ufh, ulen, rt, flags);

out:
    if (!err)
        return len;
    else
        return err;
}