示例#1
0
文件: packet.c 项目: nomnom100/pom-ng
struct packet *packet_clone(struct packet *src, unsigned int flags) {

    struct packet *dst = NULL;

    if (!(flags & PACKET_FLAG_FORCE_NO_COPY) && !src->pkt_buff) {
        // If it doesn't have a pkt_buff structure, it means it was not allocated by us
        // That means that the packet is somewhere probably in a ringbuffer (pcap)
        dst = packet_alloc();
        if (!dst)
            return NULL;
        // FIXME get the alignment offset from the input
        if (packet_buffer_alloc(dst, src->len, 0) != POM_OK) {
            packet_release(dst);
            return NULL;
        }

        dst->ts = src->ts;
        memcpy(dst->buff, src->buff, src->len);

        dst->datalink = src->datalink;
        dst->input = src->input;

        // Multipart and stream are not copied

        return dst;
    }

    __sync_fetch_and_add(&src->refcount, 1);
    return src;
}
示例#2
0
struct packet *logout_packet(unsigned short sessid) {
	struct packet *ret = packet_alloc();
	ret->family = 0xf1;
	ret->unk1 = 0xe0;
	ret->dir = 0x0e;
	ret->pltype = 0x00;
	ret->connid = 0;
	ret->subseq = 0;
	ret->unk2 = 0;
	ret->sessid = sessid;
	ret->tail = 0;

	ret->data = block_alloc();
	ret->data->id = 0x0b;
	ret->data->data = NULL;
	ret->data->nchildren = 0;

	unsigned char xxx[1024];

	xxx[0] = 0x04;
	block_addchild(ret->data, "1", xxx, 1);

	*(unsigned short *)(xxx) = htons(0);
	*(unsigned short *)(xxx+2) = htons(0); // job nr.
	*(unsigned short *)(xxx+4) = htons(sessid);
	*(unsigned short *)(xxx+6) = htons(0);
	*(unsigned short *)(xxx+8) = htons(0);
	block_addchild(ret->data, "2", xxx, 0x0a);

	return ret;
}
示例#3
0
// ENVOI DE PACKET HELLO
int init_one_hop(call_t *c, void *args) {
    struct nodedata *nodedata = get_node_private_data(c);

    //recuperer le support de communication DOWN
    entityid_t *down = get_entity_links_down(c);
    call_t c0 = {down[0], c->node};

    //destination de paquet
    destination_t destination = {BROADCAST_ADDR, {-1, -1, -1}};

    //creation de paquet et initialisation de son data
    packet_t *packet = packet_alloc(c, nodedata->overhead[0] + sizeof(struct packet_hello));
    struct packet_hello *hello = (struct packet_hello *) (packet->data + nodedata->overhead[0]);

    //initilailser les données
    hello->type=HELLO;
    hello->source=c->node;

    if (SET_HEADER(&c0, packet, &destination) == -1) {
            packet_dealloc(packet);
            return -1;
    }

    DEBUG;
    /*printf("Node %d (%lf %lf %lf) broadcast a packet hello, at %lf\n", c->node,                                 //id de Noeud
           get_node_position(c->node)->x,get_node_position(c->node)->y,get_node_position(c->node)->z,           //la postion x, y,z de Noeud
           get_time_now_second());//*/                                                                              //l'instant d'envoi.

    //L'envoi
    TX(&c0,packet);
    //tous c'est bien passé
    return 1;
}
示例#4
0
int av_packet_ref(AVPacket *dst, const AVPacket *src)
{
    int ret;

    ret = av_packet_copy_props(dst, src);
    if (ret < 0)
        return ret;

    if (!src->buf) {
        ret = packet_alloc(&dst->buf, src->size);
        if (ret < 0)
            goto fail;
        if (src->size)
            memcpy(dst->buf->data, src->data, src->size);

        dst->data = dst->buf->data;
    } else {
        dst->buf = av_buffer_ref(src->buf);
        if (!dst->buf) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
        dst->data = src->data;
    }

    dst->size = src->size;

    return 0;
fail:
    av_packet_free_side_data(dst);
    return ret;
}
示例#5
0
struct packet *command_cancel_packet(unsigned short connid, unsigned short sessid, unsigned char tail, unsigned short jobnr) {
	struct packet *ret = packet_alloc();
	ret->family = 0xf1;
	ret->unk1 = 0xe0;
	ret->dir = 0x03;
	ret->pltype = 0x01;
	ret->connid = connid;
	ret->subseq = 0;
	ret->unk2 = 0;
	ret->sessid = sessid;
	ret->tail = tail;

	ret->data = block_alloc();
	ret->data->id = 0x0a;
	ret->data->data = NULL;
	ret->data->nchildren = 0;

	unsigned char xxx[1024];

	xxx[0] = 0x05;
	block_addchild(ret->data, "1", xxx, 1);

	*(unsigned short *)(xxx) = htons(0);
	*(unsigned short *)(xxx+2) = htons(jobnr);
	*(unsigned short *)(xxx+4) = htons(0);
	*(unsigned short *)(xxx+6) = htons(0);
	*(unsigned short *)(xxx+8) = htons(0);
	block_addchild(ret->data, "2", xxx, 0x0a);

	return ret;
}
示例#6
0
struct packet *command_confirmation_packet(unsigned short connid, unsigned short sessid, unsigned char tail, char *c, int len) {
	struct packet *ret = packet_alloc();
	ret->family = 0xf1;
	ret->unk1 = 0xe0;
	ret->dir = 0x03;
	ret->pltype = 0x01;
	ret->connid = connid;
	ret->subseq = 0;
	ret->unk2 = 0;
	ret->sessid = sessid;
	ret->tail = tail;

	ret->data = block_alloc();
	ret->data->id = 8;
	ret->data->data = NULL;
	ret->data->nchildren = 0;

	unsigned char xxx[1024];

	xxx[0] = 0x04;
	block_addchild(ret->data, "1", xxx, 1);

	*(unsigned short *)(xxx) = htons(0);
	*(unsigned short *)(xxx+2) = htons(0);
	*(unsigned short *)(xxx+4) = htons(0);
	*(unsigned short *)(xxx+6) = htons(0);
	*(unsigned short *)(xxx+8) = htons(0);
	block_addchild(ret->data, "2", xxx, 0x0a);

	block_addchild(ret->data, "6-1", (unsigned char *)c, len);

	return ret;
}
示例#7
0
struct packet *command_packet(unsigned short sessid, char *c, int len) {
	struct packet *ret = packet_alloc();
	ret->family = 0xf1;
	ret->unk1 = 0xe0;
	ret->dir = 0x02;
	ret->pltype = 0x00;
	ret->connid = 0;
	ret->subseq = 0;
	ret->unk2 = 0;
	ret->sessid = sessid;
	ret->tail = 0;

	ret->data = block_alloc();
	ret->data->id = 4;
	ret->data->data = NULL;
	ret->data->nchildren = 0;

	unsigned char xxx[1024];

	xxx[0] = 0x04;
	block_addchild(ret->data, "1", xxx, 1);

	*(unsigned short *)(xxx) = htons(0);
	*(unsigned short *)(xxx+2) = htons(0); // job nr.
	*(unsigned short *)(xxx+4) = htons(0);
	*(unsigned short *)(xxx+6) = htons(0);
	xxx[8] = 0;
	block_addchild(ret->data, "2", xxx, 0x09);

