Esempio n. 1
0
// Bind the master netlink socket for all communication
// responses will have to be routed to appropriate bus master
GOOD_OR_BAD w1_bind( struct connection_in * in )
{
	struct port_in * pin = in->pown ;
	struct sockaddr_nl l_local ;

	pin->type = ct_netlink ;
	Test_and_Close( &(pin->file_descriptor) ) ; // just in case
	
	// Example from http://lxr.linux.no/linux+v3.0/Documentation/connector/ucon.c#L114
	//pin->file_descriptor = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
//    pin->file_descriptor = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC , NETLINK_CONNECTOR);
    pin->file_descriptor = socket(PF_NETLINK, SOCK_RAW , NETLINK_CONNECTOR);
	if ( FILE_DESCRIPTOR_NOT_VALID( pin->file_descriptor ) ) {
		ERROR_CONNECT("Netlink (w1) socket (are you root?)");
		return gbBAD;
	}
//	fcntl (pin->file_descriptor, F_SETFD, FD_CLOEXEC); // for safe forking

	l_local.nl_pid = in->master.w1_monitor.pid = getpid() ;
	l_local.nl_pad = 0;
	l_local.nl_family = AF_NETLINK;
	l_local.nl_groups = 23;

	if ( bind( pin->file_descriptor, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl) ) == -1 ) {
		ERROR_CONNECT("Netlink (w1) bind (are you root?)");
		Test_and_Close( &( pin->file_descriptor) );
		return gbBAD ;
	}
	pin->state = cs_deflowered ;
	return gbGOOD ;
}
Esempio n. 2
0
void telnet_session_destroy(struct telnet_session_s *t)
{
	daemon_assert(invariant(t));

	Test_and_Close( & t->in_fd);
	Test_and_Close( & t->out_fd);
}
Esempio n. 3
0
/* Called on head of multibus group */
void serial_free(struct connection_in *connection)
{
    FILE_DESCRIPTOR_OR_ERROR fd ;
    struct port_in * pin = connection->pown ;

    if ( pin->state == cs_virgin ) {
        return ;
    }

    fd = pin->file_descriptor ;
    if ( FILE_DESCRIPTOR_NOT_VALID( fd ) ) {
        // reopen to restore attributes
        fd = open( pin->init_data, O_RDWR | O_NONBLOCK | O_NOCTTY ) ;
    }

    // restore tty settings
    if ( FILE_DESCRIPTOR_VALID( fd ) ) {
        LEVEL_DEBUG("COM_close: flush");
        tcflush( fd, TCIOFLUSH);
        LEVEL_DEBUG("COM_close: restore");
        if ( tcsetattr( fd, TCSANOW, &(pin->dev.serial.oldSerialTio) ) < 0) {
            ERROR_CONNECT("Cannot restore port attributes: %s", pin->init_data);
        }
    }
    Test_and_Close( &( pin->file_descriptor) ) ;
}
Esempio n. 4
0
void COM_close(struct connection_in *connection)
{
	struct port_in * pin ;
	
	if (connection == NO_CONNECTION) {
		LEVEL_DEBUG("Attempt to close a NULL device");
		return ;
	}
	pin = connection->pown ;

	switch ( pin->type ) {
		case ct_unknown:
		case ct_none:
		case ct_usb:
			LEVEL_DEBUG("ERROR!!! ----------- ERROR!");
			return ;
		case ct_telnet:
		case ct_tcp:
			break ;
		case ct_i2c:
		case ct_netlink:
			LEVEL_DEBUG("Unimplemented!!!");
			return ;
		case ct_serial:
			break ;
	}

	switch ( pin->state ) {
		case cs_virgin:
			break ;
		default:
		case cs_deflowered:
			Test_and_Close( &( pin->file_descriptor) ) ;
			break ;
	}
}
Esempio n. 5
0
/* Read from a telnet device
*/
GOOD_OR_BAD telnet_read(BYTE * buf, const size_t size, struct connection_in *in)
{
	struct port_in * pin ;
	// temporary buffer (add some extra space)
	BYTE readin_buf[size+2] ;

	// state machine for telnet escape chars
	// handles TELNET protocol, specifically RFC854
	// http://www.ietf.org/rfc/rfc854.txt
	enum {
		telnet_regular,
		telnet_iac,
		telnet_sb,
		telnet_sb_opt,
		telnet_sb_val,
		telnet_sb_iac,
		telnet_will,
		telnet_wont,
		telnet_do,
		telnet_dont,
	} telnet_read_state = telnet_regular ;

	size_t actual_readin = 0 ;
	size_t current_index = 0 ;
	size_t still_needed = size ;

	// test inputs
	if ( size == 0 ) {
		return gbGOOD ;
	}
	
	if ( in == NO_CONNECTION ) {
		return gbBAD ;
	}
	pin = in->pown ;

	if ( FILE_DESCRIPTOR_NOT_VALID(pin->file_descriptor) ) {
		return gbBAD ;
	}
	
	// loop and look for escape sequances
	while ( still_needed > 0 ) {

		// see if the state requires a longer read than currently scheduled
		size_t minimum_chars  = still_needed ;
		switch( telnet_read_state ) {
			case telnet_sb:
				minimum_chars += 4 ;
				break ;
			case telnet_sb_opt:
				minimum_chars += 3 ;
				break ;
			case telnet_sb_val:
				minimum_chars += 2 ;
				break ;
			case telnet_iac:
			case telnet_sb_iac:
			case telnet_will:
			case telnet_wont:
			case telnet_do:
			case telnet_dont:
				minimum_chars += 1 ;
				break ;
			case telnet_regular:
				break ;
		}

		if ( current_index >= actual_readin ) {
			// need to read more -- just read what we think we need -- escape chars may require repeat
			if ( tcp_read( pin->file_descriptor, readin_buf, minimum_chars, &(pin->timeout), &actual_readin) < 0 ) {
				LEVEL_DEBUG("tcp seems closed") ;
				Test_and_Close( &(pin->file_descriptor) ) ;
				return gbBAD ;
			}

			if (actual_readin < minimum_chars) {
				LEVEL_CONNECT("Telnet (ethernet) error");
				Test_and_Close( &(pin->file_descriptor) ) ;
				return gbBAD;
			}

			current_index = 0 ;
		}

		switch ( telnet_read_state ) {
			case telnet_regular :
				if ( readin_buf[current_index] == TELNET_IAC ) {
						if (Globals.traffic) {
							LEVEL_DEBUG("TELNET: IAC");
						}
					// starting escape sequence
					// following bytes will better characterize
					telnet_read_state = telnet_iac ;
				} else {
					// normal processing
					// move byte to response and decrement needed bytes
					// stay in current state
					buf[size - still_needed] = readin_buf[current_index] ;
					-- still_needed ;
				}
				break ;
			case telnet_iac:
				//printf("TELNET: IAC %d\n",readin_buf[current_index]);
				switch ( readin_buf[current_index] ) {
					case TELNET_EOF:
					case TELNET_SUSP:
					case TELNET_ABORT:
					case TELNET_EOR:
					case TELNET_SE:
					case TELNET_NOP:
					case TELNET_DM:
					case TELNET_BREAK:
					case TELNET_IP:
					case TELNET_AO:
					case TELNET_AYT:
					case TELNET_EC:
					case TELNET_EL:
					case TELNET_GA:
						// 2 byte sequence
						// just read 2nd character
						if (Globals.traffic) {
							LEVEL_DEBUG("TELNET: End 2-byte sequence");
						}
						telnet_read_state = telnet_regular ;
						break ;
					case TELNET_SB:
						// multibyte squence
						// start scanning for 0xF0
						telnet_read_state = telnet_sb ;
						break ;
					case TELNET_WILL:
						// 3 byte sequence
						// just read 2nd char
						telnet_read_state = telnet_will ;
						break ;
					case TELNET_WONT:
						// 3 byte sequence
						// just read 2nd char
						telnet_read_state = telnet_wont ;
						break ;
					case TELNET_DO:
						// 3 byte sequence
						// just read 2nd char
						telnet_read_state = telnet_do ;
						break ;
					case TELNET_DONT:
						// 3 byte sequence
						// just read 2nd char
						telnet_read_state = telnet_dont ;
						break ;
					case TELNET_IAC:
						// escape the FF character
						// make this a single regular FF char
						buf[size - still_needed] = 0xFF ;
						-- still_needed ;
						if (Globals.traffic) {
							LEVEL_DEBUG("TELNET: FF escape sequence");
						}
						telnet_read_state = telnet_regular ;
						break ;
					default:
						LEVEL_DEBUG("Unexpected telnet sequence");
						return gbBAD ;
				}
				break ;
			case telnet_sb:
				switch ( readin_buf[current_index] ) {
					case TELNET_IAC:
						LEVEL_DEBUG("Unexpected telnet sequence");
						return gbBAD ;
					default:
						//printf("TELNET: IAC SB opt=%d\n",readin_buf[current_index]);
						// stay in this mode
						telnet_read_state = telnet_sb_opt ;
						break ;
				}
				break ;
			case telnet_sb_opt:
				switch ( readin_buf[current_index] ) {
					case TELNET_IAC:
						LEVEL_DEBUG("Unexpected telnet sequence");
						return gbBAD ;
					default:
						//printf("TELNET: IAC SB sub_opt=%d\n",readin_buf[current_index]);
						// stay in this mode
						telnet_read_state = telnet_sb_val ;
						break ;
				}
				break ;
			case telnet_sb_val:
				switch ( readin_buf[current_index] ) {
					case TELNET_IAC:
						// stay in this mode
						telnet_read_state = telnet_sb_iac ;
						break ;
					default:
						//printf("TELNET: IAC SB val=%d\n",readin_buf[current_index]);
						// stay in this mode
						break ;
				}
				break ;
			case telnet_sb_iac:
				switch ( readin_buf[current_index] ) {
					case TELNET_SE:
						//printf("TELNET: IAC SE\n");
						if (Globals.traffic) {
							LEVEL_DEBUG("TELNET: End multi-byte sequence");
						}
						telnet_read_state = telnet_regular ;
						break ;					
					default:
						LEVEL_DEBUG("Unexpected telnet sequence");
						return gbBAD ;
				}
				break ;
			case telnet_will:
				//printf("TELNET: IAC WILL %d\n",readin_buf[current_index]);
				// 3 byte sequence
				// now reading 3rd char
				if (Globals.traffic) {
					LEVEL_DEBUG("TELNET: End 3-byte sequence");
				}
				telnet_read_state = telnet_regular ;
				break ;
			case telnet_wont:
				//printf("TELNET: IAC WONT %d\n",readin_buf[current_index]);
				// 3 byte sequence
				// now reading 3rd char
				if (Globals.traffic) {
					LEVEL_DEBUG("TELNET: End 3-byte sequence");
				}
				telnet_read_state = telnet_regular ;
				break ;
			case telnet_do:
				//printf("TELNET: IAC DO %d\n",readin_buf[current_index]);
				// 3 byte sequence
				// now reading 3rd char
				if (Globals.traffic) {
					LEVEL_DEBUG("TELNET: End 3-byte sequence");
				}
				telnet_read_state = telnet_regular ;
				break ;
			case telnet_dont:
				// 3 byte sequence
				// now reading 3rd char
				if (Globals.traffic) {
					LEVEL_DEBUG("TELNET: End 3-byte sequence");
				}
				telnet_read_state = telnet_regular ;
				break ;
		}
		++ current_index ;
	}
	return gbGOOD ;
}