00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00081 #include <string.h>
00082
00083 #include "ipsec/debug.h"
00084 #include "ipsec/util.h"
00085
00086 #include "ipsec/sa.h"
00087 #include "ipsec/ah.h"
00088 #include "ipsec/esp.h"
00089
00090
00096 db_set_netif db_sets[IPSEC_NR_NETIFS] ;
00097
00098 typedef struct ipsec_in_ip_struct
00099 {
00100 ipsec_ip_header ip ;
00101 union
00102 {
00103 ipsec_ah_header ah ;
00104 ipsec_esp_header esp ;
00105 ipsec_tcp_header tcp ;
00106 ipsec_udp_header udp ;
00107 } inner_header ;
00108 } ipsec_in_ip ;
00109
00110
00111
00136 db_set_netif *ipsec_spd_load_dbs(spd_entry *inbound_spd_data, spd_entry *outbound_spd_data, sad_entry *inbound_sad_data, sad_entry *outbound_sad_data)
00137 {
00138 int netif ;
00139 int index ;
00140 spd_entry *sp, *sp_next, *sp_prev ;
00141 sad_entry *sa, *sa_next, *sa_prev ;
00142
00143 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00144 "ipsec_spd_load_dbs",
00145 ("inbound_spd_data=%p, outbound_spd_data=%p, inbound_sad_data=%p, outbound_sad_data=%p",
00146 (void *)inbound_spd_data, (void *)outbound_spd_data, (void *)inbound_sad_data, (void *)outbound_sad_data)
00147 );
00148
00149
00150 for(netif=0; netif < IPSEC_NR_NETIFS; netif++)
00151 {
00152 if(db_sets[netif].use_flag == IPSEC_FREE) break ;
00153 }
00154 if(netif >= IPSEC_NR_NETIFS)
00155 {
00156 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_load_dbs", ("%p", (void *)NULL) );
00157 return NULL;
00158 }
00159
00160
00161 db_sets[netif].inbound_spd.table = inbound_spd_data ;
00162 db_sets[netif].outbound_spd.table = outbound_spd_data ;
00163 db_sets[netif].inbound_sad.table = inbound_sad_data ;
00164 db_sets[netif].outbound_sad.table = outbound_sad_data ;
00165
00166 db_sets[netif].use_flag = IPSEC_USED ;
00167
00168
00169 for(index=0; index < IPSEC_MAX_SPD_ENTRIES; index++)
00170 if(db_sets[netif].inbound_spd.table[index].use_flag != IPSEC_USED)
00171 db_sets[netif].inbound_spd.table[index].use_flag = IPSEC_FREE ;
00172
00173 for(index=0; index < IPSEC_MAX_SPD_ENTRIES; index++)
00174 if(db_sets[netif].inbound_sad.table[index].use_flag != IPSEC_USED)
00175 db_sets[netif].inbound_sad.table[index].use_flag = IPSEC_FREE ;
00176
00177 for(index=0; index < IPSEC_MAX_SAD_ENTRIES; index++)
00178 if(db_sets[netif].outbound_spd.table[index].use_flag != IPSEC_USED)
00179 db_sets[netif].outbound_spd.table[index].use_flag = IPSEC_FREE ;
00180
00181 for(index=0; index < IPSEC_MAX_SAD_ENTRIES; index++)
00182 if(db_sets[netif].outbound_sad.table[index].use_flag != IPSEC_USED)
00183 db_sets[netif].outbound_sad.table[index].use_flag = IPSEC_FREE ;
00184
00185
00186
00187
00188 sp = inbound_spd_data ;
00189
00190 if(sp->use_flag == IPSEC_USED)
00191 {
00192 db_sets[netif].inbound_spd.first = sp ;
00193
00194 if ((sp+1)->use_flag == IPSEC_USED)
00195 {
00196 sp_next = (sp+1) ;
00197 }
00198 else
00199 {
00200 sp_next = NULL ;
00201 }
00202
00203 for(index=0, sp_prev=NULL;
00204 (index < IPSEC_MAX_SPD_ENTRIES) && (sp[index+1].use_flag == IPSEC_USED);
00205 sp_prev = &sp[index], sp_next = &sp[index+2], index++)
00206 {
00207 sp[index].prev = sp_prev ;
00208 sp[index].next = sp_next ;
00209 }
00210
00211 sp[index].next = NULL ;
00212 db_sets[netif].inbound_spd.last = &sp[index] ;
00213 }
00214 else
00215 {
00216
00217 db_sets[netif].inbound_spd.first = NULL ;
00218 db_sets[netif].inbound_spd.last = NULL ;
00219 }
00220
00221
00222 sp = outbound_spd_data ;
00223
00224 if(sp->use_flag == IPSEC_USED)
00225 {
00226 db_sets[netif].outbound_spd.first = sp ;
00227
00228 if ((sp+1)->use_flag == IPSEC_USED)
00229 {
00230 sp_next = (sp+1) ;
00231 }
00232 else
00233 {
00234 sp_next = NULL ;
00235 }
00236
00237 for(index=0, sp_prev=NULL;
00238 (index < IPSEC_MAX_SPD_ENTRIES) && (sp[index+1].use_flag == IPSEC_USED);
00239 sp_prev = &sp[index], sp_next = &sp[index+2], index++)
00240 {
00241 sp[index].prev = sp_prev ;
00242 sp[index].next = sp_next ;
00243 }
00244
00245 sp[index].next = NULL ;
00246 db_sets[netif].outbound_spd.last = &sp[index] ;
00247 }
00248 else
00249 {
00250
00251 db_sets[netif].outbound_spd.first = NULL ;
00252 db_sets[netif].outbound_spd.last = NULL ;
00253 }
00254
00255
00256
00257 sa = inbound_sad_data ;
00258
00259 if(sa->use_flag == IPSEC_USED)
00260 {
00261 db_sets[netif].inbound_sad.first = sa ;
00262
00263 if ((sa+1)->use_flag == IPSEC_USED)
00264 {
00265 sa_next = (sa+1) ;
00266 }
00267 else
00268 {
00269 sa_next = NULL ;
00270 }
00271
00272 for(index=0, sa_prev=NULL;
00273 (index < IPSEC_MAX_SAD_ENTRIES) && (sa[index+1].use_flag == IPSEC_USED);
00274 sa_prev = &sa[index], sa_next = &sa[index+2], index++)
00275 {
00276 sa[index].prev = sa_prev ;
00277 sa[index].next = sa_next ;
00278 }
00279
00280 sa[index].next = NULL ;
00281 db_sets[netif].inbound_sad.last = &sa[index] ;
00282 }
00283 else
00284 {
00285
00286 db_sets[netif].inbound_sad.first = NULL ;
00287 db_sets[netif].inbound_sad.last = NULL ;
00288 }
00289
00290
00291 sa = outbound_sad_data ;
00292
00293 if(sa->use_flag == IPSEC_USED)
00294 {
00295 db_sets[netif].outbound_sad.first = sa ;
00296
00297 if ((sa+1)->use_flag == IPSEC_USED)
00298 {
00299 sa_next = (sa+1) ;
00300 }
00301 else
00302 {
00303 sa_next = NULL ;
00304 }
00305
00306 for(index=0, sa_prev=NULL;
00307 (index < IPSEC_MAX_SAD_ENTRIES) && (sa[index+1].use_flag == IPSEC_USED);
00308 sa_prev = &sa[index], sa_next = &sa[index+2], index++)
00309 {
00310 sa[index].prev = sa_prev ;
00311 sa[index].next = sa_next ;
00312 }
00313
00314 sa[index].next = NULL ;
00315 db_sets[netif].outbound_sad.last = &sa[index] ;
00316 }
00317 else
00318 {
00319
00320 db_sets[netif].outbound_sad.first = NULL ;
00321 db_sets[netif].outbound_sad.last = NULL ;
00322 }
00323
00324 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_load_dbs", ("&db_sets[netif] = %p", &db_sets[netif]) );
00325 return &db_sets[netif] ;
00326 }
00327
00336 ipsec_status ipsec_spd_release_dbs(db_set_netif *dbs)
00337 {
00338 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00339 "ipsec_spd_release_dbs",
00340 ("dbs=%p",
00341 (void *)dbs)
00342 );
00343
00344 dbs->inbound_spd.first = NULL ;
00345 dbs->inbound_spd.last = NULL ;
00346 dbs->inbound_spd.table = NULL ;
00347
00348 dbs->outbound_spd.first = NULL ;
00349 dbs->outbound_spd.last = NULL ;
00350 dbs->outbound_spd.table = NULL ;
00351
00352 dbs->inbound_sad.first = NULL ;
00353 dbs->inbound_sad.last = NULL ;
00354 dbs->inbound_sad.table = NULL ;
00355
00356 dbs->outbound_sad.first = NULL ;
00357 dbs->outbound_sad.last = NULL ;
00358 dbs->outbound_sad.table = NULL ;
00359
00360 dbs->use_flag = IPSEC_FREE ;
00361
00362 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_load_dbs", ("return = %d", IPSEC_STATUS_SUCCESS));
00363 return IPSEC_STATUS_SUCCESS ;
00364 }
00365
00375 spd_entry *ipsec_spd_get_free(spd_table *table)
00376 {
00377 int index ;
00378 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00379 "ipsec_spd_get_free",
00380 ("table=%p",
00381 (void *)table)
00382 );
00383
00384
00385 for(index = 0; index < IPSEC_MAX_SPD_ENTRIES; index++)
00386 {
00387 if (table->table[index].use_flag == IPSEC_FREE)
00388 break ;
00389 }
00390
00391 if (index >= IPSEC_MAX_SPD_ENTRIES)
00392 {
00393 return NULL ;
00394 }
00395
00396 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_get_free", ("&table->table[index] = %p", &table->table[index]));
00397 return &table->table[index] ;
00398 }
00399
00428 spd_entry *ipsec_spd_add(__u32 src, __u32 src_net, __u32 dst, __u32 dst_net, __u8 proto, __u16 src_port, __u16 dst_port, __u8 policy, spd_table *table)
00429 {
00430 spd_entry *free_entry ;
00431 spd_entry *tmp_entry ;
00432 int table_size ;
00433
00434 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00435 "ipsec_spd_add",
00436 ("src=%lu, src_net=%lu, dst=%lu, dst_net=%lu, proto=%u, src_port=%u, dst_port=%u, policy=%u, table=%p",
00437 src, src_net, dst, dst_net, proto, src_port, dst_port, policy, (void *)table)
00438 );
00439
00440 table_size = table->size ;
00441
00442 free_entry = ipsec_spd_get_free(table) ;
00443 if (free_entry == NULL)
00444 {
00445 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_add", ("%p", (void *)NULL) );
00446 return NULL ;
00447 }
00448
00449
00450 free_entry->src = src ;
00451 free_entry->src_netaddr = src_net ;
00452 free_entry->dest = dst ;
00453 free_entry->dest_netaddr = dst_net ;
00454
00455 free_entry->protocol = proto ;
00456 free_entry->src_port = src_port ;
00457 free_entry->dest_port = dst_port ;
00458 free_entry->policy = policy ;
00459
00460 free_entry->use_flag = IPSEC_USED ;
00461
00462
00465
00466 if(table->first == NULL)
00467 {
00468 table->first = free_entry ;
00469 table->first->next = NULL ;
00470 table->first->prev = NULL ;
00471 table->last = free_entry ;
00472 }
00473 else
00474 {
00475
00476 for(tmp_entry = table->first; tmp_entry->next != NULL; tmp_entry = tmp_entry->next)
00477 {
00478 }
00479
00480
00481 free_entry->prev = tmp_entry ;
00482 tmp_entry->next = free_entry ;
00483 free_entry->next = NULL ;
00484 }
00485
00486 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_add", ("free_entry=%p", (void *)free_entry) );
00487 return free_entry ;
00488 }
00496 ipsec_status ipsec_spd_add_sa(spd_entry *entry, sad_entry *sa)
00497 {
00498 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00499 "ipsec_spd_add_sa",
00500 ("entry=%p, sa=%p",
00501 (void *)entry, (void *)sa)
00502 );
00503
00504 entry->sa = sa ;
00505
00506 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_add_sa", ("return = %d", IPSEC_STATUS_SUCCESS) );
00507 return IPSEC_STATUS_SUCCESS ;
00508 }
00509
00523 ipsec_status ipsec_spd_del(spd_entry *entry, spd_table *table)
00524 {
00525 spd_entry *next_ptr ;
00526 spd_entry *prev_ptr ;
00527
00528 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00529 "ipsec_spd_del",
00530 ("entry=%p, table=%p",
00531 (void *)entry, (void *)table)
00532 );
00533
00534
00535 if((entry >= table->table ) && (entry <= (table->table + (IPSEC_MAX_SPD_ENTRIES*sizeof(spd_entry)))))
00536 {
00537
00540
00541
00542 if(entry->use_flag != IPSEC_USED)
00543 {
00544 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_del", ("return = %d", IPSEC_STATUS_FAILURE) );
00545 return IPSEC_STATUS_FAILURE ;
00546 }
00547
00548
00549 prev_ptr = entry->prev ;
00550 next_ptr = entry->next ;
00551 if(prev_ptr)
00552 prev_ptr->next = next_ptr ;
00553 if(next_ptr)
00554 next_ptr->prev = prev_ptr ;
00555
00556
00557 if(entry->next == NULL)
00558 {
00559 table->last == entry->prev ;
00560 }
00561
00562
00563 if(entry == table->first)
00564 {
00565 table->first = entry->next ;
00566 }
00567
00568
00569 entry->use_flag = IPSEC_FREE ;
00570
00571 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_del", ("return = %d", IPSEC_STATUS_SUCCESS) );
00572 return IPSEC_STATUS_SUCCESS ;
00573 }
00574
00575 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_del", ("return = %d", IPSEC_STATUS_FAILURE) );
00576 return IPSEC_STATUS_FAILURE ;
00577 }
00578
00597 spd_entry *ipsec_spd_lookup(ipsec_ip_header *header, spd_table *table)
00598 {
00599 spd_entry *tmp_entry ;
00600 ipsec_in_ip *ip ;
00601
00602 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00603 "ipsec_spd_lookup",
00604 ("header=%p, table=%p",
00605 (void *)header, (void *)table)
00606 );
00607
00608 ip = (ipsec_in_ip*) header ;
00609
00610
00611 for(tmp_entry = table->first; tmp_entry != NULL; tmp_entry = tmp_entry->next)
00612 {
00613 if(ipsec_ip_addr_maskcmp(header->src, tmp_entry->src, tmp_entry->src_netaddr))
00614 {
00615 if(ipsec_ip_addr_maskcmp(header->dest, tmp_entry->dest, tmp_entry->dest_netaddr))
00616 {
00617 if((tmp_entry->protocol == 0) || tmp_entry->protocol == header->protocol)
00618 {
00619 if(header->protocol == IPSEC_PROTO_TCP)
00620 {
00621 if((tmp_entry->src_port == 0) || (tmp_entry->src_port == ip->inner_header.tcp.src))
00622 if( (tmp_entry->dest_port == 0) || (tmp_entry->dest_port == ip->inner_header.tcp.dest))
00623 {
00624 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_lookup", ("tmp_entry = %p", (void *) tmp_entry) );
00625 return tmp_entry ;
00626 }
00627 }
00628 else if(header->protocol == IPSEC_PROTO_UDP)
00629 {
00630 if((tmp_entry->src_port == 0) || (tmp_entry->src_port == ip->inner_header.udp.src))
00631 if( (tmp_entry->dest_port == 0) || (tmp_entry->dest_port == ip->inner_header.udp.dest))
00632 {
00633 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_lookup", ("tmp_entry = %p", (void *) tmp_entry) );
00634 return tmp_entry ;
00635 }
00636 }
00637 else
00638 {
00639 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_lookup", ("tmp_entry = %p", (void *) tmp_entry) );
00640 return tmp_entry ;
00641 }
00642 }
00643 }
00644 }
00645 }
00646 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_spd_lookup", ("return = %p", (void *) NULL) );
00647 return NULL ;
00648 }
00649
00656 void ipsec_spd_print_single(spd_entry *entry)
00657 {
00658 char log_message[IPSEC_LOG_MESSAGE_SIZE+1] ;
00659 char ip_addr1[IPSEC_LOG_MESSAGE_SIZE+1] ;
00660 char ip_addr2[IPSEC_LOG_MESSAGE_SIZE+1] ;
00661 char ip_addr3[IPSEC_LOG_MESSAGE_SIZE+1] ;
00662 char ip_addr4[IPSEC_LOG_MESSAGE_SIZE+1] ;
00663 char protocol[10+1] ;
00664 char policy[10+1] ;
00665
00666 strcpy(ip_addr1, ipsec_inet_ntoa(entry->src)) ;
00667 strcpy(ip_addr2, ipsec_inet_ntoa(entry->src_netaddr)) ;
00668 strcpy(ip_addr3, ipsec_inet_ntoa(entry->dest)) ;
00669 strcpy(ip_addr4, ipsec_inet_ntoa(entry->dest_netaddr)) ;
00670
00671 switch(entry->protocol)
00672 {
00673 case IPSEC_PROTO_TCP:
00674 strcpy(protocol, " TCP") ;
00675 break ;
00676 case IPSEC_PROTO_UDP:
00677 strcpy(protocol, " UDP") ;
00678 break ;
00679 case IPSEC_PROTO_AH:
00680 strcpy(protocol, " AH") ;
00681 break ;
00682 case IPSEC_PROTO_ESP:
00683 strcpy(protocol, " ESP") ;
00684 break ;
00685 case IPSEC_PROTO_ICMP:
00686 strcpy(protocol, "ICMP") ;
00687 break ;
00688 default :
00689 sprintf(protocol, "%4d", entry->protocol) ;
00690 }
00691
00692 switch(entry->policy)
00693 {
00694 case POLICY_APPLY:
00695 strcpy(policy, " APPLY") ;
00696 break ;
00697 case POLICY_BYPASS:
00698 strcpy(policy, " BYPASS") ;
00699 break ;
00700 case POLICY_DISCARD:
00701 strcpy(policy, "DISCARD") ;
00702 break ;
00703 default:
00704 strcpy(policy, "UNKNOWN") ;
00705 }
00706
00707 sprintf(log_message, "%15s/%15s %15s/%15s %3s %5u %5u %7s 0x%p",
00708 ip_addr1, ip_addr2, ip_addr3, ip_addr4,
00709 protocol,
00710 ipsec_ntohs(entry->src_port),
00711 ipsec_ntohs(entry->dest_port),
00712 policy,
00713 entry->sa) ;
00714
00715 printf(" %s\n", log_message) ;
00716
00717 return ;
00718 }
00719
00726 void ipsec_spd_print(spd_table *table)
00727 {
00728 spd_entry *tmp_ptr ;
00729
00730 IPSEC_LOG_MSG("ipsec_spd_print", ("Printf Security Policy Database")) ;
00731 printf(" src-addr/net-addr dst-addr/net-addr proto prt:src/dest policy SA\n") ;
00732
00733 if(table->first == NULL)
00734 {
00735 printf(" SPD table is empty\n") ;
00736 }
00737
00738
00739 for(tmp_ptr = table->first; tmp_ptr != NULL; tmp_ptr = tmp_ptr->next)
00740 {
00741 ipsec_spd_print_single(tmp_ptr) ;
00742 }
00743
00744 return ;
00745 }
00746
00756 sad_entry *ipsec_sad_get_free(sad_table *table)
00757 {
00758 int index ;
00759
00760
00761 for(index = 0; index < IPSEC_MAX_SAD_ENTRIES; index++)
00762 {
00763 if (table->table[index].use_flag == IPSEC_FREE)
00764 break ;
00765 }
00766
00767 if (index >= IPSEC_MAX_SAD_ENTRIES)
00768 {
00769 return NULL ;
00770 }
00771
00772 return &table->table[index] ;
00773 }
00774
00796 sad_entry *ipsec_sad_add(sad_entry *entry, sad_table *table)
00797 {
00798 sad_entry *free_entry ;
00799 sad_entry *tmp_entry ;
00800
00801 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00802 "ipsec_sad_add",
00803 ("entry=%p, table=%p",
00804 (void *)entry, (void *)table )
00805 );
00806 free_entry = ipsec_sad_get_free(table) ;
00807 if (free_entry == NULL)
00808 {
00809 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_add", ("return = %p", (void *) NULL) );
00810 return NULL ;
00811 }
00812
00813
00814 free_entry->dest = entry->dest ;
00815 free_entry->dest_netaddr = entry->dest_netaddr ;
00816 free_entry->spi = entry->spi ;
00817 free_entry->protocol = entry->protocol ;
00818 free_entry->mode = entry->mode ;
00819 free_entry->sequence_number = entry->sequence_number ;
00820 free_entry->replay_win = entry->replay_win ;
00821 free_entry->lifetime = entry->lifetime ;
00822 free_entry->path_mtu = entry->path_mtu ;
00823 free_entry->enc_alg = entry->enc_alg ;
00824 memcpy(free_entry->enckey, entry->enckey, IPSEC_MAX_ENCKEY_LEN) ;
00825 free_entry->auth_alg = entry->auth_alg ;
00826 memcpy(free_entry->authkey, entry->authkey, IPSEC_MAX_AUTHKEY_LEN) ;
00827
00828 free_entry->use_flag = IPSEC_USED ;
00829
00830
00833
00834 if(table->first == NULL)
00835 {
00836 table->first = free_entry ;
00837 table->first->next = NULL ;
00838 table->first->prev = NULL ;
00839 table->last = free_entry ;
00840 }
00841 else
00842 {
00843
00844 for(tmp_entry = table->first; tmp_entry->next != NULL; tmp_entry = tmp_entry->next)
00845 {
00846 }
00847
00848 free_entry->prev = tmp_entry ;
00849 tmp_entry->next = free_entry ;
00850 free_entry->next = NULL ;
00851 }
00852
00853 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_add", ("free_entry = %p", (void *) free_entry) );
00854 return free_entry ;
00855 }
00856
00870 ipsec_status ipsec_sad_del(sad_entry *entry, sad_table *table)
00871 {
00872 sad_entry *next_ptr ;
00873 sad_entry *prev_ptr ;
00874
00875 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00876 "ipsec_sad_del",
00877 ("entry=%p, table=%p",
00878 (void *)entry, (void *)table )
00879 );
00880
00881
00882 if((entry >= table->table ) && (entry <= (table->table + (IPSEC_MAX_SAD_ENTRIES*sizeof(sad_entry)))))
00883 {
00884
00885
00886 if(entry->use_flag != IPSEC_USED)
00887 {
00888 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_del", ("return = %d", IPSEC_STATUS_FAILURE) );
00889 return IPSEC_STATUS_FAILURE ;
00890 }
00891
00892
00893 prev_ptr = entry->prev ;
00894 next_ptr = entry->next ;
00895 if(prev_ptr)
00896 prev_ptr->next = next_ptr ;
00897 if(next_ptr)
00898 next_ptr->prev = prev_ptr ;
00899
00900
00901 if(entry->next == NULL)
00902 {
00903 table->last == entry->prev ;
00904 }
00905
00906
00907 if(entry == table->first)
00908 {
00909 table->first = entry->next ;
00910 }
00911
00912
00913 entry->use_flag = IPSEC_FREE ;
00914
00915
00916 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_del", ("return = %d", IPSEC_STATUS_SUCCESS) );
00917 return IPSEC_STATUS_SUCCESS ;
00918 }
00919
00920 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_del", ("return = %d", IPSEC_STATUS_FAILURE) );
00921 return IPSEC_STATUS_FAILURE ;
00922 }
00923
00940 sad_entry *ipsec_sad_lookup(__u32 dest, __u8 proto, __u32 spi, sad_table *table)
00941 {
00942 sad_entry *tmp_entry ;
00943
00944 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
00945 "ipsec_sad_lookup",
00946 ("dest=%lu, proto=%d, spi=%lu, table=%p",
00947 dest, proto, spi, (void *)table )
00948 );
00949
00950
00951 for(tmp_entry = table->first; tmp_entry != NULL; tmp_entry = tmp_entry->next)
00952 {
00953 if(ipsec_ip_addr_maskcmp(dest, tmp_entry->dest, tmp_entry->dest_netaddr))
00954 {
00955 if(tmp_entry->protocol == proto)
00956 {
00957 if(tmp_entry->spi == spi)
00958 {
00959 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_lookup", ("tmp_entry = %p", (void *)tmp_entry) );
00960 return tmp_entry ;
00961 }
00962 }
00963 }
00964 }
00965 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_lookup", ("return = %p", (void *)NULL) );
00966 return NULL ;
00967 }
00968
00975 void ipsec_sad_print_single(sad_entry *entry)
00976 {
00977 char log_message[IPSEC_LOG_MESSAGE_SIZE+1] ;
00978 char dest[IPSEC_LOG_MESSAGE_SIZE+1] ;
00979 char dest_netaddr[IPSEC_LOG_MESSAGE_SIZE+1] ;
00980 char crypto[10+1] ;
00981
00982 strcpy(dest, ipsec_inet_ntoa(entry->dest)) ;
00983 strcpy(dest_netaddr, ipsec_inet_ntoa(entry->dest_netaddr)) ;
00984
00985 if (entry->protocol == IPSEC_PROTO_AH)
00986 strcpy(crypto, entry->auth_alg == IPSEC_HMAC_MD5 ? " MD5" : "SHA1") ;
00987 else
00988 strcpy(crypto, entry->enc_alg == IPSEC_DES ? " DES" : "3DES") ;
00989
00990 sprintf(log_message, "%15s/%15s %4s %5s %4s %10lu %5d %10lu %4d %8x 0x%p ",
00991 dest,
00992 dest_netaddr,
00993 entry->protocol == IPSEC_PROTO_ESP ? "ESP" : " AH",
00994 entry->mode == IPSEC_TUNNEL ? " TUN" : "TRANS",
00995 crypto,
00996 entry->sequence_number,
00997 entry->replay_win,
00998 entry->lifetime,
00999 entry->path_mtu,
01000 ipsec_ntohl(entry->spi),
01001 entry
01002 ) ;
01003 printf(" %s\n", log_message) ;
01004
01005 return ;
01006 }
01007
01014 void ipsec_sad_print(sad_table *table)
01015 {
01016 sad_entry *tmp_ptr ;
01017
01018 IPSEC_LOG_MSG("ipsec_sad_print", ("Print Security Association Database")) ;
01019 printf(" dest/dest netaddr proto mode crypto seq win ltime mtu spi addr\n") ;
01020
01021 if(table->first == NULL)
01022 {
01023 printf(" SAD table is empty\n") ;
01024 }
01025
01026
01027 for(tmp_ptr = table->first; tmp_ptr != NULL; tmp_ptr = tmp_ptr->next)
01028 {
01029 ipsec_sad_print_single(tmp_ptr) ;
01030 }
01031 }
01032
01040 __u32 ipsec_sad_get_spi(ipsec_ip_header *header)
01041 {
01042 ipsec_in_ip *ptr ;
01043
01044 IPSEC_LOG_TRC(IPSEC_TRACE_ENTER,
01045 "ipsec_sad_get_spi",
01046 ("header=%p",
01047 (void *)header)
01048 );
01049
01050
01051 ptr = (ipsec_in_ip*)header ;
01052
01053 if (ptr->ip.protocol == IPSEC_PROTO_ESP)
01054 {
01055 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_get_spi", ("ptr->inner_header.esp.spi = %ul", ptr->inner_header.esp.spi) );
01056 return ptr->inner_header.esp.spi ;
01057 }
01058
01059 if (ptr->ip.protocol == IPSEC_PROTO_AH)
01060 {
01061 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_get_spi", ("ptr->inner_header.ah.spi = %ul", ptr->inner_header.ah.spi) );
01062 return ptr->inner_header.ah.spi ;
01063 }
01064
01065 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "ipsec_sad_get_spi", ("return = 0") );
01066 return 0 ;
01067 }
01068
01078 ipsec_status ipsec_spd_flush(spd_table *table, spd_entry *def_entry)
01079 {
01080 memset(table->table, 0, sizeof(spd_entry)*IPSEC_MAX_SPD_ENTRIES) ;
01081 table->first = NULL ;
01082 table->first = NULL ;
01083
01084 if(ipsec_spd_add( def_entry->src,
01085 def_entry->src_netaddr,
01086 def_entry->dest,
01087 def_entry->dest_netaddr,
01088 def_entry->protocol,
01089 def_entry->src_port,
01090 def_entry->dest_port,
01091 def_entry->policy,
01092 table) == NULL)
01093 return IPSEC_STATUS_FAILURE ;
01094
01095 return IPSEC_STATUS_SUCCESS ;
01096 }
01097
01104 ipsec_status ipsec_sad_flush(sad_table *table)
01105 {
01106 memset(table->table, 0, sizeof(spd_entry)*IPSEC_MAX_SAD_ENTRIES) ;
01107 table->first = NULL ;
01108 table->first = NULL ;
01109
01110 return IPSEC_STATUS_SUCCESS ;
01111 }