	block_addchild(ret->data, "6-1", (unsigned char *)c, len);

	return ret;
}
示例#8
0
packet_t* packet_pack(const void* in_data, size_t in_max_size)
{
	if (0 == in_data || 0 == in_max_size)
		return 0;

	packet_t* packet = packet_alloc(in_max_size);
	packet_join(packet, in_data, in_max_size);
	return packet;
}
示例#9
0
//RECEPTION et REPONDRE AU PACKET HELLO
int rx_one_hop(call_t *c, packet_t *packet) {
    struct nodedata *nodedata = get_node_private_data(c);

    //RECEPTION  DE PACKET HELLO
    struct packet_hello *hello = (struct packet_hello *) (packet->data + nodedata->overhead[0]);

    DEBUG;
    /*printf("NOde %d a recu un HELLO de %d (%lf %lf %lf) at %lf\n",c->node,
           hello->source,
           get_node_position(hello->source)->x,get_node_position(hello->source)->y,get_node_position(hello->source)->z,
           get_time_now_second());//*/


    //l'ajoute de voisin
    if(!list_recherche(nodedata->N1,hello->source))
        list_insert(&nodedata->N1,hello->source);


    //REPONSE DE PAKET HELLO

    //recuperer le support de communication MAC
     entityid_t *down = get_entity_links_down(c);
     call_t c0 = {down[0], c->node};

     //destination de paquet
     destination_t destination = {hello->source, {get_node_position(hello->source)->x,get_node_position(hello->source)->y,get_node_position(hello->source)->z}};

     //creation de paquet et initialisation de son data
     packet_t *rpacket = packet_alloc(c, nodedata->overhead[0] + sizeof(struct packet_hello));
     struct packet_hello *rhello = (struct packet_hello *) (rpacket->data + nodedata->overhead[0]);

     //initilailser les données
     rhello->type     =   REP_HELLO;
     rhello->source   =   c->node;

     if (SET_HEADER(&c0, rpacket, &destination) == -1) {
         packet_dealloc(rpacket);
         return -1;
     }

     DEBUG;
     /*printf("Node %d (%lf %lf %lf) repond a %d  packet hello, at %lf\n", c->node,                               //id de Noeud de noeud encours
                get_node_position(c->node)->x,get_node_position(c->node)->y,get_node_position(c->node)->z,           //la postion x, y,z de Noeud
                hello->source,                                                                                       //id de noued de destination
                get_time_now_second()); //*/                                                                             //l'instant d'envoi.

     //L'envoi
     TX(&c0,rpacket);

    //liberer le packet
    packet_dealloc(packet);

    //tous c'est bien passé
    return 1;

}
/**
 * Deal with data sent by a node
 */
