Ejemplo n.º 1
0
void process_packet(int socket) {

	unsigned char *buffer;
	int size = 0;
	struct sockaddr_in recv_addr;
	struct iphdr *ipheader;
	struct ospfhdr *ospfheader;
	unsigned int iphdr_len, recv_addr_len;
	struct ospf_interface *oiface;

	buffer = malloc(sizeof(*buffer)*REPLAY_PACKET_BUFFER);
	memset(&recv_addr,0,sizeof(recv_addr));
	recv_addr_len = sizeof(recv_addr);

	size = recvfrom(socket, buffer, REPLAY_PACKET_BUFFER, 0, (struct sockaddr *)&recv_addr, &recv_addr_len);
	if(size>0) {
		oiface = find_oiface_by_socket(socket);
		if(recv_addr.sin_addr.s_addr != oiface->iface->ip.s_addr) {
			ipheader = (struct iphdr *)buffer;
			iphdr_len = ipheader->ihl*4;
			ospfheader = (struct ospfhdr *)(buffer+iphdr_len);
			switch(ospfheader->mesg_type) {

			case OSPF_MESG_HELLO:
				process_hello(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface);
				break;
			case OSPF_MESG_DBDESC:
				process_dbdesc(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface);
				break;
			case OSPF_MESG_LSR:
				process_lsr(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface);
				break;
			case OSPF_MESG_LSU:
				process_lsu(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface);
				break;
			case OSPF_MESG_LSACK:
				process_lsack(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface);
				break;
			}
		}
	} else {
		//error reading in packet
	}
	free(buffer);

}
Ejemplo n.º 2
0
void *recv_loop(void *p) {
	uint8_t buf[BUFFER_SIZE];
	interface *iface;
	ospf_header *ospfhdr;
	neighbor *nbr;
	in_addr_t src;
	while (*(int *)p) {
		iface = recv_ospf(sock, buf, BUFFER_SIZE, &src);
		ospfhdr = (ospf_header *)(buf + sizeof(struct iphdr));
		/* check if the packet is from myself */
		if (ospfhdr->router_id == myid) continue;
		for (nbr = iface->nbrs; nbr; nbr = nbr->next)
			if (ospfhdr->router_id == nbr->router_id) break;
		switch (ospfhdr->type) {
			case OSPF_TYPE_HELLO: process_hello(iface, nbr, ospfhdr, src); break;
			case OSPF_TYPE_DD: process_dd(iface, nbr, ospfhdr); break;
			case OSPF_TYPE_LSR: process_lsr(nbr, ospfhdr);break;
			case OSPF_TYPE_LSU: process_lsu(iface->a, nbr, ospfhdr);break;
			case OSPF_TYPE_LSACK: process_ack(nbr, ospfhdr);break;
			default: break;
		}
	}
	return NULL;
}
Ejemplo n.º 3
0
/*
 * Serial interrupt handler
 */
