rrenum.c (78064) | rrenum.c (118660) |
---|---|
1/* $FreeBSD: head/usr.sbin/rtadvd/rrenum.c 78064 2001-06-11 12:39:29Z ume $ */ | 1/* $FreeBSD: head/usr.sbin/rtadvd/rrenum.c 118660 2003-08-08 16:38:23Z ume $ */ |
2/* $KAME: rrenum.c,v 1.10 2001/01/21 15:32:16 itojun Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 73 unchanged lines hidden (view full) --- 83{ 84 struct rr_pco_use *rpu, *rpulim; 85 int checklen; 86 87 /* rpm->rpm_len must be (4N * 3) as router-renum-05.txt */ 88 if ((rpm->rpm_len - 3) < 0 || /* must be at least 3 */ 89 (rpm->rpm_len - 3) & 0x3) { /* must be multiple of 4 */ 90 syslog(LOG_WARNING, "<%s> rpm_len %d is not 4N * 3", | 2/* $KAME: rrenum.c,v 1.10 2001/01/21 15:32:16 itojun Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 73 unchanged lines hidden (view full) --- 83{ 84 struct rr_pco_use *rpu, *rpulim; 85 int checklen; 86 87 /* rpm->rpm_len must be (4N * 3) as router-renum-05.txt */ 88 if ((rpm->rpm_len - 3) < 0 || /* must be at least 3 */ 89 (rpm->rpm_len - 3) & 0x3) { /* must be multiple of 4 */ 90 syslog(LOG_WARNING, "<%s> rpm_len %d is not 4N * 3", |
91 __FUNCTION__, rpm->rpm_len); | 91 __func__, rpm->rpm_len); |
92 return 1; 93 } 94 /* rpm->rpm_code must be valid value */ 95 switch(rpm->rpm_code) { 96 case RPM_PCO_ADD: 97 case RPM_PCO_CHANGE: 98 case RPM_PCO_SETGLOBAL: 99 break; 100 default: | 92 return 1; 93 } 94 /* rpm->rpm_code must be valid value */ 95 switch(rpm->rpm_code) { 96 case RPM_PCO_ADD: 97 case RPM_PCO_CHANGE: 98 case RPM_PCO_SETGLOBAL: 99 break; 100 default: |
101 syslog(LOG_WARNING, "<%s> unknown rpm_code %d", __FUNCTION__, | 101 syslog(LOG_WARNING, "<%s> unknown rpm_code %d", __func__, |
102 rpm->rpm_code); 103 return 1; 104 } 105 /* rpm->rpm_matchlen must be 0 to 128 inclusive */ 106 if (rpm->rpm_matchlen > 128) { 107 syslog(LOG_WARNING, "<%s> rpm_matchlen %d is over 128", | 102 rpm->rpm_code); 103 return 1; 104 } 105 /* rpm->rpm_matchlen must be 0 to 128 inclusive */ 106 if (rpm->rpm_matchlen > 128) { 107 syslog(LOG_WARNING, "<%s> rpm_matchlen %d is over 128", |
108 __FUNCTION__, rpm->rpm_matchlen); | 108 __func__, rpm->rpm_matchlen); |
109 return 1; 110 } 111 112 /* 113 * rpu->rpu_uselen, rpu->rpu_keeplen, and sum of them must be 114 * between 0 and 128 inclusive 115 */ 116 for (rpu = (struct rr_pco_use *)(rpm + 1), --- 7 unchanged lines hidden (view full) --- 124 * and rpu_keeplen is unsigned char 125 * (128 > rpu_uselen > 0) 126 * (128 > rpu_keeplen > 0) 127 * (rpu_uselen + rpu_keeplen > 0) 128 */ 129 if (checklen > 128) { 130 syslog(LOG_WARNING, "<%s> sum of rpu_uselen %d and" 131 " rpu_keeplen %d is %d(over 128)", | 109 return 1; 110 } 111 112 /* 113 * rpu->rpu_uselen, rpu->rpu_keeplen, and sum of them must be 114 * between 0 and 128 inclusive 115 */ 116 for (rpu = (struct rr_pco_use *)(rpm + 1), --- 7 unchanged lines hidden (view full) --- 124 * and rpu_keeplen is unsigned char 125 * (128 > rpu_uselen > 0) 126 * (128 > rpu_keeplen > 0) 127 * (rpu_uselen + rpu_keeplen > 0) 128 */ 129 if (checklen > 128) { 130 syslog(LOG_WARNING, "<%s> sum of rpu_uselen %d and" 131 " rpu_keeplen %d is %d(over 128)", |
132 __FUNCTION__, rpu->rpu_uselen, | 132 __func__, rpu->rpu_uselen, |
133 rpu->rpu_keeplen, 134 rpu->rpu_uselen + rpu->rpu_keeplen); 135 return 1; 136 } 137 } 138 return 0; 139} 140 --- 19 unchanged lines hidden (view full) --- 160 irr->irr_vltime = 0; 161 irr->irr_pltime = 0; 162 memset(&irr->irr_flags, 0, sizeof(irr->irr_flags)); 163 irr->irr_useprefix.sin6_len = 0; /* let it mean, no addition */ 164 irr->irr_useprefix.sin6_family = 0; 165 irr->irr_useprefix.sin6_addr = in6addr_any; 166 if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 && 167 errno != EADDRNOTAVAIL) | 133 rpu->rpu_keeplen, 134 rpu->rpu_uselen + rpu->rpu_keeplen); 135 return 1; 136 } 137 } 138 return 0; 139} 140 --- 19 unchanged lines hidden (view full) --- 160 irr->irr_vltime = 0; 161 irr->irr_pltime = 0; 162 memset(&irr->irr_flags, 0, sizeof(irr->irr_flags)); 163 irr->irr_useprefix.sin6_len = 0; /* let it mean, no addition */ 164 irr->irr_useprefix.sin6_family = 0; 165 irr->irr_useprefix.sin6_addr = in6addr_any; 166 if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 && 167 errno != EADDRNOTAVAIL) |
168 syslog(LOG_ERR, "<%s> ioctl: %s", __FUNCTION__, | 168 syslog(LOG_ERR, "<%s> ioctl: %s", __func__, |
169 strerror(errno)); 170 return; 171 } 172 173 for (rpu = (struct rr_pco_use *)(rpm + 1), 174 rpulim = (struct rr_pco_use *)((char *)rpm + len); 175 rpu < rpulim; 176 rpu += 1) { --- 15 unchanged lines hidden (view full) --- 192 irr->irr_rrf_decrprefd = 193 (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME) == 0 ? 0 : 1; 194 irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix); 195 irr->irr_useprefix.sin6_family = AF_INET6; 196 irr->irr_useprefix.sin6_addr = rpu->rpu_prefix; 197 198 if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 && 199 errno != EADDRNOTAVAIL) | 169 strerror(errno)); 170 return; 171 } 172 173 for (rpu = (struct rr_pco_use *)(rpm + 1), 174 rpulim = (struct rr_pco_use *)((char *)rpm + len); 175 rpu < rpulim; 176 rpu += 1) { --- 15 unchanged lines hidden (view full) --- 192 irr->irr_rrf_decrprefd = 193 (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME) == 0 ? 0 : 1; 194 irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix); 195 irr->irr_useprefix.sin6_family = AF_INET6; 196 irr->irr_useprefix.sin6_addr = rpu->rpu_prefix; 197 198 if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 && 199 errno != EADDRNOTAVAIL) |
200 syslog(LOG_ERR, "<%s> ioctl: %s", __FUNCTION__, | 200 syslog(LOG_ERR, "<%s> ioctl: %s", __func__, |
201 strerror(errno)); 202 203 /* very adhoc: should be rewritten */ 204 if (rpm->rpm_code == RPM_PCO_CHANGE && 205 IN6_ARE_ADDR_EQUAL(&rpm->rpm_prefix, &rpu->rpu_prefix) && 206 rpm->rpm_matchlen == rpu->rpu_uselen && 207 rpu->rpu_uselen == rpu->rpu_keeplen) { 208 if ((rai = if_indextorainfo(ifindex)) == NULL) --- 36 unchanged lines hidden (view full) --- 245{ 246 int ifindex = 0; 247 struct in6_rrenumreq irr; 248 249 if ((rr_pco_check(len, rpm) != NULL)) 250 return 1; 251 252 if (s == -1 && (s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { | 201 strerror(errno)); 202 203 /* very adhoc: should be rewritten */ 204 if (rpm->rpm_code == RPM_PCO_CHANGE && 205 IN6_ARE_ADDR_EQUAL(&rpm->rpm_prefix, &rpu->rpu_prefix) && 206 rpm->rpm_matchlen == rpu->rpu_uselen && 207 rpu->rpu_uselen == rpu->rpu_keeplen) { 208 if ((rai = if_indextorainfo(ifindex)) == NULL) --- 36 unchanged lines hidden (view full) --- 245{ 246 int ifindex = 0; 247 struct in6_rrenumreq irr; 248 249 if ((rr_pco_check(len, rpm) != NULL)) 250 return 1; 251 252 if (s == -1 && (s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { |
253 syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__, | 253 syslog(LOG_ERR, "<%s> socket: %s", __func__, |
254 strerror(errno)); 255 exit(1); 256 } 257 258 memset(&irr, 0, sizeof(irr)); 259 irr.irr_origin = PR_ORIG_RR; 260 irr.irr_m_len = rpm->rpm_matchlen; 261 irr.irr_m_minlen = rpm->rpm_minlen; --- 11 unchanged lines hidden (view full) --- 273 (iflist[ifindex]->ifm_flags & IFF_UP) == 0) 274 continue; 275 /* TODO: interface scope check */ 276 do_use_prefix(len, rpm, &irr, ifindex); 277 } 278 if (errno == ENXIO) 279 return 0; 280 else if (errno) { | 254 strerror(errno)); 255 exit(1); 256 } 257 258 memset(&irr, 0, sizeof(irr)); 259 irr.irr_origin = PR_ORIG_RR; 260 irr.irr_m_len = rpm->rpm_matchlen; 261 irr.irr_m_minlen = rpm->rpm_minlen; --- 11 unchanged lines hidden (view full) --- 273 (iflist[ifindex]->ifm_flags & IFF_UP) == 0) 274 continue; 275 /* TODO: interface scope check */ 276 do_use_prefix(len, rpm, &irr, ifindex); 277 } 278 if (errno == ENXIO) 279 return 0; 280 else if (errno) { |
281 syslog(LOG_ERR, "<%s> if_indextoname: %s", __FUNCTION__, | 281 syslog(LOG_ERR, "<%s> if_indextoname: %s", __func__, |
282 strerror(errno)); 283 return 1; 284 } 285 return 0; 286} 287 288/* 289 * call do_pco() for each Prefix Control Operations(PCOs) in a received --- 15 unchanged lines hidden (view full) --- 305 306 while (cp < lim) { 307 int rpmlen; 308 309 rpm = (struct rr_pco_match *)cp; 310 if (len < sizeof(struct rr_pco_match)) { 311 tooshort: 312 syslog(LOG_ERR, "<%s> pkt too short. left len = %d. " | 282 strerror(errno)); 283 return 1; 284 } 285 return 0; 286} 287 288/* 289 * call do_pco() for each Prefix Control Operations(PCOs) in a received --- 15 unchanged lines hidden (view full) --- 305 306 while (cp < lim) { 307 int rpmlen; 308 309 rpm = (struct rr_pco_match *)cp; 310 if (len < sizeof(struct rr_pco_match)) { 311 tooshort: 312 syslog(LOG_ERR, "<%s> pkt too short. left len = %d. " |
313 "gabage at end of pkt?", __FUNCTION__, len); | 313 "gabage at end of pkt?", __func__, len); |
314 return 1; 315 } 316 rpmlen = rpm->rpm_len << 3; 317 if (len < rpmlen) 318 goto tooshort; 319 320 if (do_pco(rr, rpmlen, rpm)) { | 314 return 1; 315 } 316 rpmlen = rpm->rpm_len << 3; 317 if (len < rpmlen) 318 goto tooshort; 319 320 if (do_pco(rr, rpmlen, rpm)) { |
321 syslog(LOG_WARNING, "<%s> invalid PCO", __FUNCTION__); | 321 syslog(LOG_WARNING, "<%s> invalid PCO", __func__); |
322 goto next; 323 } 324 325 next: 326 cp += rpmlen; 327 len -= rpmlen; 328 } 329 --- 10 unchanged lines hidden (view full) --- 340{ 341 u_char ntopbuf[INET6_ADDRSTRLEN]; 342 343 /* omit rr minimal length check. hope kernel have done it. */ 344 /* rr_command length check */ 345 if (len < (sizeof(struct icmp6_router_renum) + 346 sizeof(struct rr_pco_match))) { 347 syslog(LOG_ERR, "<%s> rr_command len %d is too short", | 322 goto next; 323 } 324 325 next: 326 cp += rpmlen; 327 len -= rpmlen; 328 } 329 --- 10 unchanged lines hidden (view full) --- 340{ 341 u_char ntopbuf[INET6_ADDRSTRLEN]; 342 343 /* omit rr minimal length check. hope kernel have done it. */ 344 /* rr_command length check */ 345 if (len < (sizeof(struct icmp6_router_renum) + 346 sizeof(struct rr_pco_match))) { 347 syslog(LOG_ERR, "<%s> rr_command len %d is too short", |
348 __FUNCTION__, len); | 348 __func__, len); |
349 return 1; 350 } 351 352 /* destination check. only for multicast. omit unicast check. */ 353 if (IN6_IS_ADDR_MULTICAST(dst) && !IN6_IS_ADDR_MC_LINKLOCAL(dst) && 354 !IN6_IS_ADDR_MC_SITELOCAL(dst)) { 355 syslog(LOG_ERR, "<%s> dst mcast addr %s is illegal", | 349 return 1; 350 } 351 352 /* destination check. only for multicast. omit unicast check. */ 353 if (IN6_IS_ADDR_MULTICAST(dst) && !IN6_IS_ADDR_MC_LINKLOCAL(dst) && 354 !IN6_IS_ADDR_MC_SITELOCAL(dst)) { 355 syslog(LOG_ERR, "<%s> dst mcast addr %s is illegal", |
356 __FUNCTION__, | 356 __func__, |
357 inet_ntop(AF_INET6, dst, ntopbuf, INET6_ADDRSTRLEN)); 358 return 1; 359 } 360 361 /* seqnum and segnum check */ 362 if (rro.rro_seqnum > rr->rr_seqnum) { 363 syslog(LOG_WARNING, 364 "<%s> rcvd old seqnum %d from %s", | 357 inet_ntop(AF_INET6, dst, ntopbuf, INET6_ADDRSTRLEN)); 358 return 1; 359 } 360 361 /* seqnum and segnum check */ 362 if (rro.rro_seqnum > rr->rr_seqnum) { 363 syslog(LOG_WARNING, 364 "<%s> rcvd old seqnum %d from %s", |
365 __FUNCTION__, (u_int32_t)ntohl(rr->rr_seqnum), | 365 __func__, (u_int32_t)ntohl(rr->rr_seqnum), |
366 inet_ntop(AF_INET6, from, ntopbuf, INET6_ADDRSTRLEN)); 367 return 1; 368 } 369 if (rro.rro_seqnum == rr->rr_seqnum && 370 (rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 && 371 RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) { 372 if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0) 373 syslog(LOG_WARNING, 374 "<%s> rcvd duped segnum %d from %s", | 366 inet_ntop(AF_INET6, from, ntopbuf, INET6_ADDRSTRLEN)); 367 return 1; 368 } 369 if (rro.rro_seqnum == rr->rr_seqnum && 370 (rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 && 371 RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) { 372 if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0) 373 syslog(LOG_WARNING, 374 "<%s> rcvd duped segnum %d from %s", |
375 __FUNCTION__, rr->rr_segnum, | 375 __func__, rr->rr_segnum, |
376 inet_ntop(AF_INET6, from, ntopbuf, 377 INET6_ADDRSTRLEN)); 378 return 0; 379 } 380 381 /* update seqnum */ 382 if (rro.rro_seqnum != rr->rr_seqnum) { 383 /* then must be "<" */ --- 24 unchanged lines hidden (view full) --- 408 } 409 410 /* update segnum */ 411 RR_SET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum); 412 413 return; 414 415 failed: | 376 inet_ntop(AF_INET6, from, ntopbuf, 377 INET6_ADDRSTRLEN)); 378 return 0; 379 } 380 381 /* update seqnum */ 382 if (rro.rro_seqnum != rr->rr_seqnum) { 383 /* then must be "<" */ --- 24 unchanged lines hidden (view full) --- 408 } 409 410 /* update segnum */ 411 RR_SET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum); 412 413 return; 414 415 failed: |
416 syslog(LOG_ERR, "<%s> received RR was invalid", __FUNCTION__); | 416 syslog(LOG_ERR, "<%s> received RR was invalid", __func__); |
417 return; 418} 419 420void 421rr_input(int len, struct icmp6_router_renum *rr, struct in6_pktinfo *pi, 422 struct sockaddr_in6 *from, struct in6_addr *dst) 423{ 424 u_char ntopbuf[2][INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 425 426 syslog(LOG_DEBUG, 427 "<%s> RR received from %s to %s on %s", | 417 return; 418} 419 420void 421rr_input(int len, struct icmp6_router_renum *rr, struct in6_pktinfo *pi, 422 struct sockaddr_in6 *from, struct in6_addr *dst) 423{ 424 u_char ntopbuf[2][INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 425 426 syslog(LOG_DEBUG, 427 "<%s> RR received from %s to %s on %s", |
428 __FUNCTION__, | 428 __func__, |
429 inet_ntop(AF_INET6, &from->sin6_addr, 430 ntopbuf[0], INET6_ADDRSTRLEN), 431 inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN), 432 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 433 434 /* packet validation based on Section 4.1 of RFC2894 */ 435 if (len < sizeof(struct icmp6_router_renum)) { 436 syslog(LOG_NOTICE, 437 "<%s>: RR short message (size %d) from %s to %s on %s", | 429 inet_ntop(AF_INET6, &from->sin6_addr, 430 ntopbuf[0], INET6_ADDRSTRLEN), 431 inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN), 432 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 433 434 /* packet validation based on Section 4.1 of RFC2894 */ 435 if (len < sizeof(struct icmp6_router_renum)) { 436 syslog(LOG_NOTICE, 437 "<%s>: RR short message (size %d) from %s to %s on %s", |
438 __FUNCTION__, len, | 438 __func__, len, |
439 inet_ntop(AF_INET6, &from->sin6_addr, 440 ntopbuf[0], INET6_ADDRSTRLEN), 441 inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN), 442 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 443 return; 444 } 445 446 /* --- 4 unchanged lines hidden (view full) --- 451 * We rely on the kernel input routine for unicast addresses, and thus 452 * check multicast destinations only. 453 */ 454 if (IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr) && 455 !IN6_ARE_ADDR_EQUAL(&in6a_site_allrouters, &pi->ipi6_addr)) { 456 syslog(LOG_NOTICE, 457 "<%s>: RR message with invalid destination (%s) " 458 "from %s on %s", | 439 inet_ntop(AF_INET6, &from->sin6_addr, 440 ntopbuf[0], INET6_ADDRSTRLEN), 441 inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN), 442 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 443 return; 444 } 445 446 /* --- 4 unchanged lines hidden (view full) --- 451 * We rely on the kernel input routine for unicast addresses, and thus 452 * check multicast destinations only. 453 */ 454 if (IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr) && 455 !IN6_ARE_ADDR_EQUAL(&in6a_site_allrouters, &pi->ipi6_addr)) { 456 syslog(LOG_NOTICE, 457 "<%s>: RR message with invalid destination (%s) " 458 "from %s on %s", |
459 __FUNCTION__, | 459 __func__, |
460 inet_ntop(AF_INET6, &dst, ntopbuf[0], INET6_ADDRSTRLEN), 461 inet_ntop(AF_INET6, &from->sin6_addr, 462 ntopbuf[1], INET6_ADDRSTRLEN), 463 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 464 return; 465 } 466 467 rr_rcvifindex = pi->ipi6_ifindex; --- 6 unchanged lines hidden (view full) --- 474 case ICMP6_ROUTER_RENUMBERING_RESULT: 475 /* RESULT will be processed by rrenumd */ 476 break; 477 case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET: 478 /* TODO: sequence number reset */ 479 break; 480 default: 481 syslog(LOG_ERR, "<%s> received unknown code %d", | 460 inet_ntop(AF_INET6, &dst, ntopbuf[0], INET6_ADDRSTRLEN), 461 inet_ntop(AF_INET6, &from->sin6_addr, 462 ntopbuf[1], INET6_ADDRSTRLEN), 463 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 464 return; 465 } 466 467 rr_rcvifindex = pi->ipi6_ifindex; --- 6 unchanged lines hidden (view full) --- 474 case ICMP6_ROUTER_RENUMBERING_RESULT: 475 /* RESULT will be processed by rrenumd */ 476 break; 477 case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET: 478 /* TODO: sequence number reset */ 479 break; 480 default: 481 syslog(LOG_ERR, "<%s> received unknown code %d", |
482 __FUNCTION__, rr->rr_code); | 482 __func__, rr->rr_code); |
483 break; 484 485 } 486 487 return; 488} | 483 break; 484 485 } 486 487 return; 488} |