static void worldsens_tx_byte(struct _worldsens_c_byte_tx *pkt){
    uint64_t tx_start = ws_csync + pkt->period;
    uint64_t tx_end   = tx_start + pkt->duration;

    /* create packet */
    packet_t *packet;
    node_t   *node   = get_node_by_id(worldsens_get_wsnet_node_id(pkt->node_id));
    entity_t *entity = get_entity_by_id(pkt->antenna_id);
    call_t c = {entity->id, node->id, -1};

    /* put uint64_t into doubles to retrieve double value after swap */
    double *power_dbm = (double *) &(pkt->power_dbm);
    double *freq      = (double *) &(pkt->freq);  
    
    packet = packet_alloc(&c, 1);

    packet->clock0         =  tx_start;                /* tx start */
    packet->clock1         =  tx_end;                  /* tx end */
    packet->duration       =  pkt->duration;
    packet->node           =  node->id;                /* source */
    packet->antenna        =  pkt->antenna_id;
    packet->worldsens_mod  =  pkt->wsim_mod_id;        /* radio modulation in wsim. Better when it matches with wsnet modulation... */
    packet->channel        =  0;                       /* TODO: handle channel from wsim radio */
    packet->worldsens_freq = *freq;
    packet->txdBm          = *power_dbm;
    packet->Tb             =  pkt->duration / packet->real_size;
    *(packet->data)        =  pkt->data;

    if (pkt->wsnet_mod_id == -1)
        packet->modulation = ws_default_mod;
    else 
        packet->modulation = pkt->wsnet_mod_id;       /* modulation we are using in wsnet for calculation */

    /* log informations*/
    int iii;
    WSNET_S_DBG_DBG ("WSNET2:: <-- TX (%"PRId64") (src ip:%d,size:%d,data",
		     packet->clock0, pkt->node_id, packet->size);
    for(iii=0; iii<packet->size; iii++) {
        WSNET_S_DBG_DBG(":%02x", packet->data[ iii ] & 0xff);
    }
    WSNET_S_DBG_DBG (",duration:%"PRId64",freq:%ghz,wsim modul:%d,tx:%lgdbm)\n",
		     packet->duration, packet->worldsens_freq, packet->worldsens_mod, packet->txdBm);

    /* proceed TX */
    MEDIA_TX(&c, packet);

    /* reply by sending a backtrack or a rp reminder */
    worldsens_send_reply();

    return;
}
示例#11
0
int av_new_packet(AVPacket *pkt, int size)
{
    AVBufferRef *buf = NULL;
    int ret = packet_alloc(&buf, size);
    if (ret < 0)
        return ret;

    av_init_packet(pkt);
    pkt->buf      = buf;
    pkt->data     = buf->data;
    pkt->size     = size;

    return 0;
}
示例#12
0
文件: avpacket.c 项目: MythTV/mythtv
int av_packet_make_refcounted(AVPacket *pkt)
{
    int ret;

    if (pkt->buf)
        return 0;

    ret = packet_alloc(&pkt->buf, pkt->size);
    if (ret < 0)
        return ret;
    if (pkt->size)
        memcpy(pkt->buf->data, pkt->data, pkt->size);

    pkt->data = pkt->buf->data;

    return 0;
}
示例#13
0
static void sniff_rx(phy_status_t status)
{
    // Switch packets
    phy_packet_t *rx_packet = radio.sniff.pkt_buf + radio.sniff.pkt_index;
    radio.sniff.pkt_index = (radio.sniff.pkt_index + 1) % 2;

    // Enter RX again
    phy_status_t ret = phy_rx(platform_phy, 0,
            soft_timer_time() + soft_timer_ms_to_ticks(500),
            radio.sniff.pkt_buf + radio.sniff.pkt_index, sniff_rx);

    if (ret != PHY_SUCCESS)
    {
        log_error("PHY RX Failed");
    }

    if (status == PHY_SUCCESS)
    {
        // Send packet to serial
        packet_t *serial_pkt = packet_alloc(IOTLAB_SERIAL_PACKET_OFFSET);
        if (serial_pkt == NULL)
        {
            log_error("Failed to get a packet for sniffed RX");
            return;
        }

        uint8_t *data = serial_pkt->data;

        // Place timestamp, channel, RSSI, LQI, captured length, as header
        data = packer_uint32_pack(data,
                packer_uint32_hton(
                        iotlab_control_convert_time(rx_packet->timestamp)));
        *data++ = radio.current_channel;
        *data++ = rx_packet->rssi;
        *data++ = rx_packet->lqi;
        *data++ = rx_packet->length;
        memcpy(data, rx_packet->data, rx_packet->length);
        data += rx_packet->length;
        serial_pkt->length = data - serial_pkt->data;

        event_post(EVENT_QUEUE_APPLI, sniff_send_to_serial, serial_pkt);
    }
}
示例#14
0
文件: packet.c 项目: nomnom100/pom-ng
int packet_multipart_process(struct packet_multipart *multipart, struct proto_process_stack *stack, unsigned int stack_index) {

    struct packet *p = packet_alloc();
    if (!p) {
        packet_multipart_cleanup(multipart);
        return PROTO_ERR;
    }


    if (packet_buffer_alloc(p, multipart->cur, multipart->align_offset)) {
        packet_release(p);
        packet_multipart_cleanup(multipart);
        pom_oom(multipart->cur);
        return PROTO_ERR;
    }

    struct packet_multipart_pkt *tmp = multipart->head;
    for (; tmp; tmp = tmp->next) {
        if (tmp->offset + tmp->len > multipart->cur) {
            pomlog(POMLOG_DEBUG "Offset in packet fragment is bigger than packet size.");
            packet_release(p);
            packet_multipart_cleanup(multipart);
            return PROTO_INVALID;
        }
        memcpy(p->buff + tmp->offset, tmp->pkt->buff + tmp->pkt_buff_offset, tmp->len);
    }

    p->ts = multipart->tail->pkt->ts;

    p->multipart = multipart;
    p->len = multipart->cur;
    p->datalink = multipart->proto;
    p->input = multipart->head->pkt->input;
    stack[stack_index].pload = p->buff;
    stack[stack_index].plen = p->len;
    stack[stack_index].proto = p->datalink;

    int res = core_process_multi_packet(stack, stack_index, p);

    packet_release(p);

    return (res == PROTO_ERR ? POM_ERR : POM_OK);
}
示例#15
0
int av_new_packet(AVPacket *pkt, int size)
{
    AVBufferRef *buf = NULL;
    int ret = packet_alloc(&buf, size);
    if (ret < 0)
        return ret;

    av_init_packet(pkt);
    pkt->buf      = buf;
    pkt->data     = buf->data;
    pkt->size     = size;
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
    pkt->destruct = dummy_destruct_packet;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

    return 0;
}
示例#16
0
文件: avpacket.c 项目: MythTV/mythtv
int av_packet_make_writable(AVPacket *pkt)
{
    AVBufferRef *buf = NULL;
    int ret;

    if (pkt->buf && av_buffer_is_writable(pkt->buf))
        return 0;

    ret = packet_alloc(&buf, pkt->size);
    if (ret < 0)
        return ret;
    if (pkt->size)
        memcpy(buf->data, pkt->data, pkt->size);

    av_buffer_unref(&pkt->buf);
    pkt->buf  = buf;
    pkt->data = buf->data;

    return 0;
}
示例#17
0
static void poll_time(handler_arg_t arg)
{
    int32_t ed = 0;
    uint32_t timestamp = iotlab_control_convert_time(soft_timer_time());
    phy_ed(platform_phy, &ed);

    // Get packet if required
    if (radio.poll.serial_pkt == NULL)
    {
        radio.poll.serial_pkt = packet_alloc(IOTLAB_SERIAL_PACKET_OFFSET);
        if (radio.poll.serial_pkt == NULL)
        {
            log_error("Failed to get Packet");
            return;
        }
        memcpy(radio.poll.serial_pkt->data, &timestamp, 4);
        radio.poll.serial_pkt->length = 4;
    }

    // Append measurement
    radio.poll.serial_pkt->data[radio.poll.serial_pkt->length] = ed;
    radio.poll.serial_pkt->length++;

    // Increase count
    radio.poll.current_poll_in_pkt++;
    if (radio.poll.current_poll_in_pkt >= radio.poll.max_poll_per_pkt)
    {
        radio.poll.current_poll_in_pkt = 0;

        // Send
        if (iotlab_serial_send_frame(RADIO_NOTIF_POLLING, radio.poll.serial_pkt)
                != 1)
        {
            log_error("Failed to send serial log");
            packet_free(radio.poll.serial_pkt);
        }
        radio.poll.serial_pkt = NULL;
    }
}
示例#18
0
static void pkt_tick(handler_arg_t arg)
{
    // unused
    (void) arg;

    enum tdma_result res;

    /* ensure we're connected */
    if (mac_tdma_is_connected())
    {
        leds_on(LED_1);
    }
    else
    {
        leds_off(LED_1);
        return;
    }

    /* get a packet */
    packet_t *packet = packet_alloc(0);
    if (!packet)
    {
        log_error("Can't allocate a packet");
        return;
    }

    /* fill it */
    log_printf("Send packet %u\n", index);
    *(packet->data) = index++;
    packet->length = 1;

    /* send the packet to the coordinator */
    if ((res = mac_tdma_send(packet, 0, pkt_sent, packet)) != TDMA_OK)
    {
        packet_free(packet);
        log_printf("Packet sending failed %d\n", res);
    }
}
示例#19
0
int av_packet_ref(AVPacket *dst, AVPacket *src)
{
    int ret;

    ret = av_packet_copy_props(dst, src);
    if (ret < 0)
        return ret;

    if (!src->buf) {
        ret = packet_alloc(&dst->buf, src->size);
        if (ret < 0)
            goto fail;
        memcpy(dst->buf->data, src->data, src->size);
    } else
        dst->buf = av_buffer_ref(src->buf);

    dst->size = src->size;
    dst->data = dst->buf->data;
    return 0;
fail:
    av_packet_free_side_data(dst);
    return ret;
}
示例#20
0
static void
alloc_cb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
    struct client_context *client = container_of(handle, struct client_context,
                                                 handle);
    packet_alloc(&client->packet, buf);
}
示例#21
0
struct packet *login_packet(unsigned short sessid, char *hostname, char *username, char *password, char *newpassword, unsigned char reopen) {
	char pwd[256] = "";
	char npwd[256] = "";

	strcpy(pwd, password);
	if (newpassword) strcpy(npwd, newpassword);

	char *idx = index(pwd, ' ');
	if (idx) {
		// the user wants to change the password (separated by space)
		*idx = 0;
		strcpy(npwd, idx+1);
	}

	struct packet *ret = packet_alloc();
	ret->family = 0xf1;
	ret->unk1 = 0xe0;
	ret->dir = 0x04;
	ret->pltype = 0x00;
	ret->connid = 0;
	ret->subseq = 0;
	ret->unk2 = 0;
	ret->sessid = sessid;
	ret->tail = 0;

	ret->data = block_alloc();
	ret->data->id = 1;
	ret->data->data = NULL;
	ret->data->nchildren = 0;

	unsigned char xxx[1024];

	xxx[0] = 0x01;
	block_addchild(ret->data, "1", xxx, 1);

	*(unsigned short *)(xxx) = htons(0);
	*(unsigned short *)(xxx+2) = htons(0); // job nr.
	*(unsigned short *)(xxx+4) = htons(sessid);
	*(unsigned short *)(xxx+6) = htons(0);
	*(unsigned short *)(xxx+8) = htons(0);
	block_addchild(ret->data, "2", xxx, 0x0a);

	block_addchild(ret->data, "4-1", (unsigned char *)hostname, strlen(hostname));

	memset(xxx, 0xff, 0x01b8);
	block_addchild(ret->data, "4-3-1", xxx, 0x01b8);

