int ipauto6(void) { struct packet *m = NULL; char buf6[INET6_ADDRSTRLEN + 1]; struct in6_addr ipaddr; int n = 100; m = nbr_sol(&vpc[pcid]); vpc[pcid].ip6auto = 1; if (m != NULL) enq(&vpc[pcid].oq, m); do { usleep(10000); if (vpc[pcid].ip6.ip.addr32[0] != 0 || vpc[pcid].ip6.ip.addr32[1] != 0 || vpc[pcid].ip6.ip.addr32[2] != 0 || vpc[pcid].ip6.ip.addr32[3] != 0) { memset(buf6, 0, INET6_ADDRSTRLEN + 1); memcpy(ipaddr.s6_addr, vpc[pcid].ip6.ip.addr8, 16); vinet_ntop6(AF_INET6, &ipaddr, buf6, INET6_ADDRSTRLEN + 1); printf("GLOBAL SCOPE : %s/%d\n", buf6, vpc[pcid].ip6.cidr); printf("ROUTER LINK-LAYER : "); PRINT_MAC(vpc[pcid].ip6.gmac); printf("\n"); return 1; } } while (--n > 0); printf("No router answered ICMPv6 Router Solicitation\n"); return 1; }
void autoconf6(void) { int i; struct packet *m = NULL; for (i = 0; i < num_pths; i++) { m = nbr_sol(&vpc[pcid]); if (m != NULL) enq(&vpc[pcid].oq, m); } }
void locallink6(pcs *pc) { pc->link6.ip.addr8[15] = pc->ip4.mac[5]; pc->link6.ip.addr8[14] = pc->ip4.mac[4]; pc->link6.ip.addr8[13] = pc->ip4.mac[3]; pc->link6.ip.addr8[12] = 0xfe; pc->link6.ip.addr8[11] = 0xff; pc->link6.ip.addr8[10] = pc->ip4.mac[2]; pc->link6.ip.addr8[9] = pc->ip4.mac[1]; pc->link6.ip.addr8[8] = (pc->ip4.mac[0] ^ 0x2); pc->link6.ip.addr8[1] = 0x80; pc->link6.ip.addr8[0] = 0xfe; pc->link6.cidr = 64; pc->link6.type = IP6TYPE_LOCALLINK; /* try auto-configure stateless */ struct packet *m = nbr_sol(pc); if (m != NULL) enq(&pc->oq, m); }
/* * find neighbor * * return the mac * NULL, not found * */ u_char *nbDiscovery(pcs *pc, ip6 *dst) { int i, j; static u_char mac[ETH_ALEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; int waittime = 1000; struct timeval tv; /* linklocal address */ if (dst->addr16[0] == IPV6_ADDR_INT16_ULL) { mac[0] = (dst->addr8[8] ^ 0x2); mac[1] = dst->addr8[9]; mac[2] = dst->addr8[10]; mac[3] = dst->addr8[13]; mac[4] = dst->addr8[14]; mac[5] = dst->addr8[15]; return mac; } /* find router */ if (!sameNet6((char *)pc->ip6.ip.addr8, (char *)dst->addr8, pc->ip6.cidr) && dst->addr16[0] != IPV6_ADDR_INT16_ULL) { gettimeofday(&(tv), (void*)0); while (!timeout(tv, waittime)) { struct packet *m; if (memcmp(pc->ip6.gmac, (const char *)mac, ETH_ALEN) != 0) return (pc->ip6.gmac); m = nbr_sol(pc); if (m == NULL) { printf("out of memory\n"); return NULL; } enq(&pc->oq, m); delay_ms(10); } return NULL; } else { /* search neightbor cache */ for (i = 0; i < POOL_SIZE; i++) { if (sameNet6((char *)pc->ipmac6[i].ip.addr8, (char *)dst->addr8, 128)) return (pc->ipmac6[i].mac); } } /* find neighbor */ i = 0; j = -1; while ((i++ < 3) && (j == -1)){ struct packet *m; m = nb_sol(pc, dst); if (m == NULL) { printf("out of memory\n"); return NULL; } enq(&pc->oq, m); gettimeofday(&(tv), (void*)0); while (!timeout(tv, waittime)) { delay_ms(1); for (i = 0; i < POOL_SIZE; i++) { if (sameNet6((char *)pc->ipmac6[i].ip.addr8, (char *)dst->addr8, 128)) return (pc->ipmac6[i].mac); } } } return NULL; }
int run_ipset6(int argc, char **argv) { char buf[INET6_ADDRSTRLEN + 1]; pcs *pc = &vpc[pcid]; struct in6_addr ipaddr; int hasMask = 0; struct packet *m; int eui64 = 0; switch (argc) { case 1: run_show6(pc); return 1; case 4: if (!strcasecmp(argv[3], "eui-64") || !strcasecmp(argv[3], "eui64")) eui64 = 1; case 3: if (!strcasecmp(argv[2], "eui-64") || !strcasecmp(argv[2], "eui64")) eui64 = 1; else { pc->ip6.cidr = atoi(argv[2]); if (pc->ip6.cidr == 0) pc->ip6.cidr = 64; hasMask = 1; } case 2: if (!hasMask) pc->ip6.cidr = 64; if (vinet_pton6(AF_INET6, argv[1], &ipaddr) == 1) { vinet_ntop6(AF_INET6, &ipaddr, buf, INET6_ADDRSTRLEN + 1); memcpy(pc->ip6.ip.addr8, ipaddr.s6_addr, 16); if (eui64) { pc->ip6.ip.addr8[15] = pc->ip4.mac[5]; pc->ip6.ip.addr8[14] = pc->ip4.mac[4]; pc->ip6.ip.addr8[13] = pc->ip4.mac[3]; pc->ip6.ip.addr8[12] = 0xfe; pc->ip6.ip.addr8[11] = 0xff; pc->ip6.ip.addr8[10] = pc->ip4.mac[2]; pc->ip6.ip.addr8[9] = pc->ip4.mac[1]; pc->ip6.ip.addr8[8] = (pc->ip4.mac[0] &0x20) ? pc->ip4.mac[0] & 0xef : (pc->ip4.mac[0] | 0x20); pc->ip6.type = IP6TYPE_EUI64; } else pc->ip6.type = IP6TYPE_NONE; memset(buf, 0, INET6_ADDRSTRLEN + 1); memcpy(ipaddr.s6_addr, pc->ip6.ip.addr8, 16); vinet_ntop6(AF_INET6, &ipaddr, buf,INET6_ADDRSTRLEN + 1); printf("PC%d : %s/%d %s\n", pcid + 1, buf, pc->ip6.cidr, (pc->ip6.type == IP6TYPE_EUI64) ? "eui-64" : ""); m = nbr_sol(pc); if (m == NULL) { printf("out of memory\n"); return 1; } enq(&pc->oq, m); } else { printf("Invalid ipv6 address.\n"); } break; default: printf("Invalid.\n"); break; } return 1; }