/* allocate buffer but free unless able to read and parse nlm fully */ static GOOD_OR_BAD Get_and_Parse_Pipe( FILE_DESCRIPTOR_OR_ERROR file_descriptor, struct netlink_parse * nlp ) { struct nlmsghdr peek_nlm ; struct nlmsghdr * nlm ; size_t payload_length ; // first read start of message to get length and details if ( read( file_descriptor, &peek_nlm, W1_NLM_LENGTH ) != W1_NLM_LENGTH ) { ERROR_DEBUG("Pipe (w1) read header error"); return gbBAD ; } LEVEL_DEBUG("Pipe header: len=%u type=%u seq=%u|%u pid=%u ",peek_nlm.nlmsg_len,peek_nlm.nlmsg_type,NL_BUS(peek_nlm.nlmsg_seq),NL_SEQ(peek_nlm.nlmsg_seq),peek_nlm.nlmsg_pid); // allocate space nlm = owmalloc( peek_nlm.nlmsg_len ) ; nlp->nlm = nlm ; if ( nlm == NULL ) { LEVEL_DEBUG("Netlink (w1) Cannot allocate %d byte buffer for data", peek_nlm.nlmsg_len ) ; return gbBAD ; } memcpy( nlm, &peek_nlm, W1_NLM_LENGTH ) ; // copy header // read rest of packet if ( peek_nlm.nlmsg_len <= W1_NLM_LENGTH ) { owfree(nlm) ; LEVEL_DEBUG( "W1 packet error. Length is too short." ) ; return gbBAD ; } payload_length = peek_nlm.nlmsg_len - W1_NLM_LENGTH ; if ( read( file_descriptor, NLMSG_DATA(nlm), payload_length ) != (ssize_t) payload_length ) { owfree(nlm) ; nlp->nlm = NULL ; ERROR_DEBUG("Pipe (w1) read payload error"); return gbBAD ; } if ( BAD( Netlink_Parse_Buffer( nlp )) ) { LEVEL_DEBUG("Buffer parsing error"); owfree(nlm) ; nlp->nlm = NULL ; return gbBAD ; } // Good, the receiving routine should owfree buffer LEVEL_DEBUG("Pipe read --------------------"); Netlink_Parse_Show( nlp ) ; return gbGOOD ; }
GOOD_OR_BAD Netlink_Parse_Get( struct netlink_parse * nlp ) { struct nlmsghdr peek_nlm ; // first peek at message to get length and details LEVEL_DEBUG("Wait to peek at message"); int recv_len = recv( Inbound_Control.w1_monitor->pown->file_descriptor, &peek_nlm, W1_NLM_LENGTH, MSG_PEEK ); // Set time of last read _MUTEX_LOCK(Inbound_Control.w1_monitor->master.w1_monitor.read_mutex) ; timernow( &(Inbound_Control.w1_monitor->master.w1_monitor.last_read) ); _MUTEX_UNLOCK(Inbound_Control.w1_monitor->master.w1_monitor.read_mutex) ; LEVEL_DEBUG("Pre-parse header: %u bytes len=%u type=%u seq=%u|%u pid=%u",recv_len,peek_nlm.nlmsg_len,peek_nlm.nlmsg_type,NL_BUS(peek_nlm.nlmsg_seq),NL_SEQ(peek_nlm.nlmsg_seq),peek_nlm.nlmsg_pid); if (recv_len < 0) { ERROR_DEBUG("Netlink (w1) recv header error"); return gbBAD ; } // allocate space nlp->nlm = owmalloc( peek_nlm.nlmsg_len ) ; if ( nlp->nlm == NULL ) { LEVEL_DEBUG("Netlink (w1) Cannot allocate %d byte buffer for data",peek_nlm.nlmsg_len) ; return gbBAD ; } // read whole packet recv_len = recv( Inbound_Control.w1_monitor->pown->file_descriptor, &(nlp->nlm[0]), peek_nlm.nlmsg_len, 0 ); if (recv_len == -1) { ERROR_DEBUG("Netlink (w1) recv body error"); return gbBAD ; } if ( GOOD( Netlink_Parse_Buffer( nlp )) ) { LEVEL_DEBUG("Netlink read -----------------"); Netlink_Parse_Show( nlp ) ; return gbGOOD ; } return gbBAD ; }