	memset(xxx, 0x00, 2);
	block_addchild(ret->data, "4-3-2-1", xxx, 2);

	block_addchild(ret->data, "4-3-2-2", (unsigned char *)username, strlen(username));

	block_addchild(ret->data, "4-3-2-3", (unsigned char *)pwd, strlen(pwd));
	if (strlen(npwd)) {
		block_addchild(ret->data, "4-3-2-4", (unsigned char *)npwd, strlen(npwd));
	}

	xxx[0] = reopen;
	block_addchild(ret->data, "4-3-2-5", xxx, 1);

	return ret;
}
示例#22
0
void packet_handle_request(struct IOFileSys *iofs, struct PacketBase *PacketBase) {
    struct ph_handle *handle;
    struct ph_packet *pkt;
    struct DosPacket *dp;

    D(bug("[packet] got io request %d (%s)\n", iofs->IOFS.io_Command, fsa_str(iofs->IOFS.io_Command)));

    /* get our data back */
    handle = (struct ph_handle *) iofs->IOFS.io_Unit;

    /* make a fresh new packet */
    pkt = packet_alloc();
    dp = &(pkt->dp);

    /* hook the iofs up to the packet so we can find it on return
     * dp_Arg7 should be unused; DoPkt() doesn't touch it */
    dp->dp_Arg7 = (IPTR) iofs;

    /* our reply port will cause packet_reply() to be called when they reply */
    dp->dp_Port = &(handle->mount->reply_port);

    /* convert the command */
    switch (iofs->IOFS.io_Command) {

        case FSA_OPEN:
            D(bug("[packet] OPEN: lock 0x%08x (%s) name '%s' type %s\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_OPEN.io_Filename,
                (iofs->io_Union.io_OPEN.io_FileMode & FMF_LOCK) ? "EXCLUSIVE" : "SHARED"));

            if (!handle->is_lock) {
                /* If passed a filehandle, we can only deal with locking the
                 * filehandle itself or its parent (unless we were to resort
                 * to sending multiple packets)
                 */
                if (iofs->io_Union.io_OPEN.io_Filename[0] == '\0') {
                    dp->dp_Type = ACTION_COPY_DIR_FH;
                    dp->dp_Arg1 = (IPTR) handle->actual;
                }
                else if (iofs->io_Union.io_OPEN.io_Filename[0] == '/' &&
                    iofs->io_Union.io_OPEN.io_Filename[1] == '\0') {
                    dp->dp_Type = ACTION_PARENT_FH;
                    dp->dp_Arg1 = (IPTR) handle->actual;
                }
                else {
                    iofs->io_DosError = ERROR_NOT_IMPLEMENTED;
                    goto reply;
                }
            }
            else {
                dp->dp_Type = ACTION_LOCATE_OBJECT;
                dp->dp_Arg1 = (IPTR) handle->actual;
                dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_OPEN.io_Filename);
                dp->dp_Arg3 = (iofs->io_Union.io_OPEN.io_FileMode & FMF_LOCK) ? EXCLUSIVE_LOCK : SHARED_LOCK;
            }

            break;

        case FSA_OPEN_FILE: {
            ULONG mode = iofs->io_Union.io_OPEN_FILE.io_FileMode;
            struct ph_handle *new_handle;

            D(bug("[packet] OPEN_FILE: lock 0x%08x (%s) name '%s' mode 0x%x prot 0x%x\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_OPEN_FILE.io_Filename,
                mode,
                iofs->io_Union.io_OPEN_FILE.io_Protection));

            /* convert modes to the proper packet type (as best we can) */
            if ((mode & FMF_CLEAR) != 0)
                dp->dp_Type = ACTION_FINDOUTPUT;
            else if ((mode & FMF_CREATE) != 0)
                dp->dp_Type = ACTION_FINDUPDATE;
            else
                dp->dp_Type = ACTION_FINDINPUT;
            if ((mode & FMF_APPEND) != 0) {
                iofs->io_DosError = ERROR_BAD_NUMBER;
                goto reply;
            }

            /* make a new handle */
            new_handle =
                (struct ph_handle *) AllocMem(sizeof(struct ph_handle),
                MEMF_PUBLIC | MEMF_CLEAR);
            if (new_handle == NULL) {
                iofs->io_DosError = ERROR_NO_FREE_STORE;
                goto reply;
            }

            /* dos.lib buffer stuff, must be initialised this way */
            new_handle->fh.fh_Pos = new_handle->fh.fh_End = (UBYTE *) -1;

            dp->dp_Arg1 = (IPTR) MKBADDR(&new_handle->fh);
            dp->dp_Arg2 = (IPTR) (handle->is_lock ? handle->actual : NULL);
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_OPEN.io_Filename);

            break;
        }

        case FSA_CLOSE:
            D(bug("[packet] CLOSE: lock 0x%08x (%s)\n",
                handle->actual, handle_desc(handle)));

            /* if this is the root handle, then we previously intercepted a
             * call and returned it (e.g. FSA_OPEN/ACTION_PARENT), so we don't
             * want the handler to do anything */
            if (handle == &(handle->mount->root_handle)) {
                iofs->IOFS.io_Unit = NULL;
                goto reply;
            }

            dp->dp_Type = (handle->is_lock) ? ACTION_FREE_LOCK : ACTION_END;
            dp->dp_Arg1 = (IPTR) handle->actual;
            break;

        case FSA_READ:
            D(bug("[packet] READ: handle 0x%08x buf 0x%08x len %ld\n",
                handle->actual,
                iofs->io_Union.io_READ.io_Buffer,
                iofs->io_Union.io_READ.io_Length));

            dp->dp_Type = ACTION_READ;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_READ.io_Buffer;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_READ.io_Length;

            /* DOSFALSE == 0, so we can't distinguish between a zero-length
             * read and an actual error. So, we reset the length here. If the
             * returned packet is DOSFALSE, but no error, this will make sure
             * DOS gets the right length back */
            iofs->io_Union.io_READ.io_Length = 0;
            break;

        case FSA_WRITE:
            D(bug("[packet] WRITE: handle 0x%08x buf 0x%08x len %ld\n",
                handle->actual,
                iofs->io_Union.io_WRITE.io_Buffer,
                iofs->io_Union.io_WRITE.io_Length));

            dp->dp_Type = ACTION_WRITE;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_WRITE.io_Buffer;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_WRITE.io_Length;

            iofs->io_Union.io_WRITE.io_Length = 0;
            break;

        case FSA_SEEK:
#if defined(DEBUG) && DEBUG != 0
        {
            ULONG mode = iofs->io_Union.io_SEEK.io_SeekMode;

            bug("[packet] SEEK: handle 0x%08x offset %ld mode %ld (%s)\n",
                handle->actual,
                (LONG) iofs->io_Union.io_SEEK.io_Offset,
                mode,
                mode == OFFSET_BEGINNING ? "OFFSET_BEGINNING" :
                mode == OFFSET_CURRENT   ? "OFFSET_CURRENT"   :
                mode == OFFSET_END       ? "OFFSET_END"       :
                                           "[unknown]");
        }
#endif

            dp->dp_Type = ACTION_SEEK;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_SEEK.io_Offset;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_SEEK.io_SeekMode;
            break;

        case FSA_SET_FILE_SIZE:
