Socklen_t sender_len; Struct msghdr MSG; Struct iovec IOV; Struct sockaddr_in sender_addr; Sender_len = sizeof (sender_addr ); Char Buf [2048] = {0 }; Int Len = 0; Char cmsg_buf [1, 2048] = {0 };
MSG. msg_name = & sender_addr; MSG. msg_namelen = sender_len; MSG. msg_iov = & IOV; MSG. msg_iovlen = 1; MSG. msg_iov-> iov_base = Buf; MSG. msg_iov-> iov_len = 2048; MSG. msg_control = cmsg_buf; MSG. msg_controllen = 2048; MSG. msg_flags = 0;
// Receive ICMP packets from the client Len = recvmsg (sockfd, & MSG, 0 ); If (LEN =-1 ){ Perror ("recvmsg ()"); } Else if (LEN = 0 ){ Printf ("Connection closed \ n "); } Else { Printf ("read from client: Len [% d] \ n -- content:", Len ); Print_data (BUF, Len );
Struct cmsghdr * cmsg = NULL; For (cmsg = cmsg_firsthdr (& MSG ); Cmsg! = NULL; Cmsg = cmsg_nxthdr (& MSG, cmsg )) { // Ignore the Control headers that don't match what we want If (cmsg-> cmsg_level! = Ipproto_ip | Cmsg-> cmsg_type! = Ip_pktinfo) { Continue; } Struct in_pktinfo * Pi = cmsg_data (cmsg ); // Printf ("ipi_spec_dst: % s \ n", inet_ntoa (Pi-> ipi_spec_dst )); // Printf ("ipi_addr: % s \ n", inet_ntoa (Pi-> ipi_addr )); Char sender_ip [32] = {0 }; Int sender_port = 0; Transfer_sock_addr (& sender_addr, sender_ip, 32, & sender_port ); Printf ("Source IP: % s port: % d \ n", sender_ip, sender_port ); // At This Point, peeraddr is the source sockaddr // Pi-> ipi_spec_dst is the destination in_addr // Pi-> ipi_addr is the processing ing interface in_addr } Char orig_ip [32] = {0 }; Int orig_port = 0; Struct sockaddr_in * orig_addr; For (cmsg = cmsg_firsthdr (& MSG); cmsg! = NULL; Cmsg = cmsg_nxthdr (& MSG, cmsg )){ If (cmsg-> cmsg_level = sol_ip & Cmsg-> cmsg_type = ip_origdstaddr ){ Orig_addr = (struct sockaddr_in *) cmsg_data (cmsg ); Transfer_sock_addr (orig_addr, orig_ip, 32, & orig_port ); Break; } } If (cmsg = NULL ){ Printf ("ip_origdstaddr not enabled or small buffer or I/O error "); Return; } Printf ("original destination IP: % s-Port: % d \ n", orig_ip, orig_port );
// Struct sockaddr_in sin; // Memset (& sin, 0, sizeof (SIN )); // Sin. sin_family = af_inet; // Sin. sin_addr.s_addr = inet_addr ("192.168.128.2 "); // Sin. sin_port = htons (orig_port );
Int I; Int iphdrlen; // IP header length Struct IP * IP; Struct ICMP * ICMP;
IP = (struct IP *) BUF; Iphdrlen = IP-> ip_hl <2; // calculate the length of the IP header, that is, the length of the IP header multiplied by 4 ICMP = (struct ICMP *) (BUF + iphdrlen); // redirects to the ICMP header over the IP Address Header Len-= iphdrlen; // Forward to the server Printf ("sendto Server \ n "); Sendto (sockfd, ICMP, Len, 0, (struct sockaddr *) & orig_addr, sizeof (struct sockaddr )); // Receive ICMP response from the server Printf ("recvfrom Server \ n "); If (LEN = recvfrom (sockfd, Buf, 2048,0, (Struct sockaddr *) & from, & fromlen) <0 ){ Perror ("recvfrom error "); Return-1; }
Int sock_fd; Int flag = 1;
If (sock_fd = socket (af_inet, sock_raw, ipproto_icmp) <0 ){ Perror ("socket ()"); Return-1; } If (setsockopt (sock_fd, ipproto_ip, ip_hdrincl, & flag, sizeof (INT) <0 ){ Perror ("setsockopt ()-ip_hdrincl "); Return-1; } If (connect (sock_fd, & sin, sizeof (struct sockaddr_in) <0 ){ Close (sockfd ); Perror ("Connect error "); Return-1; } IP = (struct IP *) BUF; Struct in_addr ip_src, ip_dst; Ip_src.s_addr = inet_addr (orig_ip ); Ip_dst.s_addr = sender_addr.sin_addr.s_addr; IP-> ip_src = ip_src; IP-> ip_dst = ip_dst; Iphdrlen = IP-> ip_hl <2; // calculate the length of the IP header, that is, the length of the IP header multiplied by 4 // ICMP = (struct ICMP *) (BUF + iphdrlen); // redirects to the ICMP header over the IP Address Header // Len-= iphdrlen; // Send the response to the client Printf ("sendto client \ n "); Sendto (sock_fd, Buf, Len, 0, (struct sockaddr *) & sender_addr, sizeof (struct sockaddr )); Close (sock_fd ); |