00001
00002
00003
00004
00005 #include "server_config.h"
00006 #include "packets_operations.h"
00007 #include "dhcp.h"
00008
00009
00010
00011
00012 static void clear_profile (struct opt *options);
00013 static int add_option_to_profile (struct opt *mprofile, int option, char *type, char *value, int len);
00014 static int remove_option_from_profile (struct opt *mprofile, int option);
00015 static void context2profile (struct opt *profile, struct mysql_tables *mysql_tables);
00016
00017
00018
00019
00020
00021
00022
00023
00024 extern struct global_config configuration_globale;
00025
00026
00027
00028
00029
00030
00031
00032
00033 static void clear_profile (struct opt *options)
00034 {
00035 int i;
00036
00037 for (i=0; i<MAX_PROFILE_OPTIONS; i++)
00038 {
00039 options[i].code = 0;
00040 options[i].len = 0;
00041 memset ((void*)(options[i]).value, 0, VALUE_MAX_SIZE);
00042 }
00043 }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 static int add_option_to_profile (struct opt *mprofile, int option, char *type, char *value, int len)
00065 {
00066 int converted;
00067
00068
00069
00070
00071
00072 if ((option > 254) || (option < 1))
00073 {
00074 my_syslog (configuration_globale.log_file,
00075 "[INTERNAL ERROR] [%s:%d] add_option_to_profile: invalid option's value (%d)",
00076 __FILE__, __LINE__,
00077 option);
00078 return 1;
00079 }
00080
00081 converted = 0;
00082
00083 if (strcmp(type, "UINT32") == 0)
00084 {
00085 int rc = uint32_to_network_byte_order (value, (mprofile[option]).value, VALUE_MAX_SIZE);
00086 if (rc == -1) { return 1; }
00087 (mprofile[option]).len = rc * 4;
00088 (mprofile[option]).code = option;
00089 converted = 1;
00090 }
00091
00092 if (strcmp(type, "UINT16") == 0)
00093 {
00094 int rc = uint16_to_network_byte_order (value, (mprofile[option]).value, VALUE_MAX_SIZE);
00095 if (rc == -1) { return 1; }
00096 (mprofile[option]).len = rc * 2;
00097 (mprofile[option]).code = option;
00098 converted = 1;
00099 }
00100
00101 if (strcmp(type, "HEXA-BYTE") == 0)
00102 {
00103 int rc = hexa_to_binary (value, (mprofile[option]).value, VALUE_MAX_SIZE);
00104 if (rc == -1) { return 1; }
00105 (mprofile[option]).len = rc;
00106 (mprofile[option]).code = option;
00107 converted = 1;
00108 }
00109
00110 if (strcmp(type, "ASCII-BYTE") == 0)
00111 {
00112 int rc = ascii_to_binary (value, (mprofile[option]).value, len, VALUE_MAX_SIZE);
00113 if (rc == -1) { return 1; }
00114 (mprofile[option]).len = rc;
00115 (mprofile[option]).code = option;
00116 converted = 1;
00117 }
00118
00119 if (strcmp(type, "IP") == 0)
00120 {
00121 int rc = ip_to_network_byte_order (value, (mprofile[option]).value, VALUE_MAX_SIZE);
00122 if (rc == -1) { return 1; }
00123 (mprofile[option]).len = rc * 4;
00124 (mprofile[option]).code = option;
00125 converted = 1;
00126 }
00127
00128 if (converted == 0)
00129 {
00130 my_syslog (configuration_globale.log_file,
00131 "[ERROR] [%s:%d] Invalid option type (%s) for option", __FILE__, __LINE__, type);
00132 return 1;
00133 }
00134
00135 return 0;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 static int remove_option_from_profile (struct opt *mprofile, int option)
00147 {
00148 if ((option > 254) || (option < 1))
00149 {
00150 my_syslog (configuration_globale.log_file,
00151 "[INTERNAL ERROR] [%s:%d] remove_option_from_profile: invalid option's value (%d)",
00152 __FILE__, __LINE__,
00153 option);
00154 return 1;
00155 }
00156
00157 (mprofile[option]).code = 0;
00158 (mprofile[option]).len = 0;
00159
00160 memset ((void*)(mprofile[option]).value, 0, VALUE_MAX_SIZE);
00161
00162 return 0;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 static void context2profile (struct opt *profile, struct mysql_tables *mysql_tables)
00184 {
00185 int i, code, converted;
00186 char *type;
00187 char *value;
00188
00189
00190 clear_profile (profile);
00191
00192
00193
00194
00195
00196 for (i=0; i<mysql_tables->option_number; i++)
00197 {
00198 code = (int)(((mysql_tables->options)[i]).option_code);
00199
00200
00201
00202
00203
00204 if ((code > 254) || (code < 1))
00205 {
00206 my_syslog (configuration_globale.log_file,
00207 "[WARNING] [%s:%d] Invalid option code (%u) for profile_optionnel=[%s], SKIP",
00208 __FILE__, __LINE__,
00209 code,
00210 ((mysql_tables->options)[i]).profile_optionnel);
00211 continue;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 type = ((mysql_tables->options)[i]).option_type;
00224 value = ((mysql_tables->options)[i]).option_value;
00225
00226 converted = 0;
00227
00228 if (strcmp(type, "UINT32") == 0)
00229 {
00230 int rc = uint32_to_network_byte_order (value, (profile[code]).value, VALUE_MAX_SIZE);
00231 if (rc == -1) { continue; }
00232 (profile[code]).len = rc * 4;
00233 (profile[code]).code = code;
00234 converted = 1;
00235 }
00236
00237 if (strcmp(type, "UINT16") == 0)
00238 {
00239 int rc = uint16_to_network_byte_order (value, (profile[code]).value, VALUE_MAX_SIZE);
00240 if (rc == -1) { continue; }
00241 (profile[code]).len = rc * 2;
00242 (profile[code]).code = code;
00243 converted = 1;
00244 }
00245
00246 if (strcmp(type, "HEXA-BYTE") == 0)
00247 {
00248 int rc = hexa_to_binary (value, (profile[code]).value, VALUE_MAX_SIZE);
00249 if (rc == -1) { continue; }
00250 (profile[code]).len = rc;
00251 (profile[code]).code = code;
00252 converted = 1;
00253 }
00254
00255 if (strcmp(type, "ASCII-BYTE") == 0)
00256 {
00257 int rc = ascii_to_binary (value, (profile[code]).value, strlen(value), VALUE_MAX_SIZE);
00258 if (rc == -1) { continue; }
00259 (profile[code]).len = rc;
00260 (profile[code]).code = code;
00261 converted = 1;
00262 }
00263
00264 if (strcmp(type, "IP") == 0)
00265 {
00266 int rc = ip_to_network_byte_order (value, (profile[code]).value, VALUE_MAX_SIZE);
00267 if (rc == -1) { continue; }
00268 (profile[code]).len = rc * 4;
00269 (profile[code]).code = code;
00270 converted = 1;
00271 }
00272
00273 if (converted == 0)
00274 {
00275 my_syslog (configuration_globale.log_file,
00276 "[WARNING] [%s:%d] Invalid option type (%s) for profile [%s], ignore",
00277 __FILE__, __LINE__,
00278 type,
00279 ((mysql_tables->options)[i]).profile_optionnel);
00280 continue;
00281 }
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 int packets_send_offer (
00310 struct dhcp_packet *p,
00311 struct mysql_tables *mysql_tables,
00312 char *ip,
00313 unsigned long int broadcast,
00314 unsigned long int server_ip,
00315 int socket_desc,
00316 struct sockaddr_in *client_address,
00317 int tip)
00318 {
00319 struct dhcp_packet packet_out;
00320 struct sockaddr_in addr_target;
00321 int adress_size, rc, i;
00322 char *serverip;
00323 struct opt options[MAX_PROFILE_OPTIONS];
00324
00325
00326
00327 packets_clear (&packet_out);
00328 serverip = configuration_globale.server_ip_seen_by_client;
00329
00330
00331
00332
00333
00334
00335 context2profile (options, mysql_tables);
00336
00337
00338
00339
00340
00341
00342
00343
00344 packets_set_op (&packet_out, BOOTREPLY);
00345 packets_set_htype (&packet_out, packets_get_htype(p));
00346 packets_set_hlen (&packet_out, packets_get_hlen(p));
00347 packets_set_hops (&packet_out, 0);
00348 packets_set_xid (&packet_out, packets_get_xid(p));
00349 packets_set_secs (&packet_out, packets_get_secs(p));
00350 packets_set_flags (&packet_out, packets_get_flags(p));
00351 packets_set_yiaddr (&packet_out, ip);
00352 packets_set_siaddr (&packet_out, configuration_globale.server_ip_seen_by_client);
00353 packets_set_bin_giaddr (&packet_out, packets_get_bin_giaddr(p));
00354 packets_set_chaddr (&packet_out, packets_get_bin_chaddr(p));
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 if (configuration_globale.debug > 1)
00368 {
00369 my_syslog (configuration_globale.log_file,
00370 "[DEBUG] [%s:%d] Add options to DHCP packets", __FILE__, __LINE__);
00371 }
00372
00373
00374 add_option_to_profile (options, 53, "HEXA-BYTE", DHCPOFFER_HEXA, strlen(DHCPOFFER_HEXA));
00375
00376
00377 add_option_to_profile (options, 54, "IP", serverip, strlen(serverip));
00378
00379
00380
00381
00382
00383
00384
00385
00386 if (configuration_globale.debug > 1)
00387 { my_syslog (configuration_globale.log_file,
00388 "[DEBUG] [%s:%d] tip = %d",
00389 __FILE__, __LINE__,
00390 tip);
00391 }
00392
00393 if (tip == STATIC_IP)
00394 {
00395 add_option_to_profile (options, 3, "IP", mysql_tables->abonne_ip.gateway,
00396 strlen(mysql_tables->abonne_ip.gateway));
00397 add_option_to_profile (options, 1, "IP", mysql_tables->abonne_ip.subnet,
00398 strlen(mysql_tables->abonne_ip.subnet));
00399
00400 if (configuration_globale.debug > 1)
00401 { my_syslog (configuration_globale.log_file,
00402 "[DEBUG] [%s:%d] packets_send_offer: Add gateway and subnet %s %s",
00403 __FILE__, __LINE__,
00404 mysql_tables->abonne_ip.gateway,
00405 mysql_tables->abonne_ip.subnet); }
00406 }
00407
00408 if (tip == DYNAMIC_IP)
00409 {
00410 add_option_to_profile (options, 3, "IP", mysql_tables->ip_lease.gateway,
00411 strlen(mysql_tables->ip_lease.gateway));
00412 add_option_to_profile (options, 1, "IP", mysql_tables->ip_lease.subnet,
00413 strlen(mysql_tables->ip_lease.subnet));
00414 if (configuration_globale.debug > 1)
00415 { my_syslog (configuration_globale.log_file,
00416 "[DEBUG] [%s:%d] packets_send_offer: Add gateway and subnet %s %s",
00417 __FILE__, __LINE__,
00418 mysql_tables->ip_lease.gateway,
00419 mysql_tables->ip_lease.subnet); }
00420 }
00421
00422
00423
00424
00425
00426 for (i=1; i<255; i++)
00427 {
00428 if ((options[i]).code != 0)
00429 {
00430 packets_set_option (&packet_out, i, (options[i]).value, (options[i]).len);
00431 if (configuration_globale.debug > 1)
00432 { my_syslog (configuration_globale.log_file,
00433 "[DEBUG] [%s:%d] packets_send_offer: Adding option %d", __FILE__, __LINE__, i); }
00434 }
00435 }
00436
00437 packets_close_option (&packet_out);
00438
00439
00440
00441
00442
00443 adress_size = sizeof (struct sockaddr);
00444 memset ((void*)&addr_target, 0, sizeof(struct sockaddr_in));
00445
00446 if (configuration_globale.broadcast_mode == 1)
00447 {
00448 addr_target.sin_family = AF_INET;
00449 addr_target.sin_port = htons(TARGET_PORT);
00450 (addr_target.sin_addr).s_addr = broadcast;
00451 }
00452 else
00453 { memcpy ((void*)&addr_target, (void*)client_address, sizeof(struct sockaddr_in)); }
00454
00455 if (configuration_globale.debug > 0)
00456 { my_syslog (configuration_globale.log_file,
00457 "[DEBUG] [%s:%d] packets_send_offer: Sending DHCP OFFER for xid %u",
00458 __FILE__, __LINE__, packets_get_xid(p)); }
00459
00460 if (configuration_globale.dumper_mode > 0)
00461 { packet_dump (&packet_out, configuration_globale.debug_file, configuration_globale.csv_file, NULL, &addr_target); }
00462
00463 #ifndef READ_PACKET_FROM_FILE
00464
00465 rc = sendto (
00466 socket_desc,
00467 (void*)&packet_out,
00468 packet_out.ctrl.taille,
00469 0,
00470 (struct sockaddr*)&addr_target,
00471 adress_size
00472 );
00473
00474 if (rc == -1)
00475 {
00476 my_syslog (configuration_globale.log_file,
00477 "[WARNING] [%s:%d] Could not send OFFER for xid %u - %s",
00478 __FILE__, __LINE__,
00479 packets_get_xid(p),
00480 strerror(errno));
00481 return 1;
00482 }
00483
00484 #else
00485
00486 my_syslog (configuration_globale.log_file,
00487 "[INFO] [%s:%d] Reading packet from file => packet no sent (this is normal)",
00488 __FILE__, __LINE__);
00489
00490 #endif
00491
00492 return 0;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 int packets_send_ack (
00521 struct dhcp_packet *p,
00522 struct mysql_tables *mysql_tables,
00523 char *ip,
00524 unsigned long int broadcast,
00525 unsigned long int server_ip,
00526 int socket_desc,
00527 struct sockaddr_in *client_address,
00528 int tip)
00529 {
00530 struct dhcp_packet packet_out;
00531 struct sockaddr_in addr_target;
00532 int adress_size, rc, i;
00533 char *serverip;
00534 struct opt options[MAX_PROFILE_OPTIONS];
00535
00536
00537 packets_clear (&packet_out);
00538 serverip = configuration_globale.server_ip_seen_by_client;
00539
00540
00541
00542
00543
00544
00545 context2profile (options, mysql_tables);
00546
00547
00548
00549
00550
00551
00552
00553 packets_set_op (&packet_out, BOOTREPLY);
00554 packets_set_htype (&packet_out, packets_get_htype(p));
00555 packets_set_hlen (&packet_out, packets_get_hlen(p));
00556 packets_set_hops (&packet_out, 0);
00557 packets_set_xid (&packet_out, packets_get_xid(p));
00558 packets_set_secs (&packet_out, packets_get_secs(p));
00559 packets_set_flags (&packet_out, packets_get_flags(p));
00560 packets_set_yiaddr (&packet_out, ip);
00561 packets_set_siaddr (&packet_out, configuration_globale.server_ip_seen_by_client);
00562 packets_set_bin_giaddr (&packet_out, packets_get_bin_giaddr(p));
00563 packets_set_bin_ciaddr (&packet_out, packets_get_bin_ciaddr(p));
00564 packets_set_chaddr (&packet_out, packets_get_bin_chaddr(p));
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 if (configuration_globale.debug > 1)
00578 { my_syslog (configuration_globale.log_file,
00579 "[DEBUG] [%s:%d] packets_send_ack: Add option 53 (message type) = 3",
00580 __FILE__, __LINE__); }
00581
00582
00583 add_option_to_profile (options, 53, "HEXA-BYTE", DHCPACK_HEXA, strlen(DHCPACK_HEXA));
00584
00585 if (configuration_globale.debug > 1)
00586 { my_syslog (configuration_globale.log_file,
00587 "[DEBUG] [%s:%d] packets_send_ack: Add option 54 (server ID) %s",
00588 __FILE__, __LINE__, serverip); }
00589
00590
00591 add_option_to_profile (options, 54, "IP", serverip, strlen(serverip));
00592
00593
00594
00595
00596
00597
00598
00599
00600 if (configuration_globale.debug > 1)
00601 { my_syslog (configuration_globale.log_file,
00602 "[DEBUG] [%s:%d] tip = %d",
00603 __FILE__, __LINE__,
00604 tip);
00605 }
00606
00607 if (tip == STATIC_IP)
00608 {
00609 add_option_to_profile (options, 3, "IP", mysql_tables->abonne_ip.gateway,
00610 strlen(mysql_tables->abonne_ip.gateway));
00611 add_option_to_profile (options, 1, "IP", mysql_tables->abonne_ip.subnet,
00612 strlen(mysql_tables->abonne_ip.subnet));
00613
00614 if (configuration_globale.debug > 1)
00615 { my_syslog (configuration_globale.log_file,
00616 "[DEBUG] [%s:%d] packets_send_offer: Add gateway and subnet %s %s",
00617 __FILE__, __LINE__,
00618 mysql_tables->abonne_ip.gateway,
00619 mysql_tables->abonne_ip.subnet); }
00620 }
00621
00622 if (tip == DYNAMIC_IP)
00623 {
00624 add_option_to_profile (options, 3, "IP", mysql_tables->ip_lease.gateway,
00625 strlen(mysql_tables->ip_lease.gateway));
00626 add_option_to_profile (options, 1, "IP", mysql_tables->ip_lease.subnet,
00627 strlen(mysql_tables->ip_lease.subnet));
00628 if (configuration_globale.debug > 1)
00629 { my_syslog (configuration_globale.log_file,
00630 "[DEBUG] [%s:%d] packets_send_offer: Add gateway and subnet %s %s",
00631 __FILE__, __LINE__,
00632 mysql_tables->ip_lease.gateway,
00633 mysql_tables->ip_lease.subnet); }
00634 }
00635
00636
00637
00638
00639
00640 for (i=1; i<255; i++)
00641 {
00642 if ((options[i]).code != 0)
00643 {
00644 if (configuration_globale.debug > 1)
00645 { my_syslog (configuration_globale.log_file,
00646 "[DEBUG] [%s:%d] packets_send_ack: Adding option %d", __FILE__, __LINE__, i); }
00647 packets_set_option (&packet_out, i, (options[i]).value, (options[i]).len);
00648 }
00649 }
00650
00651 packets_close_option (&packet_out);
00652
00653
00654
00655
00656
00657 memset ((void*)&addr_target, 0, sizeof(struct sockaddr_in));
00658 adress_size = sizeof (struct sockaddr);
00659
00660 if (configuration_globale.broadcast_mode == 1)
00661 {
00662 addr_target.sin_family = AF_INET;
00663 addr_target.sin_port = htons(TARGET_PORT);
00664 (addr_target.sin_addr).s_addr = broadcast;
00665 }
00666 else
00667 { memcpy ((void*)&addr_target, (void*)client_address, sizeof(struct sockaddr_in)); }
00668
00669 if (configuration_globale.debug > 0)
00670 { my_syslog (configuration_globale.log_file,
00671 "[DEBUG] [%s:%d] packets_send_ack: Sending DHCP ACK for xid %u",
00672 __FILE__, __LINE__, packets_get_xid(p)); }
00673
00674
00675 if (configuration_globale.dumper_mode > 0)
00676 { packet_dump (&packet_out, configuration_globale.debug_file, configuration_globale.csv_file, NULL, &addr_target); }
00677
00678 #ifndef READ_PACKET_FROM_FILE
00679
00680 rc = sendto (
00681 socket_desc,
00682 (void*)&packet_out,
00683 packet_out.ctrl.taille,
00684 0,
00685 (struct sockaddr*)&addr_target,
00686 adress_size
00687 );
00688
00689 if (rc == -1)
00690 {
00691 my_syslog (configuration_globale.log_file, "[WARNING] [%s:%d] Could not send ACK for xid %u - %s",
00692 __FILE__, __LINE__,
00693 packets_get_xid(p),
00694 strerror(errno));
00695 return 1;
00696 }
00697
00698 #else
00699
00700 my_syslog (configuration_globale.log_file,
00701 "[INFO] [%s:%d] Reading packet from file => packet no sent (this is normal)",
00702 __FILE__, __LINE__);
00703
00704 #endif
00705
00706 return 0;
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 int log_profile (const char *file, const char *mes, const struct opt *profile)
00720 {
00721 int i, l;
00722 FILE *fd;
00723 unsigned char *c;
00724
00725 fd = fopen (file, "a");
00726 if (fd == NULL) { return 1; }
00727
00728 fprintf (fd, "%s %s ", dater(), mes);
00729
00730 for (i=0; i<256; i++)
00731 {
00732 if ((profile[i]).code != 0)
00733 {
00734 fprintf (fd, "(%d) %d [", (profile[i]).code, (profile[i]).len);
00735 c = (unsigned char*)(profile[i]).value;
00736 for (l=0; l<(profile[i]).len; l++)
00737 {
00738 fprintf (fd, "%c%c", int_to_char (((*c) & 0xF0) >> 4), int_to_char ((*c) & 0x0F));
00739 if (l < (profile[i]).len - 1) { fprintf (fd, "."); }
00740 c += 1;
00741 }
00742 fprintf (fd, "] ");
00743 }
00744 }
00745 fprintf (fd, "\n");
00746
00747 fclose (fd);
00748 return 0;
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 int reply_to_inform (
00770 struct dhcp_packet *p,
00771 struct mysql_tables *mysql_tables,
00772 unsigned long int broadcast,
00773 unsigned long int server_ip,
00774 int socket_desc,
00775 struct sockaddr_in *client_address)
00776 {
00777 struct dhcp_packet packet_out;
00778 struct sockaddr_in addr_target;
00779 int adress_size, rc, i;
00780 char *serverip;
00781 struct opt options[MAX_PROFILE_OPTIONS];
00782
00783 packets_clear (&packet_out);
00784 serverip = configuration_globale.server_ip_seen_by_client;
00785
00786
00787
00788
00789
00790
00791 context2profile (options, mysql_tables);
00792
00793
00794
00795
00796
00797
00798
00799
00800 packets_set_op (&packet_out, BOOTREPLY);
00801 packets_set_htype (&packet_out, packets_get_htype(p));
00802 packets_set_hlen (&packet_out, packets_get_hlen(p));
00803 packets_set_hops (&packet_out, 0);
00804 packets_set_xid (&packet_out, packets_get_xid(p));
00805 packets_set_secs (&packet_out, packets_get_secs(p));
00806 packets_set_flags (&packet_out, packets_get_flags(p));
00807 packets_set_siaddr (&packet_out, configuration_globale.server_ip_seen_by_client);
00808 packets_set_bin_giaddr (&packet_out, packets_get_bin_giaddr(p));
00809 packets_set_bin_ciaddr (&packet_out, packets_get_bin_ciaddr(p));
00810 packets_set_chaddr (&packet_out, packets_get_bin_chaddr(p));
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 add_option_to_profile (options, 53, "HEXA-BYTE", DHCPACK_HEXA, strlen(DHCPACK_HEXA));
00825 add_option_to_profile (options, 54, "IP", serverip, strlen(serverip));
00826
00827 remove_option_from_profile (options, 51);
00828
00829
00830
00831
00832
00833 for (i=1; i<255; i++)
00834 {
00835 if ((options[i]).code != 0)
00836 {
00837 packets_set_option (&packet_out, i, (options[i]).value, (options[i]).len);
00838 if (configuration_globale.debug > 1)
00839 { my_syslog (configuration_globale.log_file,
00840 "[DEBUG] [%s:%d] packets_send_ack: Adding option %d", __FILE__, __LINE__, i); }
00841 }
00842 }
00843
00844 packets_close_option (&packet_out);
00845
00846
00847
00848
00849
00850 adress_size = sizeof (struct sockaddr);
00851 memset ((void*)&addr_target, 0, sizeof(struct sockaddr_in));
00852
00853 if (configuration_globale.broadcast_mode == 1)
00854 {
00855 addr_target.sin_family = AF_INET;
00856 addr_target.sin_port = htons(TARGET_PORT);
00857 (addr_target.sin_addr).s_addr = broadcast;
00858 }
00859 else
00860 { memcpy ((void*)&addr_target, (void*)client_address, sizeof(struct sockaddr_in)); }
00861
00862 if (configuration_globale.debug > 0)
00863 { my_syslog (configuration_globale.log_file,
00864 "[DEBUG] [%s:%d] packets_send_offer: Sending DHCP OFFER for xid %u",
00865 __FILE__, __LINE__, packets_get_xid(p)); }
00866
00867 if (configuration_globale.dumper_mode > 0)
00868 { packet_dump (&packet_out, configuration_globale.debug_file, configuration_globale.csv_file, NULL, &addr_target); }
00869
00870 #ifndef READ_PACKET_FROM_FILE
00871
00872 rc = sendto (
00873 socket_desc,
00874 (void*)&packet_out,
00875 packet_out.ctrl.taille,
00876 0,
00877 (struct sockaddr*)&addr_target,
00878 adress_size
00879 );
00880
00881 if (rc == -1)
00882 {
00883 my_syslog (configuration_globale.log_file,
00884 "[WARNING] [%s:%d] Could not send OFFER for xid %u - %s",
00885 __FILE__, __LINE__,
00886 packets_get_xid(p),
00887 strerror(errno));
00888 return 1;
00889 }
00890
00891 #else
00892
00893 my_syslog (configuration_globale.log_file,
00894 "[INFO] [%s:%d] Reading packet from file => packet no sent (this is normal)",
00895 __FILE__, __LINE__);
00896
00897 #endif
00898
00899 return 0;
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 int packets_send_nack (
00922 struct dhcp_packet *p,
00923 struct mysql_tables *mysql_tables,
00924 char *ip,
00925 unsigned long int broadcast,
00926 unsigned long int server_ip,
00927 int socket_desc,
00928 struct sockaddr_in *client_address)
00929 {
00930 struct dhcp_packet packet_out;
00931 struct sockaddr_in addr_target;
00932 int adress_size, rc, i;
00933 char *serverip;
00934 struct opt options[MAX_PROFILE_OPTIONS];
00935
00936 packets_clear (&packet_out);
00937 serverip = configuration_globale.server_ip_seen_by_client;
00938
00939
00940
00941
00942
00943 clear_profile(options);
00944
00945
00946
00947
00948
00949 packets_set_op (&packet_out, BOOTREPLY);
00950 packets_set_htype (&packet_out, packets_get_htype(p));
00951 packets_set_hlen (&packet_out, packets_get_hlen(p));
00952 packets_set_hops (&packet_out, 0);
00953 packets_set_xid (&packet_out, packets_get_xid(p));
00954 packets_set_secs (&packet_out, packets_get_secs(p));
00955 packets_set_flags (&packet_out, packets_get_flags(p));
00956 packets_set_yiaddr (&packet_out, ip);
00957 packets_set_siaddr (&packet_out, configuration_globale.server_ip_seen_by_client);
00958 packets_set_bin_giaddr (&packet_out, packets_get_bin_giaddr(p));
00959 packets_set_bin_ciaddr (&packet_out, packets_get_bin_ciaddr(p));
00960 packets_set_chaddr (&packet_out, packets_get_bin_chaddr(p));
00961
00962
00963
00964
00965
00966 if (configuration_globale.debug > 1)
00967 { my_syslog (configuration_globale.log_file,
00968 "[DEBUG] [%s:%d] packets_send_nack: Add option 53 (message type) = 6",
00969 __FILE__, __LINE__); }
00970
00971 add_option_to_profile (options, 53, "HEXA-BYTE", DHCPNAK_HEXA, strlen(DHCPNAK_HEXA));
00972
00973
00974
00975
00976
00977 if (configuration_globale.debug > 1)
00978 { my_syslog (configuration_globale.log_file,
00979 "[DEBUG] [%s:%d] packets_send_nack: Add option 54 (server ID) %s",
00980 __FILE__, __LINE__, serverip); }
00981
00982 add_option_to_profile (options, 54, "IP", serverip, strlen(serverip));
00983
00984
00985
00986
00987
00988 for (i=1; i<255; i++)
00989 {
00990 if ((options[i]).code != 0)
00991 {
00992 if (configuration_globale.debug > 1)
00993 { my_syslog (configuration_globale.log_file,
00994 "[DEBUG] [%s:%d] packets_send_nack: Adding option %d", __FILE__, __LINE__, i); }
00995 packets_set_option (&packet_out, i, (options[i]).value, (options[i]).len);
00996 }
00997 }
00998
00999
01000
01001
01002
01003 packets_close_option (&packet_out);
01004
01005 memset ((void*)&addr_target, 0, sizeof(struct sockaddr_in));
01006 adress_size = sizeof (struct sockaddr);
01007
01008 if (configuration_globale.broadcast_mode == 1)
01009 {
01010 addr_target.sin_family = AF_INET;
01011 addr_target.sin_port = htons(TARGET_PORT);
01012 (addr_target.sin_addr).s_addr = broadcast;
01013 }
01014 else
01015 { memcpy ((void*)&addr_target, (void*)client_address, sizeof(struct sockaddr_in)); }
01016
01017 if (configuration_globale.debug > 0)
01018 { my_syslog (configuration_globale.log_file,
01019 "[DEBUG] [%s:%d] packets_send_nack: Sending DHCP NACK for xid %u",
01020 __FILE__, __LINE__, packets_get_xid(p)); }
01021
01022 if (configuration_globale.dumper_mode > 0)
01023 { packet_dump (&packet_out, configuration_globale.debug_file, configuration_globale.csv_file, NULL, &addr_target); }
01024
01025 #ifndef READ_PACKET_FROM_FILE
01026
01027
01028
01029
01030
01031 rc = sendto (
01032 socket_desc,
01033 (void*)&packet_out,
01034 packet_out.ctrl.taille,
01035 0,
01036 (struct sockaddr*)&addr_target,
01037 adress_size
01038 );
01039
01040 if (rc == -1)
01041 {
01042 my_syslog (configuration_globale.log_file,
01043 "[WARNING] [%s:%d] Could not send NAK for xid %u - %s",
01044 __FILE__, __LINE__,
01045 packets_get_xid(p),
01046 strerror(errno));
01047 return 1;
01048 }
01049
01050 #else
01051
01052
01053
01054
01055
01056 my_syslog (configuration_globale.log_file,
01057 "[INFO] [%s:%d] Reading packet from file => packet (NAK) not sent (simulation)",
01058 __FILE__, __LINE__);
01059
01060 #endif
01061
01062 return 0;
01063 }
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 int packets_send_dummy_nak (
01085 struct dhcp_packet *p,
01086 struct mysql_tables *mysql_tables,
01087 char *ip,
01088 unsigned long int broadcast,
01089 unsigned long int server_ip,
01090 int socket_desc,
01091 struct sockaddr_in *client_address)
01092 {
01093 int cr;
01094
01095 my_syslog (configuration_globale.log_file,
01096 "[DUMMY RESPONSE] [%s:%d] packets_send_dummy_nak: Sending DUMMY DHCPNAK",
01097 __FILE__, __LINE__);
01098
01099 cr = packets_send_nack ( p,
01100 mysql_tables,
01101 ip,
01102 broadcast,
01103 server_ip,
01104 socket_desc,
01105 client_address);
01106
01107 if (cr == 1)
01108 {
01109 my_syslog (configuration_globale.log_file,
01110 "[ERROR] [%s:%d] packets_send_dummy_nak: Could not send the DUMMY DHCPNAK",
01111 __FILE__, __LINE__);
01112 return 1;
01113 }
01114
01115 return 0;
01116 }
01117
01118
01119
01120
01121
01122
01123