#if defined(DEBUG) && DEBUG != 0
        {
            ULONG mode = iofs->io_Union.io_SET_FILE_SIZE.io_SeekMode;

            bug("[packet] SET_FILE_SIZE: handle 0x%08x offset %ld mode %ld (%s)\n",
                handle->actual,
                (LONG) iofs->io_Union.io_SET_FILE_SIZE.io_Offset,
                mode,
                mode == OFFSET_BEGINNING ? "OFFSET_BEGINNING" :
                mode == OFFSET_CURRENT   ? "OFFSET_CURRENT"   :
                mode == OFFSET_END       ? "OFFSET_END"       :
                                           "[unknown]");
        }
#endif

            dp->dp_Type = ACTION_SET_FILE_SIZE;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_SET_FILE_SIZE.io_Offset;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_SET_FILE_SIZE.io_SeekMode;
            break;

        case FSA_FILE_MODE: {

            D(bug("[packet] FILE_MODE: object 0x%08x (%s) mode 0x%x\b\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_FILE_MODE.io_FileMode));

            dp->dp_Type = ACTION_CHANGE_MODE;

            /* We can only change access mode */
            if ((iofs->io_Union.io_FILE_MODE.io_Mask & FMF_LOCK) == 0) {
                iofs->io_DosError = 0;
                goto reply;
            }
            if (handle->is_lock) {
                dp->dp_Arg1 = CHANGE_LOCK;
                dp->dp_Arg2 = (IPTR) handle->actual;
            }
            else {
                dp->dp_Arg1 = CHANGE_FH;
                handle->fh.fh_Arg1 = (IPTR) handle->actual;
                dp->dp_Arg2 = (IPTR) MKBADDR(&handle->fh);
            }
            dp->dp_Arg3 = (iofs->io_Union.io_FILE_MODE.io_FileMode & FMF_LOCK) ?
                EXCLUSIVE_LOCK : SHARED_LOCK;

            break;
        }

        case FSA_IS_INTERACTIVE:
            /* XXX is there some other way to query this? how does (eg) aos
             * console handler do it? */
            iofs->io_Union.io_IS_INTERACTIVE.io_IsInteractive = FALSE;
            iofs->io_DosError = 0;
            goto reply;

        case FSA_SAME_LOCK: {
            struct ph_handle *h1, *h2;
            h1 = (struct ph_handle *) iofs->io_Union.io_SAME_LOCK.io_Lock[0];
            h2 = (struct ph_handle *) iofs->io_Union.io_SAME_LOCK.io_Lock[1];

            D(bug("[packet] SAME_LOCK: lock1 0x%08x (%s) lock2 0x%08x (%s)\n",
                h1->actual, handle_desc(h1), h2->actual, handle_desc(h2)));

            dp->dp_Type = ACTION_SAME_LOCK;
            dp->dp_Arg1 = (IPTR) h1->actual;
            dp->dp_Arg2 = (IPTR) h2->actual;
            break;
        }

        case FSA_EXAMINE: {
            struct FileInfoBlock *fib;

            D(bug("[packet] EXAMINE: lock 0x%08x (%s)\n",
                handle->actual, handle_desc(handle)));

            fib = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC | MEMF_CLEAR);

            dp->dp_Type = (handle->is_lock) ? ACTION_EXAMINE_OBJECT : ACTION_EXAMINE_FH;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) MKBADDR(fib);
            break;
        }

        case FSA_EXAMINE_NEXT:
            D(bug("[packet] EXAMINE_NEXT: lock 0x%08x (%s) fib 0x%08x\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_EXAMINE_NEXT.io_fib));

            dp->dp_Type = ACTION_EXAMINE_NEXT;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) MKBADDR(iofs->io_Union.io_EXAMINE_NEXT.io_fib);
            break;

        case FSA_CREATE_DIR:
            D(bug("[packet] CREATE_DIR: lock 0x%08x (%s) name '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_CREATE_DIR.io_Filename));

            dp->dp_Type = ACTION_CREATE_DIR;
            dp->dp_Arg1 = (IPTR) (handle->is_lock ? handle->actual : NULL);
            dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_CREATE_DIR.io_Filename);
            break;

        case FSA_IS_FILESYSTEM:
            dp->dp_Type = ACTION_IS_FILESYSTEM;
            break;

        case FSA_DISK_INFO:
            dp->dp_Type = ACTION_DISK_INFO;
            dp->dp_Arg1 = (IPTR) MKBADDR(iofs->io_Union.io_INFO.io_Info);
            break;

        case FSA_CREATE_HARDLINK:
            {
                struct ph_handle *target = (struct ph_handle *)
                    iofs->io_Union.io_CREATE_HARDLINK.io_OldFile;

                D(bug("[packet] CREATE_HARDLINK: lock 0x%08x (%s) name '%s' "
                    "target 0x%08x (%s)\n",
                    handle->actual, handle_desc(handle),
                    iofs->io_Union.io_CREATE_HARDLINK.io_Filename,
                    target->actual, handle_desc(target)));

                dp->dp_Type = ACTION_MAKE_LINK;
                dp->dp_Arg1 = (IPTR) handle->actual;
                dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool,
                    iofs->io_Union.io_CREATE_HARDLINK.io_Filename);
                dp->dp_Arg3 = (IPTR) target->actual;
                dp->dp_Arg4 = LINK_HARD;
                break;
            }

        case FSA_CREATE_SOFTLINK:
            D(bug("[packet] CREATE_SOFTLINK: lock 0x%08x (%s) name '%s' target '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_CREATE_SOFTLINK.io_Filename,
                iofs->io_Union.io_CREATE_SOFTLINK.io_Reference));

            dp->dp_Type = ACTION_MAKE_LINK;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_CREATE_SOFTLINK.io_Filename);
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_CREATE_SOFTLINK.io_Reference;
            dp->dp_Arg4 = LINK_SOFT;
            break;

        case FSA_RENAME:
            D(bug("[packet] RENAME: lock 0x%08x (%s) name '%s' target '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_RENAME.io_Filename,
                iofs->io_Union.io_RENAME.io_NewName));

            /* XXX the two paths from FSA_RENAME are copied directly from the
             * arguments to rename with no changes, so they may contain volume
             * specifiers, path seperators, etc. both can be calculated
             * relative to the handle. here we just pass them through to the
             * handler as-is, but I'm not sure if that's right. fat.handler at
             * least will do the right thing. this probably needs to be
             * revisited if another packet-based handler is ported */

            dp->dp_Type = ACTION_RENAME_OBJECT;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_RENAME.io_Filename);
            dp->dp_Arg3 = (IPTR) handle->actual;
            dp->dp_Arg4 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_RENAME.io_NewName);
            break;

        case FSA_READ_SOFTLINK:
            D(bug("[packet] READ_SOFTLINK: lock 0x%08x (%s) name '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_READ_SOFTLINK.io_Filename));

            dp->dp_Type = ACTION_READ_LINK;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_READ_SOFTLINK.io_Filename;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_READ_SOFTLINK.io_Buffer;
            dp->dp_Arg4 = (IPTR) iofs->io_Union.io_READ_SOFTLINK.io_Size;
            break;

        case FSA_DELETE_OBJECT:
            D(bug("[packet] DELETE: lock 0x%08x (%s) name '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_DELETE_OBJECT.io_Filename));

            dp->dp_Type = ACTION_DELETE_OBJECT;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_DELETE_OBJECT.io_Filename);
            break;

        case FSA_SET_COMMENT:
            D(bug("[packet] SET_COMMENT: lock 0x%08x (%s) name '%s' comment '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_SET_COMMENT.io_Filename,
                iofs->io_Union.io_SET_COMMENT.io_Comment));

            dp->dp_Type = ACTION_SET_COMMENT;
            dp->dp_Arg1 = 0;
            dp->dp_Arg2 = (IPTR) handle->actual;
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_COMMENT.io_Filename);
            dp->dp_Arg4 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_COMMENT.io_Comment);
            break;
            
        case FSA_SET_PROTECT:
            D(bug("[packet] SET_PROTECT: lock 0x%08x (%s) name '%s' attrs 0x%x\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_SET_PROTECT.io_Filename,
                iofs->io_Union.io_SET_PROTECT.io_Protection));

            dp->dp_Type = ACTION_SET_PROTECT;
            dp->dp_Arg1 = 0;
            dp->dp_Arg2 = (IPTR) handle->actual;
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_PROTECT.io_Filename);
            dp->dp_Arg4 = (IPTR) iofs->io_Union.io_SET_PROTECT.io_Protection;
            break;

        case FSA_SET_OWNER: /* XXX untested */
            D(bug("[packet] SET_OWNER: lock 0x%08x (%s) name '%s' uid 0x%x gid 0x%x\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_SET_OWNER.io_Filename,
                iofs->io_Union.io_SET_OWNER.io_UID,
                iofs->io_Union.io_SET_OWNER.io_GID));

            dp->dp_Type = ACTION_SET_OWNER;
            dp->dp_Arg1 = 0;
            dp->dp_Arg2 = (IPTR) handle->actual;
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_OWNER.io_Filename);
            dp->dp_Arg4 = (IPTR) iofs->io_Union.io_SET_OWNER.io_GID << 16 |
                                 iofs->io_Union.io_SET_OWNER.io_UID;
            break;

        case FSA_SET_DATE: /* XXX untested */