const struct sigevent *
ser_intr(void *area, int id) {
	int				status, cnt;
	unsigned char	msr, lsr;
	DEV_OMAP		*dev = area;
	struct sigevent *event = NULL;
	unsigned		iir;
	uintptr_t		*port = dev->port;

#ifdef PWR_MAN
	/* Our idle state can be changed by a devctl so we must use a spinlock */
	InterruptLock(&dev->idle_spinlock);
#endif

	while (1) {
		status = 0;

#ifdef PWR_MAN
        if (dev->idle) {

            omap_clock_enable_isr(dev);
#ifdef WINBT            
            omap_force_rts(dev, 0);

            // once we are in idle mode the only interrupt that can wake us up is from am CTS line change
            tti(&dev->tty, TTI_OHW_STOP);

            // start a spare timer for debouncing, if this timer actually
            // expires, then this was a CTS glitch, if the timer
            // is cleared by having data on the RX line, it will send up the
            // oband notification to wake up the host.
            dev->signal_oband_notification = 1;

            if( dev->tty.un.s.spare_tmr == 0 ){
                atomic_set (&dev->tty.eflags, EVENT_TIMER_QUEUE);
                dev->tty.un.s.spare_tmr = 4;

                // queue the event here because the switch statement can just exit
                // without actually queuing the event with setting the status flag
                if((dev->tty.flags & EVENT_QUEUED) == 0) {
                    event = &ttyctrl.event;
                    dev_lock(&ttyctrl);
                    ttyctrl.event_queue[ttyctrl.num_events++] = &dev->tty;
                    atomic_set(&dev->tty.flags, EVENT_QUEUED);
                    dev_unlock(&ttyctrl);
                    continue;
                }
            }
#endif // End of #ifdef WINBT
        }

		unsigned ssr = read_omap(port[OMAP_UART_SSR]);
		if (ssr & OMAP_SSR_WAKEUP_STS) {
			/* Clear the wake up interrupt */
			set_port(port[OMAP_UART_SCR], OMAP_SCR_WAKEUPEN, 0);
		}
#endif


		iir = read_omap(port[OMAP_UART_IIR]) & OMAP_II_MASK;

		switch(iir) {
			case OMAP_II_RX:		// Receive data
			case OMAP_II_RXTO:		// Receive data timeout
			case OMAP_II_LS:		// Line status change
				cnt = 0;
				lsr = read_omap(port[OMAP_UART_LSR]);
				do {
					if( lsr & (OMAP_LSR_BI|OMAP_LSR_OE|OMAP_LSR_FE|OMAP_LSR_PE) ) {
						// Error character
						status |= process_lsr(dev, lsr);
					}
					else {
						// Good character
						status |= tti(&dev->tty, (read_omap(port[OMAP_UART_RHR])) & 0xff);
						cnt++;
					}
					lsr = read_omap(port[OMAP_UART_LSR]);
				} while(lsr & OMAP_LSR_RXRDY && cnt < FIFO_SIZE);
#ifdef WINBT
				if( cnt && dev->signal_oband_notification ){

				    // received data after a CTS wake up
				    // notify the host that it's a valid CTS wakeup.
				    dev->signal_oband_notification = 0;
		            dev->tty.oband_data |= _OBAND_SER_MS;
		            atomic_set(&dev->tty.flags, OBAND_DATA);
		            atomic_set(&dev->tty.flags, EVENT_NOTIFY_OBAND);
		            status |= 1;
				}

				if (cnt && dev->tty.un.s.spare_tmr) {
				    // received data, clear spare timer
	                dev->tty.un.s.spare_tmr = 0;
	            }
#endif
				break;

			case OMAP_II_TX:		// Transmit buffer empty

				// disable thr interrupt
				set_port(dev->port[OMAP_UART_IER], OMAP_IER_THR, 0);

				dev->tty.un.s.tx_tmr = 0;
				/* Send event to io-char, tto() will be processed at thread time */
				atomic_set(&dev->tty.flags, EVENT_TTO);
				status |= 1;
				break;

			case OMAP_II_MS:		// Modem change
				msr = read_omap(port[OMAP_UART_MSR]);

				if(msr & OMAP_MSR_DDCD) {
					status |= tti(&dev->tty, (msr & OMAP_MSR_DCD) ? TTI_CARRIER : TTI_HANGUP);
				}

				if((msr & OMAP_MSR_DCTS)  &&  (dev->tty.c_cflag & OHFLOW)) {
					status |= tti(&dev->tty, (msr & OMAP_MSR_CTS) ? TTI_OHW_CONT : TTI_OHW_STOP);
				}

				/* OBAND notification of Modem status change */
				dev->tty.oband_data |= _OBAND_SER_MS;
				atomic_set(&dev->tty.flags, OBAND_DATA);
				atomic_set(&dev->tty.flags, EVENT_NOTIFY_OBAND);
				status |= 1;

				break;

			case OMAP_II_NOINTR:	// No interrupt
				if (read_omap(port[OMAP_UART_SSR]) & OMAP_SSR_WAKEUP_STS) {	// Wake up interrupt
					set_port(port[OMAP_UART_SCR], OMAP_SCR_WAKEUPEN, 0);		// clear wakeup interrupt
					set_port(port[OMAP_UART_SCR], OMAP_SCR_WAKEUPEN, OMAP_SCR_WAKEUPEN);	// re-enable wakeup interrupt
				}
			default:
				goto done;
		}

		if (status) {
			if((dev->tty.flags & EVENT_QUEUED) == 0) {
				event = &ttyctrl.event;
				dev_lock(&ttyctrl);
				ttyctrl.event_queue[ttyctrl.num_events++] = &dev->tty;
				atomic_set(&dev->tty.flags, EVENT_QUEUED);
				dev_unlock(&ttyctrl);
			}
		}
	}

done:
#ifdef PWR_MAN
	InterruptUnlock(&dev->idle_spinlock);
#endif

	return (event);
}