| Home | Register | Members | Search | Links |
![]() |
| Thread Tools | Display Modes |
|
|
|
| |
|
pdbuchan@yahoo.com
Guest
Posts: n/a
|
ok, I made some progress. I can do everything except pin the socket to
the interface. Changing hop limit with ancillary data structures is finally working. In case anybody else is curious, I will be posting my final solution when I've got it. Dave |
|
|
|
|
|||
|
|||
|
pdbuchan@yahoo.com
Guest
Posts: n/a
|
Hi guys,
Here's an update. I seem to send a valid Neighbor Solicitation packet, but wireshark sees no response. I'm a bit confused about joining or not joining multicast. From the wireshark view of my packet, I can't see any problems. Anyway, maybe someone can tell me why I get no response. Dave [code] #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netinet/icmp6.h> #include <arpa/inet.h> #include <netdb.h> #include <sys/ioctl.h> #include <bits/ioctls.h> #include <linux/socket.h> #include <net/if.h> struct in6_pktinfo { struct in6_addr ipi6_addr; int ipi6_ifindex; }; unsigned short int checksum (unsigned short int *, int); int main (int argc, char **argv) { int MAXPACKETLEN = 131072; int NSHDRLEN = sizeof (struct nd_neighbor_solicit); int OPTLEN = 8; int PSDHDRLEN = 16 + 16 + 4 + 3 + 1 + NSHDRLEN + OPTLEN; int i, sd, status, ifindex, cmsglen, hoplimit; struct addrinfo hints; struct addrinfo *res; struct sockaddr_in6 dst; struct sockaddr_in6 src; struct nd_neighbor_solicit *ns; socklen_t srclen; unsigned char *outpack, *options, *psdhdr; struct msghdr msghdr; struct ifreq ifr; struct cmsghdr *cmsghdr1; struct iovec iov[2]; char *target, *source, *interface; unsigned char temp[16]; void *tmp; interface = malloc (20); memset (interface, 0, sizeof (interface)); strcpy (interface, "wlan0"); target = malloc (40); memset (target, 0, 40 * sizeof (char)); source = malloc (40); memset (source, 0, 40 * sizeof (char)); outpack = malloc (MAXPACKETLEN); memset (outpack, 0, MAXPACKETLEN * sizeof (unsigned char)); options = malloc (OPTLEN); memset (options, 0, OPTLEN * sizeof (unsigned char)); psdhdr = malloc (PSDHDRLEN); memset (psdhdr, 0, PSDHDRLEN * sizeof (unsigned char)); strcpy (target, "ipv6.google.com"); strcpy (source, "2002:XXXX:XXXX::1"); /* redacted for this post */ memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_flags = AI_CANONNAME; hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_RAW; hints.ai_protocol = IPPROTO_ICMPV6; if ((status = getaddrinfo (source, NULL, &hints, &res)) != 0) { fprintf (stderr, "getaddrinfo in target: %s\n", gai_strerror (status)); return (EXIT_FAILURE); } memcpy (&src, res->ai_addr, res->ai_addrlen); srclen = res->ai_addrlen; inet_pton (AF_INET6, source, psdhdr); if ((status = getaddrinfo (target, NULL, &hints, &res)) != 0) { fprintf (stderr, "getaddrinfo in target: %s\n", gai_strerror (status)); return (EXIT_FAILURE); } memcpy (&dst, res->ai_addr, res->ai_addrlen); tmp = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; memset (temp, 0, 16); memcpy (temp, tmp, 16); printf ("Target unicast IPv6 address: "); for (i=0; i<16; i++) { printf ("%02x ", temp[i]); } printf("\n"); temp[0]= 255; temp[1]=2; for (i=2; i<11; i++) { temp[i] = 0; } temp[11]=1; temp[12]=255; printf ("Target solicited-node multicast address: "); for (i=0; i<16; i++) { printf ("%02x ", temp[i]); } printf("\n"); memcpy (tmp, temp, 16); memcpy (&dst, res->ai_addr, res->ai_addrlen); memcpy (psdhdr + 16, temp, 16); if ((sd = socket (res->ai_family, res->ai_socktype, res- >ai_protocol)) < 0) { perror ("Failed to get socket descriptor "); exit (EXIT_FAILURE); } memset (&ifr, 0, sizeof (ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface); if (ioctl (sd, SIOCGIFHWADDR, &ifr) < 0) { perror ("ioctl() failed to get source MAC address "); return (EXIT_FAILURE); } options[0] = 1; options[1] = OPTLEN / 8; for (i=0; i<6; i++) { options[i+2] = (unsigned char) ifr.ifr_addr.sa_data[i]; } printf ("MAC address for interface %s is ", interface); for (i=0; i<5; i++) { printf ("%02x:", options[i+2]); } printf ("%02x\n", options[5+2]); if (bind (sd, (struct sockaddr *) &src, srclen) < 0) { perror ("Failed to bind the socket descriptor to the source address "); exit (EXIT_FAILURE); } if ((ifindex = if_nametoindex (interface)) == 0) { perror ("if_nametoindex() failed to obtain interface index "); exit (EXIT_FAILURE); } printf ("Index for interface %s is %i\n", interface, ifindex); if (setsockopt (sd, SOL_SOCKET, SO_BINDTODEVICE, (void *) &ifr, sizeof (ifr)) < 0) { perror ("SO_BINDTODEVICE failed"); exit (EXIT_FAILURE); } ns = (struct nd_neighbor_solicit *) outpack; memset (ns, 0, sizeof (*ns)); ns->nd_ns_hdr.icmp6_type = ND_NEIGHBOR_SOLICIT; ns->nd_ns_hdr.icmp6_code = 0; ns->nd_ns_hdr.icmp6_cksum = htons(0); ns->nd_ns_hdr.icmp6_data32[0] = htonl(0); ns->nd_ns_target = dst.sin6_addr; memcpy (outpack + NSHDRLEN, options, OPTLEN); memset (&msghdr, 0, sizeof (msghdr)); msghdr.msg_name = &dst; msghdr.msg_namelen = sizeof (dst); memset (&iov, 0, sizeof (iov)); iov[0].iov_base = (unsigned char *) outpack; iov[0].iov_len = NSHDRLEN + OPTLEN; msghdr.msg_iov = iov; msghdr.msg_iovlen = 1; cmsglen = CMSG_SPACE (sizeof (int)); msghdr.msg_control = malloc (cmsglen); memset (target, 0, 40); msghdr.msg_controllen = cmsglen; hoplimit = 255; cmsghdr1 = (struct cmsghdr *) (msghdr.msg_control); cmsghdr1->cmsg_level = IPPROTO_IPV6; cmsghdr1->cmsg_type = IPV6_HOPLIMIT; cmsghdr1->cmsg_len = CMSG_LEN (sizeof (int)); memcpy (CMSG_DATA (cmsghdr1), &hoplimit, sizeof (int)); psdhdr[32] = 0; psdhdr[33] = 0; psdhdr[34] = (NSHDRLEN + OPTLEN) / 256; psdhdr[35] = (NSHDRLEN + OPTLEN) % 256; psdhdr[36] = 0; psdhdr[37] = 0; psdhdr[38] = 0; psdhdr[39] = IPPROTO_ICMPV6; memcpy (psdhdr + 40, outpack, NSHDRLEN + OPTLEN); ns->nd_ns_hdr.icmp6_cksum = checksum ((unsigned short int *) psdhdr, PSDHDRLEN); printf ("Checksum: %x\n", ntohs (ns->nd_ns_hdr.icmp6_cksum)); if (sendmsg (sd, &msghdr, 0) < 0) { perror ("sendmsg() failed "); exit (EXIT_FAILURE); } close (sd); free (interface); free (target); free (source); free (outpack); free (options); free (psdhdr); free (msghdr.msg_control); return (EXIT_SUCCESS); } unsigned short int checksum (unsigned short int *addr, int len) { int nleft = len; int sum = 0; unsigned short int *w = addr; unsigned short int answer = 0; while (nleft > 1) { sum += *w++; nleft -= sizeof (unsigned short int); } if (nleft == 1) { *(unsigned char *) (&answer) = *(unsigned char *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); answer = ~sum; return (answer); } [end of code] |
|
|
|
|
|||
|
|||
|
pdbuchan@yahoo.com
Guest
Posts: n/a
|
Incidentally, the reason I don't join my interface with any multicast
address is that I'm not doing stateless autoconfiguration (which requires that I join). I've already got a unicast address, and I expect the neighbor advertisement to respond to my unicast address. I think that is the way it works for link level address resolution. Dave |
|
|
|
|
|||
|
|||
|
pdbuchan@yahoo.com
Guest
Posts: n/a
|
ok. I think it's all working now.
I will post the neighbor solicitation code below, but start a new thread to show my solution for receiving the neighbor advertisement which comes back and extracting the neighbor's link-layer (MAC) address from the advertisement. This code uses two ancillary data structures, mostly to learn how to do it. It modifies the hop limit and interface index using ancillary data. I've peppered comments throughout to explain what's going on. I've only successfully tested it with link-local addresses, as I have to use 6to4 to tunnel to the outside. I have still to research how to wrap an ipv6 packet in ipv4. In the mean time, if anyone has ipv6 service, please do try it out on say, ipv6.google.com. Dave // Sends a valid IPv6 ICMP neighbor solicitation packet, // changes hoplimit and specifies interface using ancillary // data method. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> // close() #include <netinet/icmp6.h> // struct nd_neighbor_solicit, which contains icmp6_hdr #include <arpa/inet.h> // inet_pton() and inet_ntop() #include <netdb.h> // struct addrinfo #include <sys/ioctl.h> // macro ioctl is defined #include <bits/ioctls.h> // defines values for argument "request" of ioctl. Here, we need SIOCGIFHWADDR #include <bits/socket.h> // structs msghdr and cmsghdr #include <net/if.h> // struct ifreq // Taken from <linux/ipv6.h>, also in <netinet/in.h> struct in6_pktinfo { struct in6_addr ipi6_addr; int ipi6_ifindex; }; // Function prototypes unsigned short int checksum (unsigned short int *, int); int main (int argc, char **argv) { int MAXPACKETLEN = 131072; int NSHDRLEN = sizeof (struct nd_neighbor_solicit); // Length of NS message header int OPTLEN = 8; // Option Type (1 byte) + Length (1 byte) + Length of MAC address (6 bytes) int PSDHDRLEN = 16 + 16 + 4 + 3 + 1 + NSHDRLEN + OPTLEN; // Section 8.1 of RFC 2460 int i, sd, status, ifindex, cmsglen, hoplimit; struct addrinfo hints; struct addrinfo *res; struct sockaddr_in6 dst; struct sockaddr_in6 src; struct sockaddr_in6 dstsnmc; struct nd_neighbor_solicit *ns; socklen_t srclen; unsigned char *outpack, *options, *psdhdr; unsigned char temp[16]; struct msghdr msghdr; struct ifreq ifr; struct cmsghdr *cmsghdr1, *cmsghdr2; struct in6_pktinfo *pktinfo; struct iovec iov[2]; char *target, *source, *interface; void *tmp; // Allocate memory for various arrays. tmp = (char *) malloc (20 * sizeof (char)); if (tmp != NULL) { interface = tmp;} else { fprintf (stderr, "ERROR: Cannot allocate memory for array 'interface'.\n"); exit (EXIT_FAILURE); } memset (interface, 0, sizeof (interface)); strcpy (interface, "wlan0"); tmp = (char *) malloc (40 * sizeof (char)); if (tmp != NULL) { target = tmp;} else { fprintf (stderr, "ERROR: Cannot allocate memory for array 'target'. \n"); exit (EXIT_FAILURE); } memset (target, 0, 40 * sizeof (char)); tmp = (char *) malloc (40 * sizeof (char)); if (tmp != NULL) { source = tmp;} else { fprintf (stderr, "ERROR: Cannot allocate memory for array 'source'. \n"); exit (EXIT_FAILURE); } memset (source, 0, 40 * sizeof (char)); tmp = (unsigned char *) malloc (MAXPACKETLEN * sizeof (unsigned char)); if (tmp != NULL) { outpack = tmp;} else { fprintf (stderr, "ERROR: Cannot allocate memory for array 'outpack'.\n"); exit (EXIT_FAILURE); } memset (outpack, 0, MAXPACKETLEN * sizeof (unsigned char)); tmp = (unsigned char *) malloc (OPTLEN * sizeof (unsigned char)); if (tmp != NULL) { options = tmp;} else { fprintf (stderr, "ERROR: Cannot allocate memory for array 'options'.\n"); exit (EXIT_FAILURE); } memset (options, 0, OPTLEN * sizeof (unsigned char)); tmp = (unsigned char *) malloc (PSDHDRLEN * sizeof (unsigned char)); if (tmp != NULL) { psdhdr = tmp;} else { fprintf (stderr, "ERROR: Cannot allocate memory for array 'psdhdr'. \n"); exit (EXIT_FAILURE); } memset (psdhdr, 0, PSDHDRLEN * sizeof (unsigned char)); // Hard-code target address strcpy (target, "ipv6.google.com"); // Hard-code source address strcpy (source, "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx"); // Note that you can't bind to link-local address unless you add scope) // Fill out hints, which is a struct addrinfo to be used by getaddrinfo. memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_flags = AI_CANONNAME; hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_RAW; hints.ai_protocol = IPPROTO_ICMPV6; // Turn source URL or IPv6 address into sockaddr_in6 form and copy to src, and // copy source address to checksum pseudo-header (RFC 2460). if ((status = getaddrinfo (source, NULL, &hints, &res)) != 0) { fprintf (stderr, "getaddrinfo in target: %s\n", gai_strerror (status)); return (EXIT_FAILURE); } memcpy (&src, res->ai_addr, res->ai_addrlen); srclen = res->ai_addrlen; inet_pton (AF_INET6, source, psdhdr); // Turn target URL or IPv6 address into sockaddr_in6 form and copy to dst, and // copy destination address to checksum pseudo-header (RFC 2460). if ((status = getaddrinfo (target, NULL, &hints, &res)) != 0) { fprintf (stderr, "getaddrinfo in target: %s\n", gai_strerror (status)); return (EXIT_FAILURE); } memcpy (&dstsnmc, res->ai_addr, res->ai_addrlen); memcpy (&dst, res->ai_addr, res->ai_addrlen); tmp = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; // Convert target's IPv6 unicast address to solicited-node multicast address. // Section 2.7.1 of RFC 4291. memset (temp, 0, 16); memcpy (temp, tmp, 16); printf ("Target unicast IPv6 address: "); for (i=0; i<16; i++) { printf ("%02x ", temp[i]); } printf("\n"); temp[0]= 255; temp[1]=2; for (i=2; i<11; i++) { temp[i] = 0; } temp[11]=1; temp[12]=255; printf ("Target solicited-node multicast address: "); for (i=0; i<16; i++) { printf ("%02x ", temp[i]); } printf("\n"); memcpy (tmp, temp, 16); memcpy (&dstsnmc, res->ai_addr, res->ai_addrlen); memcpy (psdhdr + 16, temp, 16); // Request a socket descriptor sd. if ((sd = socket (res->ai_family, res->ai_socktype, res- >ai_protocol)) < 0) { perror ("Failed to get socket descriptor "); exit (EXIT_FAILURE); } // Obtain source MAC address. memset (&ifr, 0, sizeof (ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface); if (ioctl (sd, SIOCGIFHWADDR, &ifr) < 0) { perror ("ioctl() failed to get source MAC address "); return (EXIT_FAILURE); } // Copy source MAC address into options buffer. options[0] = 1; // Option Type - "source link layer address" (Section 4.6 of RFC 4861) options[1] = OPTLEN / 8; // Option Length - units of 8 octets (RFC 4861) for (i=0; i<6; i++) { options[i+2] = (unsigned char) ifr.ifr_addr.sa_data[i]; } // Report source MAC address to stdout. printf ("MAC address for interface %s is ", interface); for (i=0; i<5; i++) { printf ("%02x:", options[i+2]); } printf ("%02x\n", options[5+2]); // Bind the socket descriptor to the source address if not site-local or link-local. if (!(psdhdr[0] == 0xfe)) { if (bind (sd, (struct sockaddr *) &src, srclen) < 0) { perror ("Failed to bind the socket descriptor to the source address "); exit (EXIT_FAILURE); } } // Retrieve source interface index. if ((ifindex = if_nametoindex (interface)) == 0) { perror ("if_nametoindex() failed to obtain interface index "); exit (EXIT_FAILURE); } printf ("Index for interface %s is %i\n", interface, ifindex); // Define first part of buffer outpack to be a neighbor solicit struct. ns = (struct nd_neighbor_solicit *) outpack; memset (ns, 0, sizeof (*ns)); // Populate icmp6_hdr portion of neighbor solicit struct. ns->nd_ns_hdr.icmp6_type = ND_NEIGHBOR_SOLICIT; // 135 (RFC 4861) ns->nd_ns_hdr.icmp6_code = 0; // zero for neighbor solicitation (RFC 4861) ns->nd_ns_hdr.icmp6_cksum = htons(0); // zero when calculating checksum ns->nd_ns_hdr.icmp6_data32[0] = htonl(0); // Reserved - must be set to zero (RFC 4861) ns->nd_ns_target = dst.sin6_addr; // Target address (NOT MULTICAST) (as type in6_addr) // Append options to end of neighbor solicit struct. memcpy (outpack + NSHDRLEN, options, OPTLEN); // Prepare msghdr for sendmsg(). memset (&msghdr, 0, sizeof (msghdr)); msghdr.msg_name = &dstsnmc; // Destination IPv6 address (solicited node multicast) (as struct sockaddr_in6) msghdr.msg_namelen = sizeof (dstsnmc); memset (&iov, 0, sizeof (iov)); iov[0].iov_base = (unsigned char *) outpack; // Point msghdr to buffer outpack iov[0].iov_len = NSHDRLEN + OPTLEN; msghdr.msg_iov = iov; // scatter/gather array msghdr.msg_iovlen = 1; // number of elements in scatter/gather array // Tell msghdr we're adding cmsghdr data to change hop limit and specify interface. // Allocate some memory for our cmsghdr data. cmsglen = CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct in6_pktinfo)); tmp = (unsigned char *) malloc (cmsglen * sizeof (unsigned char)); if (tmp != NULL) { msghdr.msg_control = tmp;} else { fprintf (stderr, "ERROR: Cannot allocate memory for array 'msghdr.msg_control'.\n"); exit (EXIT_FAILURE); } memset (msghdr.msg_control, 0, cmsglen); msghdr.msg_controllen = cmsglen; // Change hop limit to 255 as required for neighbor solicitation (RFC 4861). hoplimit = 255; cmsghdr1 = CMSG_FIRSTHDR (&msghdr); cmsghdr1->cmsg_level = IPPROTO_IPV6; cmsghdr1->cmsg_type = IPV6_HOPLIMIT; // We want to change hop limit cmsghdr1->cmsg_len = CMSG_LEN (sizeof (int)); *((int *) CMSG_DATA (cmsghdr1)) = hoplimit; // Specify source interface index for this packet via cmsghdr data. cmsghdr2 = CMSG_NXTHDR (&msghdr, cmsghdr1); cmsghdr2->cmsg_level = IPPROTO_IPV6; cmsghdr2->cmsg_type = IPV6_PKTINFO; // We want to specify interface here cmsghdr2->cmsg_len = CMSG_LEN (sizeof (struct in6_pktinfo)); pktinfo = (struct in6_pktinfo *) CMSG_DATA (cmsghdr2); pktinfo->ipi6_ifindex = ifindex; // Compute ICMPv6 checksum (RFC 2460). // psdhdr[0 to 15] = source IPv6 address, set earlier. // psdhdr[16 to 31] = destination IPv6 address, set earlier. psdhdr[32] = 0; // Length should not be greater than 65535 (i.e., 2 bytes) psdhdr[33] = 0; // Length should not be greater than 65535 (i.e., 2 bytes) psdhdr[34] = (NSHDRLEN + OPTLEN) / 256; // Upper layer packet length psdhdr[35] = (NSHDRLEN + OPTLEN) % 256; // Upper layer packet length psdhdr[36] = 0; // Must be zero psdhdr[37] = 0; // Must be zero psdhdr[38] = 0; // Must be zero psdhdr[39] = IPPROTO_ICMPV6; memcpy (psdhdr + 40, outpack, NSHDRLEN + OPTLEN); ns->nd_ns_hdr.icmp6_cksum = checksum ((unsigned short int *) psdhdr, PSDHDRLEN); printf ("Checksum: %x\n", ntohs (ns->nd_ns_hdr.icmp6_cksum)); // Send packet. if (sendmsg (sd, &msghdr, 0) < 0) { perror ("sendmsg() failed "); exit (EXIT_FAILURE); } close (sd); // Free allocated memory. free (interface); free (target); free (source); free (outpack); free (options); free (psdhdr); free (msghdr.msg_control); return (EXIT_SUCCESS); } // Checksum function unsigned short int checksum (unsigned short int *addr, int len) { int nleft = len; int sum = 0; unsigned short int *w = addr; unsigned short int answer = 0; while (nleft > 1) { sum += *w++; nleft -= sizeof (unsigned short int); } if (nleft == 1) { *(unsigned char *) (&answer) = *(unsigned char *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); answer = ~sum; return (answer); } |
|
|
|
|
|||
|
|||
|
clemens fischer
Guest
Posts: n/a
|
pdbuchan@... wrote:
> ok. I think it's all working now. > I will post the neighbor solicitation code below, but start a new > thread to show my solution for receiving the neighbor advertisement > which comes back and extracting the neighbor's link-layer (MAC) > address from the advertisement. Hi, why are you doing all this? AFAIK neighbor discovery/solicitation is done by the IP stack all by itself. Look at: $ egrep . /proc/sys/net/ipv6/neigh/wlan0/* /proc/sys/net/ipv6/conf/default/* /proc/sys/net/ipv6/neigh/wlan0/anycast_delay:99 /proc/sys/net/ipv6/neigh/wlan0/app_solicit:0 /proc/sys/net/ipv6/neigh/wlan0/base_reachable_time:30 /proc/sys/net/ipv6/neigh/wlan0/base_reachable_time_ms:30000 /proc/sys/net/ipv6/neigh/wlan0/delay_first_probe_time:5 /proc/sys/net/ipv6/neigh/wlan0/gc_stale_time:60 /proc/sys/net/ipv6/neigh/wlan0/locktime:0 /proc/sys/net/ipv6/neigh/wlan0/mcast_solicit:3 /proc/sys/net/ipv6/neigh/wlan0/proxy_delay:79 /proc/sys/net/ipv6/neigh/wlan0/proxy_qlen:64 /proc/sys/net/ipv6/neigh/wlan0/retrans_time:300 /proc/sys/net/ipv6/neigh/wlan0/retrans_time_ms:1000 /proc/sys/net/ipv6/neigh/wlan0/ucast_solicit:3 /proc/sys/net/ipv6/neigh/wlan0/unres_qlen:3 /proc/sys/net/ipv6/conf/default/accept_dad:1 /proc/sys/net/ipv6/conf/default/accept_ra:0 /proc/sys/net/ipv6/conf/default/accept_ra_defrtr:0 /proc/sys/net/ipv6/conf/default/accept_ra_pinfo:0 /proc/sys/net/ipv6/conf/default/accept_ra_rt_info_max_plen:0 /proc/sys/net/ipv6/conf/default/accept_ra_rtr_pref:0 /proc/sys/net/ipv6/conf/default/accept_redirects:0 /proc/sys/net/ipv6/conf/default/accept_source_route:0 /proc/sys/net/ipv6/conf/default/autoconf:0 /proc/sys/net/ipv6/conf/default/dad_transmits:1 /proc/sys/net/ipv6/conf/default/disable_ipv6:0 /proc/sys/net/ipv6/conf/default/force_mld_version:0 /proc/sys/net/ipv6/conf/default/force_tllao:0 /proc/sys/net/ipv6/conf/default/forwarding:1 /proc/sys/net/ipv6/conf/default/hop_limit:64 /proc/sys/net/ipv6/conf/default/max_addresses:16 /proc/sys/net/ipv6/conf/default/max_desync_factor:600 /proc/sys/net/ipv6/conf/default/mc_forwarding:0 /proc/sys/net/ipv6/conf/default/mtu:1280 /proc/sys/net/ipv6/conf/default/optimistic_dad:0 /proc/sys/net/ipv6/conf/default/proxy_ndp:0 /proc/sys/net/ipv6/conf/default/regen_max_retry:5 /proc/sys/net/ipv6/conf/default/router_probe_interval:60 /proc/sys/net/ipv6/conf/default/router_solicitation_delay:1 /proc/sys/net/ipv6/conf/default/router_solicitation_interval:4 /proc/sys/net/ipv6/conf/default/router_solicitations:3 /proc/sys/net/ipv6/conf/default/temp_prefered_lft:86400 /proc/sys/net/ipv6/conf/default/temp_valid_lft:604800 /proc/sys/net/ipv6/conf/default/use_tempaddr:2 You might consider the relevant RFC's [1] [1] http://www.ietf.org/rfc/rfc3756.txt A tool that might help you is ip(8) from package iproute2. Youz might also use: http://www.google.com/search?q=linux...20solicitation clemens |
|
|
|
|
|||
|
|||
|
pdbuchan@yahoo.com
Guest
Posts: n/a
|
Hi Clemens,
I wanted to do raw sockets in IPv6 where I could edit all aspects of the IP header. Ancillary data methods do not allow all values to be edited. As IPv6 does not have the IP_HDRINCL option (although I hear Windows has something like it), I was trying to use PF_PACKET/ SOCK_DGRAM. man 7 packet (on Ubuntu) reads, in part: "The socket_type is either SOCK_RAW for raw packets including the link level header or SOCK_DGRAM for cooked packets with the link level header removed. The link level header information is available in a common format in a sockaddr_ll. SOCK_RAW packets are passed to and from the device driver without any changes in the packet data. .... When transmitting a packet, the user supplied buffer should contain the physical layer header. That packet is then queued unmodified to the network driver of the interface defined by the destination address. SOCK_DGRAM operates on a slightly higher level. The physical header is removed before the packet is passed to the user. Packets sent through a SOCK_DGRAM packet socket get a suitable physical layer header based on the information in the sockaddr_ll destination address before they are queued." I had mis-read this to mean that I didn't need the physical layer header data (MAC address) and that linux would do the neighbor discovery for me and fill it in. But on second reading, I now believe that I must still provide it. Regardless, the purpose is merely to learn and have fun bouncing packets between my laptops. Dave |
|
|
|
|
|||
|
|||
|
pdbuchan@yahoo.com
Guest
Posts: n/a
|
One final follow-up:
I looked at how to encapsulate IPv6 in IPv4 (6to4 tunneling) and RFC 4213 gives the details. It's very simple. You prepend an IPv4 header on the front of your IPv6 header (20 bytes). You set values according to the RFC, and send to the 6to4 IPv4 address (192.88.99.1). I tried to send an IPv6 neighbor solicitation to ipv6.google.com over 6to4 and got no response. But if I sent a hand-crafted ICMPv6 echo request to ipv6.google.com over 6to4, I DO receive an echo reply. This got me thinking that maybe the neighbor solicitation was being dropped. I went back to my neighbor solicitation program that successfully sends solicits within link-local scope (from laptop to laptop on my lan) and I tunnelled it through 6to4. Nothing showed up on the wire, so I can only conclude that either the sending or receiving machine's stack is silently dropping the packet. Perhaps there's a rule about dropping 6to4 traffic if the IPv6 header is going to a multicast address (for neighbor solicitation, you need to send to the solicited-node multicast address). Regardless, I now see why I never received a reply. I will assume that since my IPv6 (not 6to4 tunnelled) neighbor solicitation works for link-local addresses, it will work on a native IPv6 connection. The original purpose of the neighbor solicitation was to obtain the link-layer (MAC) address of the target so I could prepare PF_PACKET/ SOCK_RAW packets in IPv6 which require the link-layer address of the target. I seem to be able to do that. For targets external to my network, I need to use 6to4 since I don't have native IPv6 service, but in that case I'm using raw IPv4 sockets and can use IP_HDRINCL. Also, the IPv6 header is fully accessible to me in that case anyway since it follows the IPv4 header as just data. So manual neighbor solicitation is unnecessary for 6to4 traffic. Dave |
|
|
|
|
|||
|
|||
|
|
|
| |
![]() |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Packet sniffing wi-Fi-hacking neighbor ( | arkland | Wireless Internet | 58 | 07-30-2011 06:45 AM |
| Using vs. Avoiding Steel Structures | jlaham | Wireless Internet | 1 | 10-15-2007 10:15 AM |
| sendto() and structures | ericunfuk | Linux Networking | 1 | 03-24-2007 12:22 PM |
| max iovec structures in msghdr? | Oliver Kowalke | Linux Networking | 0 | 01-15-2007 05:16 PM |
| How to send a tcp packet to same machine from a kernel module by creating a sk_buff struct | will_u_tellmemore | Linux Networking | 0 | 01-11-2007 12:45 PM |
Forum Software Powered by vBulletin®, Copyright Jelsoft Enterprises Ltd.
SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc. |



Linear Mode