#if defined(DEBUG) && DEBUG != 0
        {
            struct DateTime dt;
            char datestr[LEN_DATSTRING];

            dt.dat_Stamp = iofs->io_Union.io_SET_DATE.io_Date;
            dt.dat_Format = FORMAT_DOS;
            dt.dat_Flags = 0;
            dt.dat_StrDay = NULL;
            dt.dat_StrDate = datestr;
            dt.dat_StrTime = NULL;
            DateToStr(&dt);

            bug("[packet] SET_DATE: lock 0x%08x (%s) name '%s' date '%s'\n",
                handle->actual, handle_desc(handle),
                iofs->io_Union.io_SET_DATE.io_Filename,
                datestr);
        }
#endif

            dp->dp_Type = ACTION_SET_DATE;
            dp->dp_Arg1 = 0;
            dp->dp_Arg2 = (IPTR) handle->actual;
            dp->dp_Arg3 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_SET_DATE.io_Filename);
            dp->dp_Arg4 = (IPTR) &iofs->io_Union.io_SET_DATE.io_Date;
            break;

        case FSA_MORE_CACHE: /* XXX untested */
            D(bug("[packet] MORE_CACHE: buffers '0x%x'\n", iofs->io_Union.io_MORE_CACHE.io_NumBuffers));

            dp->dp_Type = ACTION_MORE_CACHE;
            dp->dp_Arg1 = (IPTR) iofs->io_Union.io_MORE_CACHE.io_NumBuffers;
            break;

        case FSA_FORMAT: /* XXX untested */
            D(bug("[packet] FSA_FORMAT: name '%s' type 0x%x\n",
                  iofs->io_Union.io_FORMAT.io_VolumeName,
                  iofs->io_Union.io_FORMAT.io_DosType));

            dp->dp_Type = ACTION_FORMAT;
            dp->dp_Arg1 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_FORMAT.io_VolumeName);
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_FORMAT.io_DosType;
            break;

        case FSA_INHIBIT:
            D(bug("[packet] FSA_INHIBIT: %sinhibit\n", iofs->io_Union.io_INHIBIT.io_Inhibit == 0 ? "un" : ""));

            dp->dp_Type = ACTION_INHIBIT;
            dp->dp_Arg1 = iofs->io_Union.io_INHIBIT.io_Inhibit ? DOSTRUE : DOSFALSE;
            break;

        case FSA_RELABEL:
            D(bug("[packet] FSA_RELABEL: name '%s'\n", iofs->io_Union.io_RELABEL.io_NewName));

            dp->dp_Type = ACTION_RENAME_DISK;
            dp->dp_Arg1 = (IPTR) mkbstr(pkt->pool, iofs->io_Union.io_RELABEL.io_NewName);
            break;

        case FSA_LOCK_RECORD: /* XXX untested */
#if defined(DEBUG) && DEBUG != 0
        {
            ULONG mode = iofs->io_Union.io_RECORD.io_RecordMode;

            bug("[packet] FSA_LOCK_RECORD: handle 0x%08x offset %ld size %ld mode %d (%s) timeout %d\n",
                handle->actual,
                (LONG) iofs->io_Union.io_RECORD.io_Offset,
                iofs->io_Union.io_RECORD.io_Size,
                mode,
                mode == REC_EXCLUSIVE       ? "REC_EXCLUSIVE"       :
                mode == REC_EXCLUSIVE_IMMED ? "REC_EXCLUSIVE_IMMED" :
                mode == REC_SHARED          ? "REC_SHARED"          :
                mode == REC_SHARED_IMMED    ? "REC_SHARED_IMMED"    :
                                              "[unknown]",
                iofs->io_Union.io_RECORD.io_Timeout);
        }
#endif

            dp->dp_Type = ACTION_LOCK_RECORD;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_RECORD.io_Offset;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_RECORD.io_Size;
            dp->dp_Arg4 = (IPTR) iofs->io_Union.io_RECORD.io_RecordMode;
            dp->dp_Arg5 = (IPTR) iofs->io_Union.io_RECORD.io_Timeout;
            break;

        case FSA_UNLOCK_RECORD: /* XXX untested */
            D(bug("[packet] FSA_UNLOCK_RECORD: handle 0x%08x offset %ld size %ld\n",
                  handle->actual,
                  (LONG) iofs->io_Union.io_RECORD.io_Offset,
                  iofs->io_Union.io_RECORD.io_Size));

            dp->dp_Type = ACTION_FREE_RECORD;
            dp->dp_Arg1 = (IPTR) handle->actual;
            dp->dp_Arg2 = (IPTR) iofs->io_Union.io_RECORD.io_Offset;
            dp->dp_Arg3 = (IPTR) iofs->io_Union.io_RECORD.io_Size;
            break;

        case FSA_ADD_NOTIFY:
            D(bug("[packet] FSA_ADD_NOTIFY: nr 0x%08x name '%s'\n", 
                  iofs->io_Union.io_NOTIFY.io_NotificationRequest,
                  iofs->io_Union.io_NOTIFY.io_NotificationRequest->nr_FullName));

            dp->dp_Type = ACTION_ADD_NOTIFY;
            dp->dp_Arg1 =
                (SIPTR) iofs->io_Union.io_NOTIFY.io_NotificationRequest;
            break;

        case FSA_REMOVE_NOTIFY:
            D(bug("[packet] FSA_REMOVE_NOTIFY: nr 0x%08x name '%s'\n", 
                  iofs->io_Union.io_NOTIFY.io_NotificationRequest,
                  iofs->io_Union.io_NOTIFY.io_NotificationRequest->nr_FullName));

            dp->dp_Type = ACTION_REMOVE_NOTIFY;
            dp->dp_Arg1 =
                (SIPTR) iofs->io_Union.io_NOTIFY.io_NotificationRequest;
            break;

        /* XXX implement */
        case FSA_EXAMINE_ALL:
        case FSA_EXAMINE_ALL_END:
        case FSA_MOUNT_MODE:
        case FSA_CHANGE_SIGNAL:
        case FSA_PARENT_DIR:
        case FSA_PARENT_DIR_POST:
        case FSA_CONSOLE_MODE:
            D(bug("[packet] command not implemented\n"));
            iofs->io_DosError = ERROR_NOT_IMPLEMENTED;
            goto reply;

        default:
            D(bug("[packet] unknown command\n"));
            iofs->io_DosError = ERROR_ACTION_NOT_KNOWN;
            goto reply;
    }

    D(bug("[packet] converted to %s packet\n", act_str(dp->dp_Type)));

    /* WaitIO() will look into this */
    iofs->IOFS.io_Message.mn_Node.ln_Type = NT_MESSAGE;

    /* since these all go to the packet handler process, they can't be done now */
    iofs->IOFS.io_Flags &= ~IOF_QUICK;

    /* send the packet */
    PutMsg(&(handle->mount->process->pr_MsgPort), dp->dp_Link);

    return;

    /* jump here to reply to the packet now, handling IOF_QUICK appropriately */
