int vpnapi_control_dp_send_msg(oor_ctrl_t *ctrl, lbuf_t *buff, uconn_t *udp_conn) { int ret; int sock; ip_addr_t *src_addr, *dst_addr; vpnapi_ctr_dplane_data_t * data; data = (vpnapi_ctr_dplane_data_t *)ctrl->control_data_plane->control_dp_data; if (lisp_addr_lafi(&udp_conn->ra) != LM_AFI_IP) { OOR_LOG(LDBG_2, "vpnapi_control_dp_send_msg: Destination address %s of UDP connection is not a IP. " "Discarding!", lisp_addr_to_char(&udp_conn->ra)); return(BAD); } src_addr = lisp_addr_ip(&udp_conn->la); dst_addr = lisp_addr_ip(&udp_conn->ra); if (!lisp_addr_is_no_addr(&udp_conn->la) && (ip_addr_afi(src_addr) != ip_addr_afi(dst_addr))) { OOR_LOG(LDBG_2, "vpnapi_control_dp_send_msg: src %s and dst %s of UDP connection have " "different IP AFI. Discarding!", ip_addr_to_char(src_addr), ip_addr_to_char(dst_addr)); return(BAD); } switch (ip_addr_afi(dst_addr)){ case AF_INET: if (udp_conn->lp == LISP_CONTROL_PORT){ sock = data->ipv4_ctrl_socket; }else{ sock = data->ipv4_data_socket; } break; case AF_INET6: sock = data->ipv6_ctrl_socket; break; default: return (BAD); } ret = send_datagram_packet (sock, lbuf_data(buff), lbuf_size(buff), &udp_conn->ra, udp_conn->rp); if (ret != GOOD) { OOR_LOG(LDBG_1, "Failed to send contrl message from RLOC: %s -> %s", lisp_addr_to_char(&udp_conn->la), lisp_addr_to_char(&udp_conn->ra)); return(BAD); } else { OOR_LOG(LDBG_1, "Sent control message IP: %s -> %s UDP: %d -> %d", lisp_addr_to_char(&udp_conn->la), lisp_addr_to_char(&udp_conn->ra), udp_conn->lp, udp_conn->rp); return(GOOD); } }
int pkt_push_udp_and_ip(lbuf_t *b, uint16_t sp, uint16_t dp, ip_addr_t *sip, ip_addr_t *dip) { uint16_t udpsum; struct udphdr *uh; if (pkt_push_udp(b, sp, dp) == NULL) { OOR_LOG(LDBG_1, "Failed to push UDP header! Discarding"); return(BAD); } lbuf_reset_udp(b); if (pkt_push_ip(b, sip, dip, IPPROTO_UDP) == NULL) { OOR_LOG(LDBG_1, "Failed to push IP header! Discarding"); return(BAD); } lbuf_reset_ip(b); uh = lbuf_udp(b); udpsum = udp_checksum(uh, ntohs(uh->len), lbuf_ip(b), ip_addr_afi(sip)); if (udpsum == -1) { OOR_LOG(LDBG_1, "Failed UDP checksum! Discarding"); return (BAD); } udpsum(uh) = udpsum; return(GOOD); }
void * pkt_push_ip(lbuf_t *b, ip_addr_t *src, ip_addr_t *dst, int proto) { void *iph = NULL; if (ip_addr_afi(src) != ip_addr_afi(dst)) { OOR_LOG(LDBG_1, "src %s and dst %s IP have different AFI! Discarding!", ip_addr_to_char(src), ip_addr_to_char(dst)); return(NULL); } switch (ip_addr_afi(src)) { case AF_INET: iph = pkt_push_ipv4(b, ip_addr_get_addr(src), ip_addr_get_addr(dst), proto); break; case AF_INET6: iph = pkt_push_ipv6(b, ip_addr_get_addr(src), ip_addr_get_addr(dst), proto); break; } return(iph); }
/* Sends a raw packet out the socket file descriptor 'sfd' */ int send_raw_packet(int socket, const void *pkt, int plen, ip_addr_t *dip) { struct sockaddr *saddr = NULL; int slen, nbytes; struct sockaddr_in sa4; struct sockaddr_in6 sa6; /* build sock addr */ switch (ip_addr_afi(dip)) { case AF_INET: memset(&sa4, 0, sizeof(sa4)); sa4.sin_family = AF_INET; ip_addr_copy_to(&sa4.sin_addr, dip); slen = sizeof(struct sockaddr_in); saddr = (struct sockaddr *)&sa4; break; case AF_INET6: memset(&sa6, 0, sizeof(sa6)); sa6.sin6_family = AF_INET6; ip_addr_copy_to(&sa6.sin6_addr, dip); slen = sizeof(struct sockaddr_in6); saddr = (struct sockaddr *)&sa6; break; } nbytes = sendto(socket, pkt, plen, 0, saddr, slen); if (nbytes != plen) { OOR_LOG(LDBG_2, "send_raw_packet: send packet to %s using fail descriptor %d failed -> %s", ip_addr_to_char(dip), socket, strerror(errno)); return(BAD); } return (GOOD); }