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 #ifndef _HIP_FUNCS_H_
00026 #define _HIP_FUNCS_H_
00027
00028
00029 #if defined (__MACOSX__)
00030 #include <mac/mac_types.h>
00031 #elif defined (__WIN32__)
00032 #include <win32/types.h>
00033 #else
00034 #include <asm/types.h>
00035 #endif
00036
00037 #ifdef __MACOSX__
00038 #include <sys/types.h>
00039 #include <sys/time.h>
00040 #endif
00041 #ifdef __WIN32__
00042 #include <winsock2.h>
00043 #else
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #endif
00047 #include <sys/types.h>
00048 #include <openssl/bn.h>
00049 #include <openssl/hmac.h>
00050 #include <openssl/rsa.h>
00051 #include <time.h>
00052
00053
00054
00055
00056
00057 #define DBG(x) x
00058 #define TDIFF(a, b) ((a).tv_sec - (b).tv_sec)
00059
00060
00061
00062 #define SA2IP(x) (((struct sockaddr*)x)->sa_family==AF_INET) ? \
00063 (void*)&((struct sockaddr_in*)x)->sin_addr : \
00064 (void*)&((struct sockaddr_in6*)x)->sin6_addr
00065
00066 #define SALEN(x) (((struct sockaddr*)x)->sa_family==AF_INET) ? \
00067 sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)
00068
00069 #define SAIPLEN(x) (((struct sockaddr*)x)->sa_family==AF_INET) ? 4 : 16
00070
00071 #define SA(x) ((struct sockaddr*)x)
00072
00073
00074 #define yesno(x) x ? "yes" : "no"
00075
00076
00077 #define YLIFE(x) ((float)x-(float)64)/(float)8
00078
00079
00080 #define IS_LSI32(a) ((a & 0xFF) == 0x01)
00081 #ifdef __WIN32__
00082 #define IN6_ARE_ADDR_EQUAL IN6_ADDR_EQUAL
00083 #define IS_HIT(x) (( (ntohs(((struct in6_addr*)x)->s6_words[0]) & 0xFFFF) \
00084 == ((HIT_PREFIX_SHA1_32BITS >> 4) & 0xFFFF)) && \
00085 ( (ntohs(((struct in6_addr*)x)->s6_words[1]) & 0xFFF0) \
00086 == ((HIT_PREFIX_SHA1_32BITS & 0xFFFF)) ) )
00087 #elif defined (__MACOSX__)
00088 #define IS_HIT(x) ( (ntohl(((struct in6_addr*)x)->__u6_addr.__u6_addr32[0]) \
00089 & 0xFFFFFFF0L) == HIT_PREFIX_SHA1_32BITS )
00090 #else
00091 #define IS_HIT(x) ( (ntohl(((struct in6_addr*)x)->s6_addr32[0]) & 0xFFFFFFF0L) \
00092 == HIT_PREFIX_SHA1_32BITS )
00093 #endif
00094 #define SA2IP6(x) ( &((struct sockaddr_in6*)x)->sin6_addr )
00095
00096 #if defined(__MACOSX__) && defined(__BIG_ENDIAN__)
00097 #define IS_LSI(a) ( ( ((struct sockaddr*)a)->sa_family == AF_INET) ? \
00098 (IS_LSI32( ((struct sockaddr_in*)a)->sin_addr.s_addr >> 24)) : \
00099 (IS_HIT( &((struct sockaddr_in6*)a)->sin6_addr) ) )
00100 #else
00101 #define IS_LSI(a) ( (((struct sockaddr*)a)->sa_family == AF_INET) ? \
00102 (IS_LSI32(((struct sockaddr_in*)a)->sin_addr.s_addr)) : \
00103 (IS_HIT( &((struct sockaddr_in6*)a)->sin6_addr) ) )
00104
00105 #endif
00106 #define VALID_FAM(a) ( (((struct sockaddr*)a)->sa_family == AF_INET) || \
00107 (((struct sockaddr*)a)->sa_family == AF_INET6) )
00108
00109
00110
00111
00112
00113
00114 int hip_send_I1(hip_hit* hit, hip_assoc *hip_a, int pos);
00115 int hip_send_R1(struct sockaddr *src, struct sockaddr *dst, hip_hit *hiti,
00116 hi_node *hi, __u16 dst_port, int use_udp);
00117 int hip_generate_R1(__u8 *data, hi_node *hi, hipcookie *cookie,
00118 dh_cache_entry *dh_entry);
00119 int hip_send_I2(hip_assoc *hip_a);
00120 int hip_send_R2(hip_assoc *hip_a);
00121 int hip_send_update(hip_assoc *hip_a, struct sockaddr *newaddr,
00122 struct sockaddr *dstaddr, int use_udp);
00123 int hip_send_close(hip_assoc *hip_a, int send_ack);
00124 int hip_send_notify(hip_assoc *hip_a, int code, __u8 *data, int data_len);
00125 int hip_send(__u8 *data, int len, struct sockaddr *src, struct sockaddr *dst,
00126 hip_assoc *hip_a, int retransmit, __u16 dst_port, int use_udp);
00127 int hip_retransmit(hip_assoc *hip_a, __u8 *data, int len, struct sockaddr *src,
00128 struct sockaddr *dst);
00129 #ifdef __WIN32__
00130 void udp_hip_keepalive (void *arg);
00131 #else
00132 void *udp_hip_keepalive (void *arg);
00133 #endif
00134 int build_tlv_hostid_len(hi_node *hi, int use_hi_name);
00135 int build_tlv_hostid(__u8 *data, hi_node *hi, int use_hi_name);
00136 int build_tlv_reg_info(__u8 *data, int location);
00137 int build_tlv_reg_req(__u8 *data, int location, int lifetime1, int reg_type1);
00138 int build_tlv_reg_resp(__u8 *data, int location, int lifetime1, int reg_type1);
00139 int build_tlv_reg_failed(__u8 *data, int location, int fail_type1, int fail_reg_type1);
00140 int build_rekey(hip_assoc *hip_a);
00141
00142
00143 int hip_parse_hdr(__u8 *data, int len, struct sockaddr *src,
00144 struct sockaddr *dst, __u16 family, hiphdr **hdr, int use_udp);
00145 int hip_handle_I1(__u8 *data, hip_assoc *hip_a, struct sockaddr *src,
00146 struct sockaddr *dst, __u16 *dst_port, int use_udp);
00147 int hip_handle_R1(__u8 *data, hip_assoc *hip_a, struct sockaddr *src,
00148 __u16 *dst_port, int use_udp);
00149 int hip_handle_I2(__u8 *data, hip_assoc *hip_a, struct sockaddr *src,
00150 struct sockaddr *dst, __u16 *dst_port, int use_udp);
00151 int hip_handle_R2(__u8 *data, hip_assoc *hip_a, __u16 *dst_port, int use_udp);
00152 int hip_handle_update(__u8 *data, hip_assoc *hip_a, struct sockaddr *src, __u16 *dst_port, int use_udp);
00153 int hip_handle_close(__u8 *data, hip_assoc *hip_a, __u16 *dst_port, int use_udp);
00154 int hip_handle_notify(__u8 *buff, hip_assoc *hip_a, __u16 *dst_port, int use_udp);
00155 int hip_finish_rekey(hip_assoc *hip_a, int rebuild, int use_udp);
00156 int hip_handle_BOS(__u8 *data, struct sockaddr *src);
00157 int hip_handle_CER(__u8 *data, hip_assoc *hip_a);
00158 int rebuild_sa(hip_assoc *hip_a, struct sockaddr *newaddr, __u32 newspi,
00159 int in, int peer, int use_udp);
00160 void handle_reg_info();
00161 void handle_reg_request(char *data, int location);
00162
00163
00164 __u32 get_next_spi(hip_assoc *hip_a);
00165 int sadb_add(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *inner_src,
00166 struct sockaddr *inner_dst, hip_assoc *hip_a, __u32 spi, int direction);
00167
00168
00169 int sadb_readdress(struct sockaddr *src, struct sockaddr *dst, hip_assoc *hip_a,
00170 __u32 spi);
00171 int sadb_add_policy(hip_assoc *hip_a, struct sockaddr *out_src, struct sockaddr *out_dst,
00172 struct sockaddr *in_src, struct sockaddr *in_dst, int direction);
00173
00174 int sadb_delete(hip_assoc *hip_a, struct sockaddr *src, struct sockaddr *dst, __u32 spi);
00175 int sadb_delete_policy(struct sockaddr *src,struct sockaddr *dst,int direction);
00176 int sadb_register(int satype);
00177 int check_last_used(hip_assoc *hip_a, int direction, struct timeval *now);
00178 int sadb_lsi(struct sockaddr *ip, struct sockaddr *lsi4, struct sockaddr *lsi6);
00179 int delete_associations(hip_assoc *hip_a, __u32 old_spi_in, __u32 old_spi_out);
00180 int flush_hip_associations();
00181 int parse_acquire(char *data, struct sockaddr *src, struct sockaddr *dst);
00182 int parse_expire(char *data, __u32 *spi);
00183 void pfkey_packet_type(int type, char *r);
00184 void hip_handle_pfkey(char *buff);
00185 void hip_check_pfkey_buffer();
00186 void update_lsi_mapping(struct sockaddr *dst, struct sockaddr *lsi,hip_hit hit);
00187
00188
00189 int set_secret_key(unsigned char *key, hip_assoc *hip_a);
00190 unsigned char *get_key(hip_assoc *hip_a, int type, int peer);
00191 void compute_keys(hip_assoc *hip_a);
00192 int compute_keymat(hip_assoc *hip_a);
00193 int draw_keys(hip_assoc *hip_a, int draw_hip_keys, int keymat_index);
00194 int auth_key_len(int suite_id);
00195 int enc_key_len(int suite_id);
00196 int enc_iv_len(int suite_id);
00197
00198
00199 int add_addresses_from_dns(char *name, hi_node *hi);
00200 int read_identities_file(char *filename, int mine);
00201 int save_identities_file(int);
00202 int read_conf_file(char *);
00203 int read_reg_file(void);
00204 __u16 conf_transforms_to_mask();
00205 hi_node *create_new_hi_node();
00206 void append_hi_node(hi_node **head, hi_node *append);
00207 int add_peer_hit(hip_hit peer_hit, struct sockaddr *peer_addr);
00208 hi_node *find_host_identity(hi_node* hi_head, hip_hit *hitr);
00209 int key_data_to_hi(const __u8 *data, __u8 alg, int hi_length, __u8 di_type,
00210 int di_length, hi_node **hi_p, int max_length);
00211 hi_node *get_preferred_hi(hi_node *node);
00212 int get_addr_from_list(sockaddr_list *list, int family,
00213 struct sockaddr *addr);
00214 hip_assoc *init_hip_assoc(hi_node *my_host_id, hip_hit *peer_hit);
00215 void replace_hip_assoc(hip_assoc *a_old, hip_assoc *a_new);
00216 int free_hip_assoc(hip_assoc *hip_a);
00217 void free_hi_node(hi_node *hi);
00218 void clear_retransmissions(hip_assoc *hip_a);
00219 void set_state(hip_assoc *hip_a, int state);
00220 hip_hit *hit_lookup(struct sockaddr*);
00221 hi_node *lsi_lookup(struct sockaddr *lsi);
00222 __u32 lsi_name_lookup(char *name, int name_len);
00223 struct sockaddr *get_hip_dns_server();
00224 __u32 receive_hip_dns_response(unsigned char *buff, int len);
00225 hi_node *hi_lookup(const hip_hit hit, hi_node *node);
00226 int hits_equal(const hip_hit hit1, const hip_hit hit2);
00227 void print_cookie(hipcookie *cookie);
00228 int str_to_addr(__u8 *data, struct sockaddr *addr);
00229 int addr_to_str(struct sockaddr *addr, __u8 *data, int len);
00230 int hex_to_bin(char *src, char *dst, int dst_len);
00231 int solve_puzzle(hipcookie *cookie, __u64 *solution,
00232 hip_hit *hit_i, hip_hit *hit_r);
00233 int validate_solution(const hipcookie *cookie_r, const hipcookie *cookie_i,
00234 hip_hit *hit_i, hip_hit *hit_r, __u64 solution);
00235 int hi_to_hit(hi_node *hi, hip_hit hit);
00236 int validate_hit(hip_hit hit, hi_node *hi);
00237 void print_hex(void *data, int len);
00238 void print_binary(void *data, int len);
00239 int compare_bits(const char *s1, int s1_len, const char *s2, int s2_len,
00240 int numbits);
00241 int compare_hits(hip_hit a, hip_hit b);
00242 int compare_hits2(void const *s1, void const *s2);
00243 int maxof(int num_args, ...);
00244 int hip_header_offset(const __u8 *data);
00245 int udp_header_offset(const __u8 *data);
00246 __u16 checksum_udp_packet(__u8 *data, struct sockaddr *src, struct sockaddr *dst);
00247 void hip_packet_type(int type, char *r);
00248 void print_usage(void);
00249 __u16 checksum_packet(__u8 *data, struct sockaddr *src, struct sockaddr *dst);
00250 __u16 checksum_magic(const hip_hit *i, const hip_hit *r);
00251 int tlv_length_to_parameter_length(int length);
00252 int eight_byte_align(int length);
00253 hip_assoc* find_hip_association(struct sockaddr *src, struct sockaddr *dst,
00254 hiphdr* hiph);
00255 hip_assoc* find_hip_association2(hiphdr* hiph);
00256 hip_assoc* find_hip_association3(struct sockaddr *src, struct sockaddr *dst);
00257 void * binsert(const void *ky, const void *bs, size_t nel, size_t width, int (*compar)(const void *, const void *));
00258 void log_registration(hip_reg *hip_r, int a);
00259 void print_reg_table(hip_reg *hip_r);
00260 int delete_reg_table(hip_reg key, hip_reg *hip_r);
00261 int insert_reg_table(hip_reg key, hip_reg *hip_r);
00262 returned *search_reg_table(hip_reg p, hip_reg *hip_r, returned *ret);
00263 void cb(int p, int n, void *arg);
00264 int init_log();
00265 void fflush_log();
00266 void log_(int level, char *fmt, ...);
00267 char *logaddr(struct sockaddr *addr);
00268 void logdsa(DSA *dsa);
00269 void logrsa(RSA *rsa);
00270 void logdh(DH *dh);
00271 void logbn(BIGNUM *bn);
00272 int bn2bin_safe(const BIGNUM *a, unsigned char *to, int len);
00273 void log_hipa_fromto(int level, char *msg, hip_assoc *hip_a,__u8 from,__u8 to);
00274 void log_hipopts();
00275 #ifdef __WIN32__
00276 void log_WinError(int code);
00277 #endif
00278 #ifdef __UMH__
00279 int do_bcast();
00280 #endif
00281 void hip_sleep(int seconds);
00282 void hip_writelock();
00283 void hip_exit(int signal);
00284 void hit_to_sockaddr (struct sockaddr_in6 *sockad, hip_hit hit);
00285
00286
00287 int hip_netlink_open();
00288 int get_my_addresses();
00289 int select_preferred_address();
00290 int is_my_address(struct sockaddr *addr);
00291 int hip_handle_netlink(char *data, int length);
00292 int add_address_to_iface(struct sockaddr *addr, int plen, int if_index);
00293 int devname_to_index(char *dev, __u64 *mac);
00294 sockaddr_list *add_address_to_list(sockaddr_list **list, struct sockaddr *addr,
00295 int ifi);
00296 void delete_address_from_list(sockaddr_list **list, struct sockaddr *addr,
00297 int ifi);
00298 void delete_address_entry_from_list(sockaddr_list **list, sockaddr_list *entry);
00299 void make_address_active(sockaddr_list *item);
00300 int update_peer_list_address(const hip_hit peer_hit, struct sockaddr *old_addr, struct sockaddr *new_addr);
00301
00302
00303 void init_all_R1_caches();
00304 void init_R1_cache(hi_node *hi);
00305 hipcookie *generate_cookie();
00306 void replace_next_R1();
00307 int compute_R1_cache_index(hip_hit *hiti, __u8 current);
00308 int calculate_r1_length(hi_node *hi);
00309 void init_dh_cache();
00310 dh_cache_entry *new_dh_cache_entry(__u8 group_id);
00311 dh_cache_entry *get_dh_entry(__u8 group_id, int new);
00312 void unuse_dh_entry(DH *dh);
00313 void expire_old_dh_entries();
00314
00315
00316 int hip_status_open();
00317 void hip_handle_status_request(__u8 *buff, int len, struct sockaddr *addr);
00318
00319
00320 int hip_dht_lookup_hit(struct sockaddr *lsi, hip_hit *hit, int retry);
00321 int hip_dht_lookup_address(hip_hit *hit, struct sockaddr *addr, int retry);
00322 int hip_dht_publish(hip_hit *hit, struct sockaddr *addr, int retry);
00323 int hip_dht_select_server(struct sockaddr *addr);
00324 int add_addresses_from_dht(hi_node *hi, int retry);
00325 void publish_my_hits();
00326
00327
00328
00329
00330
00331
00332 static __inline __u64 __hton64( __u64 i )
00333 {
00334 #if defined(__MACOSX__) && defined(__BIG_ENDIAN__)
00335 return i;
00336 #endif
00337 return ((__u64)(htonl((__u32)(i) & 0xffffffff)) << 32)
00338 | htonl((__u32)(((i) >> 32) & 0xffffffff ));
00339 }
00340 #define hton64(i) __hton64( i )
00341 #define ntoh64(i) __hton64( i )
00342
00343
00344 #ifdef __WIN32__
00345 static __inline int gettimeofday(struct timeval *tv, void *tz)
00346 {
00347 if (!tv) return(-1);
00348 tv->tv_usec = 0;
00349 tv->tv_sec = time(NULL);
00350 return(0);
00351 }
00352
00353 #define pthread_mutex_lock(mp) WaitForSingleObject(*mp, INFINITE)
00354 #define pthread_mutex_unlock(mp) ReleaseMutex(*mp)
00355
00356 #endif
00357
00358 #endif
00359
00360
00361