/** * wrapper for loose_route(msg) */ static int w_loose_route(struct sip_msg *msg, char *p1, char *p2) { return loose_route(msg); }
static int do_options(struct iphdr *iph, struct options *opt) { unsigned char *buff; int done = 0; int i, len = sizeof(struct iphdr); /* Zero out the options. */ opt->record_route.route_size = 0; opt->loose_route.route_size = 0; opt->strict_route.route_size = 0; opt->tstamp.ptr = 0; opt->security = 0; opt->compartment = 0; opt->handling = 0; opt->stream = 0; opt->tcc = 0; return(0); /* Advance the pointer to start at the options. */ buff = (unsigned char *)(iph + 1); /* Now start the processing. */ while (!done && len < iph->ihl*4) switch(*buff) { case IPOPT_END: done = 1; break; case IPOPT_NOOP: buff++; len++; break; case IPOPT_SEC: buff++; if (*buff != 11) return(1); buff++; opt->security = ntohs(*(unsigned short *)buff); buff += 2; opt->compartment = ntohs(*(unsigned short *)buff); buff += 2; opt->handling = ntohs(*(unsigned short *)buff); buff += 2; opt->tcc = ((*buff) << 16) + ntohs(*(unsigned short *)(buff+1)); buff += 3; len += 11; break; case IPOPT_LSRR: buff++; if ((*buff - 3)% 4 != 0) return(1); len += *buff; opt->loose_route.route_size = (*buff -3)/4; buff++; if (*buff % 4 != 0) return(1); opt->loose_route.pointer = *buff/4 - 1; buff++; buff++; for (i = 0; i < opt->loose_route.route_size; i++) { if(i>=MAX_ROUTE) return(1); opt->loose_route.route[i] = *(unsigned long *)buff; buff += 4; } break; case IPOPT_SSRR: buff++; if ((*buff - 3)% 4 != 0) return(1); len += *buff; opt->strict_route.route_size = (*buff -3)/4; buff++; if (*buff % 4 != 0) return(1); opt->strict_route.pointer = *buff/4 - 1; buff++; buff++; for (i = 0; i < opt->strict_route.route_size; i++) { if(i>=MAX_ROUTE) return(1); opt->strict_route.route[i] = *(unsigned long *)buff; buff += 4; } break; case IPOPT_RR: buff++; if ((*buff - 3)% 4 != 0) return(1); len += *buff; opt->record_route.route_size = (*buff -3)/4; buff++; if (*buff % 4 != 0) return(1); opt->record_route.pointer = *buff/4 - 1; buff++; buff++; for (i = 0; i < opt->record_route.route_size; i++) { if(i>=MAX_ROUTE) return 1; opt->record_route.route[i] = *(unsigned long *)buff; buff += 4; } break; case IPOPT_SID: len += 4; buff +=2; opt->stream = *(unsigned short *)buff; buff += 2; break; case IPOPT_TIMESTAMP: buff++; len += *buff; if (*buff % 4 != 0) return(1); opt->tstamp.len = *buff / 4 - 1; buff++; if ((*buff - 1) % 4 != 0) return(1); opt->tstamp.ptr = (*buff-1)/4; buff++; opt->tstamp.x.full_char = *buff; buff++; for (i = 0; i < opt->tstamp.len; i++) { opt->tstamp.data[i] = *(unsigned long *)buff; buff += 4; } break; default: return(1); } if (opt->record_route.route_size == 0) { if (opt->strict_route.route_size != 0) { memcpy(&(opt->record_route), &(opt->strict_route), sizeof(opt->record_route)); } else if (opt->loose_route.route_size != 0) { memcpy(&(opt->record_route), &(opt->loose_route), sizeof(opt->record_route)); } } if (opt->strict_route.route_size != 0 && opt->strict_route.route_size != opt->strict_route.pointer) { strict_route(iph, opt); return(0); } if (opt->loose_route.route_size != 0 && opt->loose_route.route_size != opt->loose_route.pointer) { loose_route(iph, opt); return(0); } return(0); }