Example #1
0
static void rtcfg_conn_check_cfg_timeout(struct rtcfg_connection *conn)
{
    struct rtcfg_device *rtcfg_dev;


    if (!conn->cfg_timeout)
        return;

    if (rtdm_clock_read() >= conn->last_frame + conn->cfg_timeout) {
        rtcfg_dev = &device[conn->ifindex];

        rtcfg_dev->stations_found--;
        if (conn->state == RTCFG_CONN_STAGE_2)
            rtcfg_dev->spec.srv.clients_configured--;

        rtcfg_next_conn_state(conn, RTCFG_CONN_SEARCHING);
        conn->cfg_offs = 0;
        conn->flags    = 0;

#ifdef CONFIG_RTNET_RTIPV4
        if (conn->addr_type == RTCFG_ADDR_IP) {
            struct rtnet_device *rtdev;

            /* MAC address yet unknown -> use broadcast address */
            rtdev = rtdev_get_by_index(conn->ifindex);
            if (rtdev == NULL)
                return;
            memcpy(conn->mac_addr, rtdev->broadcast, MAX_ADDR_LEN);
            rtdev_dereference(rtdev);
        }
#endif /* CONFIG_RTNET_RTIPV4 */
    }
}
Example #2
0
int rtcfg_send_ready(int ifindex)
{
    struct rtnet_device    *rtdev;
    struct rtskb           *rtskb;
    unsigned int           rtskb_size;
    struct rtcfg_frm_ready *ready_frm;


    rtdev = rtdev_get_by_index(ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    rtskb_size = rtdev->hard_header_len + sizeof(struct rtcfg_frm_ready);

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    ready_frm = (struct rtcfg_frm_ready *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_ready));

    ready_frm->head.id      = RTCFG_ID_READY;
    ready_frm->head.version = 0;

    return rtcfg_send_frame(rtskb, rtdev, eth_broadcast);
}
Example #3
0
/***
 *  rt_packet_getsockname
 */
