Beispiel #1
0
void
aoead(int fd)	// advertise the virtual blade
{
	uchar buf[2000];
	Conf *p;
	int i;

	p = (Conf *)buf;
	memset(p, 0, sizeof *p);
	memset(p->h.dst, 0xff, 6);
	memmove(p->h.src, mac, 6);
	p->h.type = htons(0x88a2);
	p->h.flags = Resp;
	p->h.maj = htons(shelf);
	p->h.min = slot;
	p->h.cmd = Config;
	p->bufcnt = htons(bufcnt);
	p->scnt = maxscnt = (getmtu(sfd, ifname) - sizeof (Ata)) / 512;
	p->firmware = htons(FWV);
	p->vercmd = 0x10 | Qread;
	memcpy(p->data, config, nconfig);
	p->len = htons(nconfig);
	if (nmasks == 0)
	if (putpkt(fd, buf, sizeof *p - sizeof p->data + nconfig) == -1) {
		perror("putpkt aoe id");
		return;
	}
	for (i=0; i<nmasks; i++) {
		memcpy(p->h.dst, &masks[i*Alen], Alen);
		if (putpkt(fd, buf, sizeof *p - sizeof p->data + nconfig) == -1)
			perror("putpkt aoe id");
	}
}
Beispiel #2
0
int
confcmd(Conf *p, int payload)	// process conf request
{
	int len;

	len = ntohs(p->len);
	if (QCMD(p) != Qread)
	if (len > Nconfig || len > payload)
		return 0;	// if you can't play nice ...
	switch (QCMD(p)) {
	case Qtest:
		if (len != nconfig)
			return 0;
		// fall thru
	case Qprefix:
		if (len > nconfig)
			return 0;
		if (memcmp(config, p->data, len))
			return 0;
		// fall thru
	case Qread:
		break;
	case Qset:
		if (nconfig)
		if (nconfig != len || memcmp(config, p->data, len)) {
			p->h.flags |= Error;
			p->h.error = ConfigErr;
			break;
		}
		// fall thru
	case Qfset:
		nconfig = len;
		memcpy(config, p->data, nconfig);
		break;
	default:
		p->h.flags |= Error;
		p->h.error = BadArg;
	}
	memmove(p->data, config, nconfig);
	p->len = htons(nconfig);
	p->bufcnt = htons(bufcnt);
	p->scnt = maxscnt = (getmtu(sfd, ifname) - sizeof (Ata)) / 512;
	p->firmware = htons(FWV);
	p->vercmd = 0x10 | QCMD(p);	// aoe v.1
	return nconfig + sizeof *p - sizeof p->data;
}
Beispiel #3
0
int
dial(char *eth, int bufcnt)		// get us a raw connection to an interface
{
	int i, n, s;
	struct sockaddr_ll sa;
	enum { aoe_type = 0x88a2 };

	memset(&sa, 0, sizeof sa);
	s = socket(PF_PACKET, SOCK_RAW, htons(aoe_type));
	if (s == -1) {
		perror("got bad socket");
		return -1;
	}
	i = getindx(s, eth);
	sa.sll_family = AF_PACKET;
	sa.sll_protocol = htons(0x88a2);
	sa.sll_ifindex = i;
	n = bind(s, (struct sockaddr *)&sa, sizeof sa);
	if (n == -1) {
		perror("bind funky");
		return -1;
	}

	struct bpf_program {
		ulong bf_len;
		void *bf_insns;
	} *bpf_program = create_bpf_program(shelf, slot);
	setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, bpf_program, sizeof(*bpf_program));
	free_bpf_program(bpf_program);

	n = bufcnt * getmtu(s, eth);
	if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) < 0)
		perror("setsockopt SOL_SOCKET, SO_SNDBUF");
	if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) < 0)
		perror("setsockopt SOL_SOCKET, SO_RCVBUF");

	return s;
}
/*thread que recebe da camada de baixo*/
PRIVATE void *internalsend(void *param)
{
    int isfragmentable;
    int mtu;
    uint16_t count_id = 0;
    wait_list_item_t intern_list_cons;
    offsetlst_t *head = NULL,*aux;
    datagram_t *data_send = ALLOC(datagram_t, sizeof(datagram_t));
    byte *buffer;
    while(TRUE)
    {
        intern_list_cons = wait_list_remove();
        //getmtu do destino
        mtu = getmtu(num_global, intern_list_cons.first_dest_link);
        //protocolo = 1 utilizado pelo transp ou protocolo = 0 utilizado pela tab de rotas
        if(intern_list_cons.protocol == 1 || intern_list_cons.protocol ==  0)
        {
            isfragmentable = fragpack(&head,intern_list_cons.data,intern_list_cons.size,mtu,intern_list_cons.offset);
            LOG("dest1 %d", intern_list_cons.dest);
            //sabe que é apenas dados
            if(isfragmentable == 0)
            {
                //nao precisou fragmentar
                data_send->size = intern_list_cons.size;
                data_send->id = count_id;
                data_send->frag = intern_list_cons.offset;
                data_send->protocol = intern_list_cons.protocol;
                data_send->ttl = intern_list_cons.ttl;
                data_send->dest = intern_list_cons.dest;
                data_send->src = intern_list_cons.src;
                data_send->data = ALLOC(byte, data_send->size);
                memcpy(data_send->data, intern_list_cons.data, data_send->size);
                buffer = ALLOC(byte, data_send->size + NET_HEADER_SIZE);
                buildsenddatagram(buffer,data_send);
                free(data_send->data);

                if(count_id <= 65535)
                    count_id++;
                else
                    count_id = 0;

                LOG("enviando para enlace");
                link_send(intern_list_cons.first_dest_link, buffer, data_send->size + NET_HEADER_SIZE);
                //free(data_send); ???

            }
            else
            {LOG("frag para enlace");
                while(head != NULL)
                {LOG("head para enlace");
                    //precisa fragmentar
                    data_send->size = head->datagram->size;
                    data_send->id = count_id;
                    data_send->frag = head->datagram->frag;
                    data_send->protocol = intern_list_cons.protocol;
                    data_send->ttl = intern_list_cons.ttl;
                    data_send->dest = intern_list_cons.dest;
                    LOG("dest %d", data_send->dest);
                    data_send->src = intern_list_cons.src;
                    data_send->data = ALLOC(byte, head->datagram->size);
                    memcpy(data_send->data, head->datagram->data, head->datagram->size);
                    LOG("enviando data %s", data_send->data);
                    buffer = ALLOC(byte, data_send->size + NET_HEADER_SIZE);
                    buildsenddatagram(buffer,data_send);
                    free(data_send->data);
                    link_send(intern_list_cons.first_dest_link, buffer, data_send->size + NET_HEADER_SIZE);
                    //anda com a lista
                    aux = head;

                    head = head->next;

                    free(aux);
                }
                LOG("fim para enlace");
                if(count_id <= 65535)
                    count_id++;
                else
                    count_id = 0;
            }
        }
        //protocolo = 2 , utilizado pelo repasse
        else
        {
            if(intern_list_cons.protocol == 2)
            {
                isfragmentable = fragpack2(&head,intern_list_cons.data,intern_list_cons.size,mtu,intern_list_cons.offset);
                
                if(isfragmentable == 0)
                {
                    //nao precisou fragmentar
                    data_send->size = intern_list_cons.size;
                    data_send->id = intern_list_cons.id;
                    data_send->frag = intern_list_cons.offset;
                    data_send->protocol = intern_list_cons.protocol;
                    data_send->ttl = intern_list_cons.ttl;
                    data_send->dest = intern_list_cons.dest;
                    data_send->src = intern_list_cons.src;
                    data_send->data = ALLOC(byte, data_send->size);
                    memcpy(data_send->data, intern_list_cons.data, data_send->size);
                    buffer = ALLOC(byte, data_send->size + NET_HEADER_SIZE);
                    buildsenddatagram(buffer,data_send);
                    free(data_send->data);
                    LOG("enviando para enlace");
                    link_send(intern_list_cons.first_dest_link, buffer, data_send->size + NET_HEADER_SIZE);
                    //free(data_send); ???
                }
                else
                {
                    while(head != NULL)
                    {
                        //precisa fragmentar
                        data_send->size = head->datagram->size;
                        data_send->id = intern_list_cons.id;
                        data_send->frag = head->datagram->frag;
                        data_send->protocol = intern_list_cons.protocol;
                        data_send->ttl = intern_list_cons.ttl;
                        data_send->dest = intern_list_cons.dest;
                        data_send->src = intern_list_cons.src;
                        data_send->data = ALLOC(byte, head->datagram->size);
                        memcpy(data_send->data, head->datagram->data, head->datagram->size);
                        
                        buffer = ALLOC(byte, data_send->size + NET_HEADER_SIZE);
                        buildsenddatagram(buffer,data_send);
                        free(data_send->data);
                        link_send(intern_list_cons.first_dest_link, buffer, data_send->size + NET_HEADER_SIZE);
                        //anda com a lista
                        aux = head;

                        head = head->next;

                        free(aux);
                    }
                    
                }
            }
        } 
    }
}