reply:
    D(bug("[packet] replying directly with error %d\n", iofs->io_DosError));
    
    /* kill the packet */
    DeletePool(pkt->pool);

    /* if they can handle quick replies, just bail out */
    if (iofs->IOFS.io_Flags & IOF_QUICK)
        return;

    /* otherwise tell them properly */
    ReplyMsg((APTR) iofs);
}
示例#23
0
static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
				      pkt_sock_mmap_t *pkt_sock,
				      odp_packet_t pkt_table[], unsigned len,
				      unsigned char if_mac[])
{
	union frame_map ppd;
	unsigned frame_num, next_frame_num;
	uint8_t *pkt_buf;
	int pkt_len;
	struct ethhdr *eth_hdr;
	unsigned i = 0;
	uint8_t nb_rx = 0;
	struct ring *ring;
	int ret;

	ring  = &pkt_sock->rx_ring;
	frame_num = ring->frame_num;

	while (i < len) {
		if (!mmap_rx_kernel_ready(ring->rd[frame_num].iov_base))
			break;

		ppd.raw = ring->rd[frame_num].iov_base;
		next_frame_num = (frame_num + 1) % ring->rd_num;

		pkt_buf = (uint8_t *)ppd.raw + ppd.v2->tp_h.tp_mac;
		pkt_len = ppd.v2->tp_h.tp_snaplen;

		/* Don't receive packets sent by ourselves */
		eth_hdr = (struct ethhdr *)pkt_buf;
		if (odp_unlikely(ethaddrs_equal(if_mac,
						eth_hdr->h_source))) {
			mmap_rx_user_ready(ppd.raw); /* drop */
			frame_num = next_frame_num;
			continue;
		}

		if (pktio_cls_enabled(pktio_entry)) {
			ret = _odp_packet_cls_enq(pktio_entry, pkt_buf,
						  pkt_len, &pkt_table[nb_rx]);
			if (ret)
				nb_rx++;
		} else {
			odp_packet_hdr_t *hdr;

			pkt_table[i] = packet_alloc(pkt_sock->pool, pkt_len, 1);
			if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID)) {
				mmap_rx_user_ready(ppd.raw); /* drop */
				frame_num = next_frame_num;
				continue;
			}
			hdr = odp_packet_hdr(pkt_table[i]);
			ret = odp_packet_copydata_in(pkt_table[i], 0,
						     pkt_len, pkt_buf);
			if (ret != 0) {
				odp_packet_free(pkt_table[i]);
				mmap_rx_user_ready(ppd.raw); /* drop */
				frame_num = next_frame_num;
				continue;
			}

			packet_parse_l2(hdr);
			nb_rx++;
		}

		mmap_rx_user_ready(ppd.raw);
		frame_num = next_frame_num;
		i++;
	}

	ring->frame_num = frame_num;
	return nb_rx;
}
示例#24
0
static int input_kismet_drone_read(struct input *i) {

	struct input_kismet_drone_priv *priv = i->priv;

	if (priv->fd == -1)
		return POM_ERR;

	while (1) {
		struct kismet_drone_packet kpkt;
		if (pom_read(priv->fd, &kpkt, sizeof(struct kismet_drone_packet)) != POM_OK)
			return POM_ERR;

		if (ntohl(kpkt.sentinel) != KISMET_DRONE_SENTINEL) {
			pomlog(POMLOG_ERR "Invalid sentinel value : 0x%X, expected 0x%X", kpkt.sentinel, KISMET_DRONE_SENTINEL);
			return POM_ERR;
		}

		enum kismet_drone_cmd cmdnum = ntohl(kpkt.drone_cmdnum);
		uint32_t data_len = ntohl(kpkt.data_len);

		debug_kismet("CMD %u, data_len %u", cmdnum, data_len);

		switch (cmdnum) {
			case kismet_drone_cmd_hello: {
				if (data_len != sizeof(struct kismet_drone_packet_hello)) {
					pomlog(POMLOG_ERR "Invalid length for hello packet : got %u, expected %u", data_len, sizeof(struct kismet_drone_packet_hello));
					return POM_ERR;
				}
				struct kismet_drone_packet_hello hello_pkt;
				if (pom_read(priv->fd, &hello_pkt, sizeof(struct kismet_drone_packet_hello)) != POM_OK)
					return POM_ERR;
				char version[33] = { 0 };
				strncpy(version, hello_pkt.kismet_version, 32);
				char hostname[33] = { 0 };
				strncpy(hostname, hello_pkt.host_name, 32);
				pomlog("Input %s connected to Kismet %s on %s (drone version %u)", i->name, version, hostname, ntohl(hello_pkt.drone_version));
				break;

			}
			case kismet_drone_cmd_source: {
				if (data_len != sizeof(struct kismet_drone_packet_source)) {
					pomlog(POMLOG_ERR "Invalid length for source packet : got %u, expected %u", data_len, sizeof(struct kismet_drone_packet_source));
					return POM_ERR;
				}
				struct kismet_drone_packet_source source_pkt;
				if (pom_read(priv->fd, &source_pkt, sizeof(struct kismet_drone_packet_source)) != POM_OK)
					return POM_ERR;

				if (source_pkt.invalidate) {
					// TODO
					return POM_ERR;
				}

				struct kismet_drone_source *src = malloc(sizeof(struct kismet_drone_source));
				if (!src) {
					pom_oom(sizeof(struct kismet_drone_source));
					return POM_ERR;
				}
				memset(src, 0, sizeof(struct kismet_drone_source));
				
				memcpy(src->uuid, source_pkt.uuid, sizeof(src->uuid));
				src->name = strndup(source_pkt.name_str, sizeof(source_pkt.name_str));
				src->interface = strndup(source_pkt.interface_str, sizeof(source_pkt.interface_str));
				src->type = strndup(source_pkt.type_str, sizeof(source_pkt.type_str));
				if (!src->name || !src->interface || !src->type) {
					if (src->name)
						free(src->name);
					if (src->interface)
						free(src->interface);
					if (src->type)
						free(src->type);
					free(src);
					pom_oom(sizeof(source_pkt.name_str));
					return POM_ERR;
				}

				pomlog("New Kismet drone source for input %s : %s (interface: %s, type: %s)", i->name, src->name, src->interface, src->type);

				if (source_pkt.channel_hop && !source_pkt.channel_dwell) {
					pomlog(POMLOG_WARN "Warning, source %s from input %s is configured to hop channels without dwelling !", i->name, src->name);
				}

				src->next = priv->srcs;
				if (priv->srcs)
					priv->srcs->prev = src;
				priv->srcs = src;

				break;
			}

			case kismet_drone_cmd_cappacket: {
				if (data_len < sizeof(struct kismet_drone_packet_capture)) {
					pomlog(POMLOG_ERR "Packet capture data length too small");
					return POM_ERR;
				}
				struct kismet_drone_packet_capture capture_pkt;
				if (pom_read(priv->fd, &capture_pkt, sizeof(struct kismet_drone_packet_capture)) != POM_OK)
					return POM_ERR;

				debug_kismet("Capture packet bitmap 0x%X, offset %u", ntohl(capture_pkt.content_bitmap), ntohl(capture_pkt.packet_offset));

				data_len -= sizeof(struct kismet_drone_packet_capture);

				uint32_t bitmap = ntohl(capture_pkt.content_bitmap);

				if (!(bitmap & KISMET_DRONE_BIT_DATA_IEEEPACKET)) {
					debug_kismet("No data in this packet, skipping %u bytes of data", data_len);
					if (input_kismet_drone_discard_bytes(priv, data_len) != POM_OK)
						return POM_ERR;
					break;
				}

				uint32_t offset = ntohl(capture_pkt.packet_offset);
				if (offset > data_len) {
					pomlog(POMLOG_ERR "Packet offset bigger than expected length");
					return POM_ERR;
				}

				if (input_kismet_drone_discard_bytes(priv, offset) != POM_OK)
					return POM_ERR;

				data_len -= offset;

				if (data_len < sizeof(struct kismet_drone_sub_packet_data)) {
					pomlog(POMLOG_ERR "Remaining data smaller than sub_packet_data");
					return POM_ERR;
				}

				struct kismet_drone_sub_packet_data data_pkt;
				if (pom_read(priv->fd, &data_pkt, sizeof(struct kismet_drone_sub_packet_data)) != POM_OK)
					return POM_ERR;

				data_len -= sizeof(struct kismet_drone_sub_packet_data);

				debug_kismet("Capture data packet bitmap 0x%X, hdr len %u, pkt len %u", ntohl(data_pkt.content_bitmap), ntohs(data_pkt.data_hdr_len), ntohs(data_pkt.packet_len));

				size_t pkt_len = ntohs(data_pkt.packet_len);

				if (pkt_len > data_len) {
					pomlog(POMLOG_ERR "Data packet length bigger than expected data size");
					return POM_ERR;
				}

				uint32_t dlt = ntohl(data_pkt.dlt);
				struct proto *datalink = NULL;
				switch (dlt) {
					case DLT_IEEE802_11:
						datalink = priv->datalink_80211;
						break;
					case DLT_IEEE802_11_RADIO:
						datalink = priv->datalink_radiotap;
						break;
					default:
						pomlog(POMLOG_ERR "Unexpected DLT received : %u", dlt);
						return POM_ERR;
				}

				struct packet *pkt = packet_alloc();
				if (!pkt)
					return POM_ERR;

				if (packet_buffer_alloc(pkt, pkt_len, 0) != POM_OK) {
					packet_release(pkt);
					return POM_ERR;
				}

				pkt->input = i;
				pkt->datalink = datalink;
				pkt->ts = (ntohll(data_pkt.tv_sec) *  1000000UL) + ntohll(data_pkt.tv_usec);

				if (pom_read(priv->fd, pkt->buff, pkt_len) != POM_OK)
					return POM_ERR;

				return core_queue_packet(pkt, 0, 0);
			}

			default: {
				if (input_kismet_drone_discard_bytes(priv, data_len) != POM_OK)
					return POM_ERR;
				break;
			}
		}


	}

	return POM_OK;

}
示例#25
0
static int input_pcap_read(struct input *i) {

	struct input_pcap_priv *p = i->priv;

	if (p->type == input_pcap_type_dir && !p->tpriv.dir.files) {
		if (input_pcap_dir_open(i) != POM_OK) {
			// Don't error out if the scan was interrupted
			if (p->tpriv.dir.interrupt_scan)
				return POM_OK;
			return POM_ERR;
		}
	}

	struct pcap_pkthdr *phdr;
	const u_char *data;
	int result = pcap_next_ex(p->p, &phdr, &data);
	if (phdr->len > phdr->caplen && !p->warning) {
		pomlog(POMLOG_WARN "Warning, some packets were truncated at capture time on input %s", i->name);
		p->warning = 1;
	}

	if (result < 0) { // End of file or error 

		if (p->type == input_pcap_type_dir) {

			if (result != -2)
				pomlog(POMLOG_WARN "Error while reading packet from file : %s. Moving on the next file ...", pcap_geterr(p->p), p->tpriv.dir.cur_file->filename);
			
			pcap_close(p->p);
			p->p = NULL;
			p->warning = 0;

			if (input_pcap_dir_open_next(p) != POM_OK)
				return POM_ERR;

			if (!p->tpriv.dir.cur_file) {
				// No more file
				return input_stop(i);
			}

			result = pcap_next_ex(p->p, &phdr, &data);
			if (result < 0) {
				pomlog(POMLOG_ERR "Error while reading first packet of new file");
				return POM_ERR;
			}
		} else {
			if (result == -2) // EOF
				return input_stop(i);

			pomlog(POMLOG_ERR "Error while reading file : %s", pcap_geterr(p->p));
			return POM_ERR;
		}
	}

	if (result == 0) // Timeout
		return POM_OK;

	struct packet *pkt = packet_alloc();
	if (!pkt)
		return POM_ERR;

	if (packet_buffer_alloc(pkt, phdr->caplen - p->skip_offset, p->align_offset) != POM_OK) {
		packet_release(pkt);
		return POM_ERR;
	}

	pkt->input = i;
	pkt->datalink = p->datalink_proto;
	pkt->ts = pom_timeval_to_ptime(phdr->ts);
	memcpy(pkt->buff, data + p->skip_offset, phdr->caplen - p->skip_offset);

	unsigned int flags = 0, affinity = 0;

	if (p->type == input_pcap_type_interface)
		flags = CORE_QUEUE_DROP_IF_FULL;

#ifdef DLT_MPEG_2_TS
	if (p->datalink_type == DLT_MPEG_2_TS) {
		// MPEG2 TS has thread affinity based on the PID
		flags |= CORE_QUEUE_HAS_THREAD_AFFINITY;
		affinity = ((((char*)pkt->buff)[1] & 0x1F) << 8) | ((char *)pkt->buff)[2];
	}
#endif

	return core_queue_packet(pkt, flags, affinity);
}