int rt_packet_getsockname(struct rtsocket *s, struct sockaddr *addr,
                          socklen_t *addrlen)
{
    struct sockaddr_ll  *sll = (struct sockaddr_ll*)addr;
    struct rtnet_device *rtdev;


    if (*addrlen < sizeof(struct sockaddr_ll))
        return -EINVAL;

    sll->sll_family   = AF_PACKET;
    sll->sll_ifindex  = s->prot.packet.ifindex;
    sll->sll_protocol = s->protocol;

    rtdev = rtdev_get_by_index(s->prot.packet.ifindex);
    if (rtdev != NULL) {
        sll->sll_hatype = rtdev->type;
        sll->sll_halen  = rtdev->addr_len;

        memcpy(sll->sll_addr, rtdev->dev_addr, rtdev->addr_len);

        rtdev_dereference(rtdev);
    } else {
        sll->sll_hatype = 0;
        sll->sll_halen  = 0;
    }

    *addrlen = sizeof(struct sockaddr_ll);

    return 0;
}
Example #4
0
int rtcfg_send_ack(int ifindex)
{
    struct rtnet_device      *rtdev;
    struct rtskb             *rtskb;
    unsigned int             rtskb_size;
    struct rtcfg_frm_ack_cfg *ack_frm;


    rtdev = rtdev_get_by_index(ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    rtskb_size = rtdev->hard_header_len + sizeof(struct rtcfg_frm_ack_cfg);

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    ack_frm = (struct rtcfg_frm_ack_cfg *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_ack_cfg));

    ack_frm->head.id      = RTCFG_ID_ACK_CFG;
    ack_frm->head.version = 0;
    ack_frm->ack_len      = htonl(device[ifindex].cfg_offs);

    return rtcfg_send_frame(rtskb, rtdev, device[ifindex].srv_mac_addr);
}
Example #5
0
int rtcfg_send_stage_1(struct rtcfg_connection *conn)
{
    struct rtnet_device          *rtdev;
    struct rtskb                 *rtskb;
    unsigned int                 rtskb_size;
    struct rtcfg_frm_stage_1_cfg *stage_1_frm;


    rtdev = rtdev_get_by_index(conn->ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    rtskb_size = rtdev->hard_header_len +
        sizeof(struct rtcfg_frm_stage_1_cfg) + conn->stage1_size +
#ifdef CONFIG_RTNET_RTIPV4
        (((conn->addr_type & RTCFG_ADDR_MASK) == RTCFG_ADDR_IP) ?
        2*RTCFG_ADDRSIZE_IP : 0);
#else /* !CONFIG_RTNET_RTIPV4 */
        0;
#endif /* CONFIG_RTNET_RTIPV4 */

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    stage_1_frm = (struct rtcfg_frm_stage_1_cfg *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_stage_1_cfg));

    stage_1_frm->head.id      = RTCFG_ID_STAGE_1_CFG;
    stage_1_frm->head.version = 0;
    stage_1_frm->addr_type    = conn->addr_type & RTCFG_ADDR_MASK;

#ifdef CONFIG_RTNET_RTIPV4
    if (stage_1_frm->addr_type == RTCFG_ADDR_IP) {
        rtskb_put(rtskb, 2*RTCFG_ADDRSIZE_IP);

        memcpy(stage_1_frm->client_addr, &(conn->addr.ip_addr), 4);

        stage_1_frm = (struct rtcfg_frm_stage_1_cfg *)
            (((u8 *)stage_1_frm) + RTCFG_ADDRSIZE_IP);

        memcpy(stage_1_frm->server_addr, &(rtdev->local_ip), 4);

        stage_1_frm = (struct rtcfg_frm_stage_1_cfg *)
            (((u8 *)stage_1_frm) + RTCFG_ADDRSIZE_IP);
    }
#endif /* CONFIG_RTNET_RTIPV4 */

    stage_1_frm->burstrate = device[conn->ifindex].burstrate;
    stage_1_frm->cfg_len   = htons(conn->stage1_size);

    memcpy(rtskb_put(rtskb, conn->stage1_size), conn->stage1_data,
           conn->stage1_size);

    return rtcfg_send_frame(rtskb, rtdev, conn->mac_addr);
}
static int rtnet_mgr_read_proc (char *page, char **start,
                off_t off, int count, int *eof, void *data)
{
    PROC_PRINT_VARS;
    int i;
    struct rtnet_device *rtdev;
    unsigned int rtskb_len;

    PROC_PRINT("\nRTnet\n\n");
    PROC_PRINT("Devices:\n");
    for (i = 1; i <= MAX_RT_DEVICES; i++) {
        rtdev = rtdev_get_by_index(i);
        if (rtdev != NULL) {
            PROC_PRINT("  %s: %s rxq=%d\n",
                rtdev->name,
                (rtdev->flags & IFF_UP) ? "UP" : "DOWN",
                rtdev->rxqueue_len);
            rtdev_dereference(rtdev);
        }
    }

    rtskb_len = ALIGN_RTSKB_STRUCT_LEN + SKB_DATA_ALIGN(RTSKB_SIZE);
    PROC_PRINT("\nrtskb pools current/max:       %d / %d\n"
               "rtskbs current/max:            %d / %d\n"
               "rtskb memory need current/max: %d / %d\n\n",
               rtskb_pools, rtskb_pools_max,
               rtskb_amount, rtskb_amount_max,
               rtskb_amount * rtskb_len, rtskb_amount_max * rtskb_len);

    PROC_PRINT_DONE;
}
Example #7
0
int rtcfg_send_simple_frame(int ifindex, int frame_id, u8 *dest_addr)
{
    struct rtnet_device     *rtdev;
    struct rtskb            *rtskb;
    unsigned int            rtskb_size;
    struct rtcfg_frm_simple *simple_frm;


    rtdev = rtdev_get_by_index(ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    rtskb_size = rtdev->hard_header_len + sizeof(struct rtcfg_frm_simple);

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    simple_frm = (struct rtcfg_frm_simple *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_simple));

    simple_frm->head.id      = frame_id;
    simple_frm->head.version = 0;

    return rtcfg_send_frame(rtskb, rtdev,
                            (dest_addr) ? dest_addr : rtdev->broadcast);
}
static int rtnet_read_proc_devices(char *buf, char **start, off_t offset,
                                   int count, int *eof, void *data)
{
    int i;
    int res;
    struct rtnet_device *rtdev;
    RTNET_PROC_PRINT_VARS(80);


    if (!RTNET_PROC_PRINT("Name\t\tFlags\n"))
        goto done;

    for (i = 1; i <= MAX_RT_DEVICES; i++) {
        rtdev = rtdev_get_by_index(i);
        if (rtdev != NULL) {
            res = RTNET_PROC_PRINT("%-15s %s%s%s%s\n",
                            rtdev->name,
                            (rtdev->flags & IFF_UP) ? "UP" : "DOWN",
                            (rtdev->flags & IFF_BROADCAST) ? " BROADCAST" : "",
                            (rtdev->flags & IFF_LOOPBACK) ? " LOOPBACK" : "",
                            (rtdev->flags & IFF_PROMISC) ? " PROMISC" : "");
            rtdev_dereference(rtdev);
            if (!res)
                break;
        }
    }

  done:
    RTNET_PROC_PRINT_DONE;
}
Example #9
0
int rtcfg_send_dead_station(struct rtcfg_connection *conn)
{
    struct rtnet_device           *rtdev;
    struct rtskb                  *rtskb;
    unsigned int                  rtskb_size;
    struct rtcfg_frm_dead_station *dead_station_frm;


    rtdev = rtdev_get_by_index(conn->ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    rtskb_size = rtdev->hard_header_len +
        sizeof(struct rtcfg_frm_dead_station) +
#ifdef CONFIG_RTNET_RTIPV4
        (((conn->addr_type & RTCFG_ADDR_MASK) == RTCFG_ADDR_IP) ?
        RTCFG_ADDRSIZE_IP : 0);
#else /* !CONFIG_RTNET_RTIPV4 */
        0;
#endif /* CONFIG_RTNET_RTIPV4 */

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    dead_station_frm = (struct rtcfg_frm_dead_station *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_dead_station));

    dead_station_frm->head.id      = RTCFG_ID_DEAD_STATION;
    dead_station_frm->head.version = 0;
    dead_station_frm->addr_type    = conn->addr_type & RTCFG_ADDR_MASK;

#ifdef CONFIG_RTNET_RTIPV4
    if (dead_station_frm->addr_type == RTCFG_ADDR_IP) {
        rtskb_put(rtskb, RTCFG_ADDRSIZE_IP);

        memcpy(dead_station_frm->logical_addr, &(conn->addr.ip_addr), 4);

        dead_station_frm = (struct rtcfg_frm_dead_station *)
            (((u8 *)dead_station_frm) + RTCFG_ADDRSIZE_IP);
    }
#endif /* CONFIG_RTNET_RTIPV4 */

    /* Ethernet-specific! */
    memcpy(dead_station_frm->physical_addr, conn->mac_addr, ETH_ALEN);
    memset(&dead_station_frm->physical_addr[ETH_ALEN], 0,
        sizeof(dead_station_frm->physical_addr) - ETH_ALEN);

    return rtcfg_send_frame(rtskb, rtdev, rtdev->broadcast);
}
Example #10
0
int rtcfg_send_announce_reply(int ifindex, u8 *dest_mac_addr)
{
    struct rtcfg_device       *rtcfg_dev = &device[ifindex];
    struct rtnet_device       *rtdev;
    struct rtskb              *rtskb;
    unsigned int              rtskb_size;
    struct rtcfg_frm_announce *announce_rpl;


    rtdev = rtdev_get_by_index(ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    rtskb_size = rtdev->hard_header_len +
        sizeof(struct rtcfg_frm_announce) +
#ifdef CONFIG_RTNET_RTIPV4
        ((rtcfg_dev->spec.clt.addr_type == RTCFG_ADDR_IP) ?
        RTCFG_ADDRSIZE_IP : 0);
#else /* !CONFIG_RTNET_RTIPV4 */
        0;
#endif /* CONFIG_RTNET_RTIPV4 */

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    announce_rpl = (struct rtcfg_frm_announce *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_announce));

    announce_rpl->head.id      = RTCFG_ID_ANNOUNCE_REPLY;
    announce_rpl->head.version = 0;
    announce_rpl->addr_type    = rtcfg_dev->spec.clt.addr_type;

#ifdef CONFIG_RTNET_RTIPV4
    if (announce_rpl->addr_type == RTCFG_ADDR_IP) {
        rtskb_put(rtskb, RTCFG_ADDRSIZE_IP);

        memcpy(announce_rpl->addr, &(rtdev->local_ip), 4);

        announce_rpl = (struct rtcfg_frm_announce *)
            (((u8 *)announce_rpl) + RTCFG_ADDRSIZE_IP);
    }
#endif /* CONFIG_RTNET_RTIPV4 */

    announce_rpl->flags     = rtcfg_dev->flags & RTCFG_FLAG_READY;
    announce_rpl->burstrate = 0; /* padding field */

    return rtcfg_send_frame(rtskb, rtdev, dest_mac_addr);
}
Example #11
0
int rtcfg_send_announce_new(int ifindex)
{
    struct rtcfg_device       *rtcfg_dev = &device[ifindex];
    struct rtnet_device       *rtdev;
    struct rtskb              *rtskb;
    unsigned int              rtskb_size;
    struct rtcfg_frm_announce *announce_new;


    rtdev = rtdev_get_by_index(ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    rtskb_size = rtdev->hard_header_len + sizeof(struct rtcfg_frm_announce) +
#ifdef CONFIG_RTNET_RTIPV4
        (((rtcfg_dev->spec.clt.addr_type & RTCFG_ADDR_MASK) == RTCFG_ADDR_IP) ?
        RTCFG_ADDRSIZE_IP : 0);
#else /* !CONFIG_RTNET_RTIPV4 */
        0;
#endif /* CONFIG_RTNET_RTIPV4 */

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    announce_new = (struct rtcfg_frm_announce *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_announce));

    announce_new->head.id      = RTCFG_ID_ANNOUNCE_NEW;
    announce_new->head.version = 0;
    announce_new->addr_type    = rtcfg_dev->spec.clt.addr_type;

#ifdef CONFIG_RTNET_RTIPV4
    if (announce_new->addr_type == RTCFG_ADDR_IP) {
        rtskb_put(rtskb, RTCFG_ADDRSIZE_IP);

        memcpy(announce_new->addr, &(rtdev->local_ip), 4);

        announce_new = (struct rtcfg_frm_announce *)
            (((u8 *)announce_new) + RTCFG_ADDRSIZE_IP);
    }
#endif /* CONFIG_RTNET_RTIPV4 */

    announce_new->flags     = rtcfg_dev->flags;
    announce_new->burstrate = rtcfg_dev->burstrate;

    return rtcfg_send_frame(rtskb, rtdev, rtdev->broadcast);
}
Example #12
0
int rtcfg_send_stage_2(struct rtcfg_connection *conn, int send_data)
{
    struct rtnet_device          *rtdev;
    struct rtcfg_device          *rtcfg_dev = &device[conn->ifindex];
    struct rtskb                 *rtskb;
    unsigned int                 rtskb_size;
    struct rtcfg_frm_stage_2_cfg *stage_2_frm;
    size_t                       total_size;
    size_t                       frag_size;


    rtdev = rtdev_get_by_index(conn->ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    if (send_data) {
        total_size = conn->stage2_file->size;
        frag_size  = MIN(rtdev->mtu - sizeof(struct rtcfg_frm_stage_2_cfg),
                         total_size);
    } else {
        total_size = 0;
        frag_size  = 0;
    }

    rtskb_size = rtdev->hard_header_len +
        sizeof(struct rtcfg_frm_stage_2_cfg) + frag_size;

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    stage_2_frm = (struct rtcfg_frm_stage_2_cfg *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_stage_2_cfg));

    stage_2_frm->head.id          = RTCFG_ID_STAGE_2_CFG;
    stage_2_frm->head.version     = 0;
    stage_2_frm->flags            = rtcfg_dev->flags;
    stage_2_frm->stations         = htonl(rtcfg_dev->other_stations);
    stage_2_frm->heartbeat_period = htons(0);
    stage_2_frm->cfg_len          = htonl(total_size);

    if (send_data)
        memcpy(rtskb_put(rtskb, frag_size), conn->stage2_file->buffer,
               frag_size);
    conn->cfg_offs = frag_size;

    return rtcfg_send_frame(rtskb, rtdev, conn->mac_addr);
}
Example #13
0
int rtcfg_send_announce_new(int ifindex)
{
    struct rtcfg_device       *rtcfg_dev = &device[ifindex];
    struct rtnet_device       *rtdev;
    struct rtskb              *rtskb;
    unsigned int              rtskb_size;
    struct rtcfg_frm_announce *announce_new;


    rtdev = rtdev_get_by_index(ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    rtskb_size = rtdev->hard_header_len + sizeof(struct rtcfg_frm_announce) +
        ((rtcfg_dev->addr_type == RTCFG_ADDR_IP) ? RTCFG_ADDRSIZE_IP : 0);

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    announce_new = (struct rtcfg_frm_announce *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_announce));

    announce_new->head.id      = RTCFG_ID_ANNOUNCE_NEW;
    announce_new->head.version = 0;
    announce_new->addr_type    = rtcfg_dev->addr_type;

    if (announce_new->addr_type == RTCFG_ADDR_IP) {
        rtskb_put(rtskb, RTCFG_ADDRSIZE_IP);

        *(u32*)announce_new->addr = rtdev->local_ip;

        announce_new = (struct rtcfg_frm_announce *)
            (((u8 *)announce_new) + RTCFG_ADDRSIZE_IP);
    }

    announce_new->flags     = rtcfg_dev->flags;
    announce_new->burstrate = rtcfg_dev->burstrate;

    return rtcfg_send_frame(rtskb, rtdev, rtdev->broadcast);
}
Example #14
0
static void rtcfg_conn_check_heartbeat(struct rtcfg_connection *conn)
{
    u64                 timeout;
    struct rtcfg_device *rtcfg_dev;


    timeout = device[conn->ifindex].spec.srv.heartbeat_timeout;
    if (!timeout)
        return;

    if (rtdm_clock_read() >= conn->last_frame + timeout) {
        rtcfg_dev = &device[conn->ifindex];

        rtcfg_dev->stations_found--;
        rtcfg_dev->stations_ready--;
        rtcfg_dev->spec.srv.clients_configured--;

        rtcfg_send_dead_station(conn);

        rtcfg_next_conn_state(conn, RTCFG_CONN_DEAD);
        conn->cfg_offs = 0;
        conn->flags    = 0;

#ifdef CONFIG_RTNET_RTIPV4
        if ((conn->addr_type & RTCFG_ADDR_MASK) == RTCFG_ADDR_IP) {
            struct rtnet_device *rtdev = rtdev_get_by_index(conn->ifindex);

            rt_ip_route_del_host(conn->addr.ip_addr, rtdev);

            if (rtdev == NULL)
                return;

            if (!(conn->addr_type & FLAG_ASSIGN_ADDR_BY_MAC))
                /* MAC address yet unknown -> use broadcast address */
                memcpy(conn->mac_addr, rtdev->broadcast, MAX_ADDR_LEN);

            rtdev_dereference(rtdev);
        }
#endif /* CONFIG_RTNET_RTIPV4 */
    }
}
Example #15
0
int rtcfg_send_stage_2_frag(struct rtcfg_connection *conn)
{
    struct rtnet_device               *rtdev;
    struct rtskb                      *rtskb;
    unsigned int                      rtskb_size;
    struct rtcfg_frm_stage_2_cfg_frag *stage_2_frm;
    size_t                            frag_size;


    rtdev = rtdev_get_by_index(conn->ifindex);
    if (rtdev == NULL)
        return -ENODEV;

    frag_size = MIN(rtdev->get_mtu(rtdev, RTCFG_SKB_PRIO) -
                    sizeof(struct rtcfg_frm_stage_2_cfg_frag),
                    conn->stage2_file->size - conn->cfg_offs);

    rtskb_size = rtdev->hard_header_len +
        sizeof(struct rtcfg_frm_stage_2_cfg_frag) + frag_size;

    rtskb = alloc_rtskb(rtskb_size, &rtcfg_pool);
    if (rtskb == NULL) {
        rtdev_dereference(rtdev);
        return -ENOBUFS;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    stage_2_frm = (struct rtcfg_frm_stage_2_cfg_frag *)
        rtskb_put(rtskb, sizeof(struct rtcfg_frm_stage_2_cfg_frag));

    stage_2_frm->head.id      = RTCFG_ID_STAGE_2_CFG_FRAG;
    stage_2_frm->head.version = 0;
    stage_2_frm->frag_offs    = htonl(conn->cfg_offs);

    memcpy(rtskb_put(rtskb, frag_size),
           conn->stage2_file->buffer + conn->cfg_offs, frag_size);
    conn->cfg_offs += frag_size;

    return rtcfg_send_frame(rtskb, rtdev, conn->mac_addr);
}
Example #16
0
/***
 *  rt_packet_getsockname
 */
int rt_packet_getsockname(struct rtsocket *sock, struct sockaddr *addr,
                          socklen_t *addrlen)
{
    struct sockaddr_ll  *sll = (struct sockaddr_ll*)addr;
    struct rtnet_device *rtdev;
    rtdm_lockctx_t      context;


    if (*addrlen < sizeof(struct sockaddr_ll))
        return -EINVAL;

    rtdm_lock_get_irqsave(&sock->param_lock, context);

    sll->sll_family   = AF_PACKET;
    sll->sll_ifindex  = sock->prot.packet.ifindex;
    sll->sll_protocol = sock->protocol;

    rtdm_lock_put_irqrestore(&sock->param_lock, context);

    rtdev = rtdev_get_by_index(sll->sll_ifindex);
    if (rtdev != NULL) {
        sll->sll_hatype = rtdev->type;
        sll->sll_halen  = rtdev->addr_len;

        memcpy(sll->sll_addr, rtdev->dev_addr, rtdev->addr_len);

        rtdev_dereference(rtdev);
    } else {
        sll->sll_hatype = 0;
        sll->sll_halen  = 0;
    }

    *addrlen = sizeof(struct sockaddr_ll);

    return 0;
}
Example #17
0
int rtwlan_tx(struct rtskb *rtskb, struct rtnet_device *rtnet_dev)
{
    struct rtwlan_device * rtwlan = rtnetdev_priv(rtnet_dev);
    struct ieee80211_hdr_3addr header = {	/* Ensure zero initialized */
        .duration_id = 0,
        .seq_ctl = 0
    };
    u8 dest[ETH_ALEN], src[ETH_ALEN];

    /* Save source and destination addresses */
    memcpy(dest, rtskb->data, ETH_ALEN);
    memcpy(src, rtskb->data + ETH_ALEN, ETH_ALEN);

    /* Generate ieee80211 compatible header */
    memcpy(header.addr3, src, ETH_ALEN);	/* BSSID */
    memcpy(header.addr2, src, ETH_ALEN);	/* SA */
    memcpy(header.addr1, dest, ETH_ALEN);	/* DA */

    /* Frame Control */
    switch(rtwlan->mode) {
        case RTWLAN_MODE_RAW:
            header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
            break;

        case RTWLAN_MODE_ACK:
            header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
            break;

        default:
            return -1;
    }

    memcpy(rtskb_push(rtskb, IEEE80211_3ADDR_LEN), &header, IEEE80211_3ADDR_LEN);

    return 0;
}

EXPORT_SYMBOL(rtwlan_tx);


/**
 * rtalloc_wlandev - Allocates and sets up a wlan device
 * @sizeof_priv: size of additional driver-private structure to
 *               be allocated for this wlan device
 *
 * Fill in the fields of the device structure with wlan-generic
 * values. Basically does everything except registering the device.
 *
 * A 32-byte alignment is enforced for the private data area.
 */

struct rtnet_device * rtwlan_alloc_dev(int sizeof_priv)
{
    struct rtnet_device *rtnet_dev;

    RTWLAN_DEBUG("Start.\n");

    rtnet_dev = rt_alloc_etherdev(sizeof(struct rtwlan_device) + sizeof_priv);
    if (!rtnet_dev)
        return NULL;

    rtdev_alloc_name(rtnet_dev, "rtwlan%d");

    return rtnet_dev;
}

EXPORT_SYMBOL(rtwlan_alloc_dev);


int rtwlan_ioctl(struct rtnet_device * rtdev,
                 unsigned int request,
                 unsigned long arg)
{
    struct rtwlan_cmd cmd;
    int ret=0;

    if (copy_from_user(&cmd, (void *)arg, sizeof(cmd)) != 0)
        return -EFAULT;

    switch(request) {
        case IOC_RTWLAN_IFINFO:
            if (cmd.args.info.ifindex > 0)
                rtdev = rtdev_get_by_index(cmd.args.info.ifindex);
            else
                rtdev = rtdev_get_by_name(cmd.head.if_name);
            if (rtdev == NULL)
                return -ENODEV;

            if (down_interruptible(&rtdev->nrt_lock)) {
                rtdev_dereference(rtdev);
                return -ERESTARTSYS;
            }

            if (rtdev->do_ioctl)
                ret = rtdev->do_ioctl(rtdev, request, &cmd);
            else 
                ret = -ENORTWLANDEV;

            memcpy(cmd.head.if_name, rtdev->name, IFNAMSIZ);
            cmd.args.info.ifindex      = rtdev->ifindex;
            cmd.args.info.flags        = rtdev->flags;

            up(&rtdev->nrt_lock);

            rtdev_dereference(rtdev);

            break;

        case IOC_RTWLAN_MODE:
        case IOC_RTWLAN_BITRATE:
        case IOC_RTWLAN_CHANNEL:
        case IOC_RTWLAN_TXPOWER:
        case IOC_RTWLAN_DROPBCAST:
        case IOC_RTWLAN_DROPMCAST:
        case IOC_RTWLAN_REGREAD:
        case IOC_RTWLAN_REGWRITE:
        case IOC_RTWLAN_BBPWRITE:
        case IOC_RTWLAN_BBPREAD:
        case IOC_RTWLAN_BBPSENS:
            if (down_interruptible(&rtdev->nrt_lock))
                return -ERESTARTSYS;

            if (rtdev->do_ioctl)
                ret = rtdev->do_ioctl(rtdev, request, &cmd);
            else
                ret = -ENORTWLANDEV;

            up(&rtdev->nrt_lock);

            break;

        default:
            ret = -ENOTTY;
    }

    if (copy_to_user((void *)arg, &cmd, sizeof(cmd)) != 0)
        return -EFAULT;

    return ret;
}


struct rtnet_ioctls rtnet_wlan_ioctls = {
    service_name: "rtwlan ioctl",
    ioctl_type: RTNET_IOC_TYPE_RTWLAN,
    handler: rtwlan_ioctl
};
Example #18
0
/***
 *  rt_socket_if_ioctl
 */
int rt_socket_if_ioctl(struct rtdm_dev_context *context, int call_flags,
                       int request, void *arg)
{
    struct rtnet_device     *rtdev;
    struct ifreq            *cur_ifr;
    struct sockaddr_in      *sin;
    int                     i;
    int                     size;
    struct ifconf           *ifc = arg;
    struct ifreq            *ifr = arg;
    int                     ret = 0;


    switch (request) {
        case SIOCGIFCONF:
            size = 0;
            cur_ifr = ifc->ifc_req;

            for (i = 1; i <= MAX_RT_DEVICES; i++) {
                rtdev = rtdev_get_by_index(i);
                if (rtdev != NULL) {
                    if ((rtdev->flags & IFF_RUNNING) == 0) {
                        rtdev_dereference(rtdev);
                        continue;
                    }

                    size += sizeof(struct ifreq);
                    if (size > ifc->ifc_len) {
                        rtdev_dereference(rtdev);
                        size = ifc->ifc_len;
                        break;
                    }

                    strncpy(cur_ifr->ifr_name, rtdev->name,
                            IFNAMSIZ);
                    sin = (struct sockaddr_in *)&cur_ifr->ifr_addr;
                    sin->sin_family      = AF_INET;
                    sin->sin_addr.s_addr = rtdev->local_ip;

                    cur_ifr++;
                    rtdev_dereference(rtdev);
                }
            }

            ifc->ifc_len = size;
            break;

        case SIOCGIFFLAGS:
            rtdev = rtdev_get_by_name(ifr->ifr_name);
            if (rtdev == NULL)
                return -ENODEV;
            else {
                ifr->ifr_flags = rtdev->flags;
                rtdev_dereference(rtdev);
            }
            break;

        default:
            ret = -EOPNOTSUPP;
            break;
    }

    return ret;
}
Example #19
0
int __init rtcap_init(void)
{
    struct rtnet_device *rtdev;
    struct net_device   *dev;
    int                 ret;
    int                 devices = 0;
    int                 i;
    unsigned long       flags;


    printk("RTcap: real-time capturing interface\n");

#if defined(CONFIG_RTAI_24) || defined(CONFIG_RTAI_30) || defined(CONFIG_RTAI_31)
    if (start_timer) {
        rt_set_oneshot_mode();
        start_rt_timer(0);
    }
#endif

    rtskb_queue_init(&cap_queue);

    ret = rtos_nrt_signal_init(&cap_signal, rtcap_signal_handler);
    if (ret < 0)
        goto error1;

    for (i = 0; i < MAX_RT_DEVICES; i++) {
        tap_device[i].present = 0;

        rtdev = rtdev_get_by_index(i);
        if (rtdev != NULL) {
            down(&rtdev->nrt_sem);

            if (test_bit(PRIV_FLAG_UP, &rtdev->priv_flags)) {
                up(&rtdev->nrt_sem);
                printk("RTcap: %s busy, skipping device!\n", rtdev->name);
                rtdev_dereference(rtdev);
                continue;
            }

            if (rtdev->mac_priv != NULL) {
                up(&rtdev->nrt_sem);

                printk("RTcap: RTmac discipline already active on device %s. "
                       "Load RTcap before RTmac!\n", rtdev->name);

                rtdev_dereference(rtdev);
                continue;
            }

            memset(&tap_device[i].tap_dev_stats, 0,
                   sizeof(struct net_device_stats));

            dev = &tap_device[i].tap_dev;
            memset(dev, 0, sizeof(struct net_device));
            dev->init = tap_dev_init;
            dev->priv = rtdev;
            strncpy(dev->name, rtdev->name, IFNAMSIZ-1);
            dev->name[IFNAMSIZ-1] = 0;

            ret = register_netdev(dev);
            if (ret < 0) {
                up(&rtdev->nrt_sem);
                rtdev_dereference(rtdev);

                printk("RTcap: unable to register %s!\n", dev->name);
                goto error2;
            }
            tap_device[i].present = TAP_DEV;

            tap_device[i].orig_xmit = rtdev->hard_start_xmit;

            if ((rtdev->flags & IFF_LOOPBACK) == 0) {
                dev = &tap_device[i].rtmac_tap_dev;
                memset(dev, 0, sizeof(struct net_device));
                dev->init = tap_dev_init;
                dev->priv = rtdev;
                strncpy(dev->name, rtdev->name, IFNAMSIZ-1);
                dev->name[IFNAMSIZ-1] = 0;
                strncat(dev->name, "-mac", IFNAMSIZ-strlen(dev->name));

                ret = register_netdev(dev);
                if (ret < 0) {
                    up(&rtdev->nrt_sem);
                    rtdev_dereference(rtdev);

                    printk("RTcap: unable to register %s!\n", dev->name);
                    goto error2;
                }
                tap_device[i].present |= RTMAC_TAP_DEV;

                rtdev->hard_start_xmit = rtcap_xmit_hook;
            } else
                rtdev->hard_start_xmit = rtcap_loopback_xmit_hook;

            /* If the device requires no xmit_lock, start_xmit points equals
             * hard_start_xmit => we have to update this as well
             */
            if (rtdev->features & RTNETIF_F_NON_EXCLUSIVE_XMIT)
                rtdev->start_xmit = rtdev->hard_start_xmit;
                
            tap_device[i].present |= XMIT_HOOK;
            __MOD_INC_USE_COUNT(rtdev->owner);

            up(&rtdev->nrt_sem);

            devices++;
        }
    }

    if (devices == 0) {
        printk("RTcap: no real-time devices found!\n");
        ret = -ENODEV;
        goto error2;
    }

    if (rtskb_pool_init(&cap_pool, rtcap_rtskbs * devices) <
            rtcap_rtskbs * devices) {
        rtskb_pool_release(&cap_pool);
        ret = -ENOMEM;
        goto error2;
    }

    /* register capturing handlers with RTnet core */
    rtos_spin_lock_irqsave(&rtcap_lock, flags);
    rtcap_handler = rtcap_rx_hook;
    rtos_spin_unlock_irqrestore(&rtcap_lock, flags);

    return 0;

  error2:
    cleanup_tap_devices();
    rtos_nrt_signal_delete(&cap_signal);

  error1:
#if defined(CONFIG_RTAI_24) || defined(CONFIG_RTAI_30) || defined(CONFIG_RTAI_31)
    if (start_timer)
        stop_rt_timer();
#endif

    return ret;
}
Example #20
0
/***
 *  rt_socket_if_ioctl
 */
int rt_socket_if_ioctl(struct rtdm_dev_context *sockctx,
                       rtdm_user_info_t *user_info, int request, void *arg)
{
    struct rtnet_device *rtdev;
    struct ifreq        *ifr = arg;
    struct sockaddr_in  *sin;
    int                 ret = 0;


    if (request == SIOCGIFCONF) {
        struct ifconf       *ifc = arg;
        struct ifreq        *cur_ifr = ifc->ifc_req;
        int                 size = 0;
        int                 i;

        for (i = 1; i <= MAX_RT_DEVICES; i++) {
            rtdev = rtdev_get_by_index(i);
            if (rtdev != NULL) {
                if ((rtdev->flags & IFF_RUNNING) == 0) {
                    rtdev_dereference(rtdev);
                    continue;
                }

                size += sizeof(struct ifreq);
                if (size > ifc->ifc_len) {
                    rtdev_dereference(rtdev);
                    size = ifc->ifc_len;
                    break;
                }

                strncpy(cur_ifr->ifr_name, rtdev->name,
                        IFNAMSIZ);
                sin = (struct sockaddr_in *)&cur_ifr->ifr_addr;
                sin->sin_family      = AF_INET;
                sin->sin_addr.s_addr = rtdev->local_ip;

                cur_ifr++;
                rtdev_dereference(rtdev);
            }
        }

        ifc->ifc_len = size;
        return 0;
    }

    rtdev = rtdev_get_by_name(ifr->ifr_name);
    if (rtdev == NULL)
        return -ENODEV;

    switch (request) {
        case SIOCGIFINDEX:
            ifr->ifr_ifindex = rtdev->ifindex;
            break;

        case SIOCGIFFLAGS:
            ifr->ifr_flags = rtdev->flags;
            break;

        case SIOCGIFHWADDR:
            memcpy(ifr->ifr_hwaddr.sa_data, rtdev->dev_addr, rtdev->addr_len);
            ifr->ifr_hwaddr.sa_family = rtdev->type;
            break;

        case SIOCGIFADDR:
            sin = (struct sockaddr_in *)&ifr->ifr_addr;
            sin->sin_family      = AF_INET;
            sin->sin_addr.s_addr = rtdev->local_ip;
            break;

        case SIOCETHTOOL:
            if (rtdev->do_ioctl != NULL)
                ret = rtdev->do_ioctl(rtdev, request, arg);
            else
                ret = -EOPNOTSUPP;
            break;

        default:
            ret = -EOPNOTSUPP;
            break;
    }

    rtdev_dereference(rtdev);
    return ret;
}
Example #21
0
/***
 *  rt_packet_sendmsg
 */
int rt_packet_sendmsg(struct rtsocket *sock, const struct msghdr *msg,
                      size_t len, int flags)
{
    struct sockaddr_ll *sll = (struct sockaddr_ll*)msg->msg_name;
    struct rtnet_device *rtdev;
    struct rtskb *rtskb;
    int ret = 0;


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

    /* a lot of sanity checks */
    if ((flags & ~MSG_DONTWAIT) ||
        (sll == NULL) || (msg->msg_namelen != sizeof(struct sockaddr_ll)) ||
        ((sll->sll_family != AF_PACKET) && (sll->sll_family != AF_UNSPEC)) ||
        (sll->sll_ifindex <= 0))
        return -EINVAL;

    if ((rtdev = rtdev_get_by_index(sll->sll_ifindex)) == NULL)
        return -ENODEV;

    rtskb = alloc_rtskb(rtdev->hard_header_len + len, &sock->skb_pool);
    if (rtskb == NULL) {
        ret = -ENOBUFS;
        goto out;
    }

    if ((len < 0) || (len > rtdev->mtu)) {
        ret = -EMSGSIZE;
        goto err;
    }

    if (sll->sll_halen != rtdev->addr_len) {
        ret = -EINVAL;
        goto err;
    }

    rtskb_reserve(rtskb, rtdev->hard_header_len);

    rt_memcpy_fromkerneliovec(rtskb_put(rtskb, len), msg->msg_iov, len);

    rtskb->rtdev    = rtdev;
    rtskb->priority = sock->priority;

    if (rtdev->hard_header) {
        ret = rtdev->hard_header(rtskb, rtdev, ntohs(sll->sll_protocol),
                                 sll->sll_addr, rtdev->dev_addr, rtskb->len);
        if (ret < 0)
            goto err;
    }

    if ((rtdev->flags & IFF_UP) != 0) {
        if (rtdev_xmit(rtskb) == 0)
            ret = len;
        else
            ret = -EAGAIN;
    } else {
        ret = -ENETDOWN;
        goto err;
    }

out:
    rtdev_dereference(rtdev);
    return ret;

err:
    kfree_rtskb(rtskb);
    rtdev_dereference(rtdev);
    return ret;
}